import pandas as pd
from pathlib import Path
import re


def extract_vertical_strikes(idea_str):
    match = re.search(r"(\d{2,5})/(\d{2,5}) (PUT|CALL)", str(idea_str))
    if match:
        return match.group(1), match.group(2), match.group(3)
    return "", "", ""


def extract_condor_strikes_from_verbose(text):
    match = re.search(r"\[CALLS (\d{2,5})/(\d{2,5})\] \+ \[PUTS (\d{2,5})/(\d{2,5})\]", str(text))
    if match:
        return match.group(1), match.group(2), match.group(3), match.group(4)
    return "", "", "", ""


def procesar_por_horario_global(input_folder, output_folder, name_value, fecha_filtro=None):
    input_path = Path(input_folder)
    output_path = Path(output_folder)
    output_path.mkdir(parents=True, exist_ok=True)

    all_data = []

    for file in sorted(input_path.glob("prediction_*.csv")):
        df = pd.read_csv(file)
        df["timestamp"] = pd.to_datetime(df["timestamp"])
        df["Day"] = df["timestamp"].dt.strftime("%m/%d/%Y")
        df["Hour"] = df["timestamp"].dt.strftime("%H:%M")
        df["HourFile"] = df["timestamp"].dt.strftime("%H%M")
        df["Symbol"] = symbol_value
        df["Raw"] = ""

        # Aplica el filtro de fecha si se especifica
        if fecha_filtro:
            df = df[df["Day"] == fecha_filtro]
            if df.empty:
                continue

        if name_value == "Vertical":
            df["Trade"] = df["IDEA"]
            vertical_mask = df["Trade"].astype(str).str.contains(r"\d{2,5}/\d{2,5} (?:PUT|CALL)", regex=True, na=False)
            df = df[vertical_mask].copy()
            df[["Strike1", "Strike2", "Option_Type"]] = df["Trade"].apply(
                lambda x: pd.Series(extract_vertical_strikes(x))
            )
            df["Name"] = "Vertical"
            final_df = df[["Day", "Hour", "Symbol", "Name", "Raw", "Trade",
                           "Strike1", "Strike2", "Option_Type", "HourFile"]]

        elif name_value == "Iron Condor":
            df["Trade"] = df["IDEA_IC"]
            df = df[df["Trade"].notna()].copy()

            condor_rows = []
            for _, row in df.iterrows():
                trade_str = str(row["Trade"])
                strikes = extract_condor_strikes_from_verbose(trade_str)
                if all(strikes):
                    condor_rows.append({
                        "Day": row["Day"],
                        "Hour": row["Hour"],
                        "Symbol": row["Symbol"],
                        "Name": "Iron Condor",
                        "Raw": row["Raw"],
                        "Trade": trade_str,
                        "Call_Strike1": strikes[0],
                        "Call_Strike2": strikes[1],
                        "Put_Strike1": strikes[2],
                        "Put_Strike2": strikes[3],
                        "HourFile": row["HourFile"]
                    })

            final_df = pd.DataFrame(condor_rows)

        else:
            print(f"[ERROR] Estrategia no reconocida: {name_value}")
            return

        if not final_df.empty:
            all_data.append(final_df)

    if not all_data:
        print("[INFO] No se encontraron datos válidos.")
        return

    full_df = pd.concat(all_data, ignore_index=True)
    horarios_validos = pd.date_range("10:05", "15:30", freq="5min").strftime("%H%M").tolist()

    for h in horarios_validos:
        group = full_df[full_df["HourFile"] == h]
        if not group.empty:
            filename = f"{symbol_value}_{name_value.replace(' ', '')}_strikes_{h}.csv"
            filepath = Path(output_folder) / filename
            new_data = group.drop(columns=["HourFile"])

            if fecha_filtro and filepath.exists():
                # Leer archivo existente
                existing_df = pd.read_csv(filepath)

                # Verificar si ya existe esa fecha
                if fecha_filtro in existing_df["Day"].values:
                    print(f"[INFO] Fecha {fecha_filtro} ya existe en {filename}, no se agrega.")
                    continue

                # Agregar nueva fecha
                combined_df = pd.concat([existing_df, new_data], ignore_index=True)
                combined_df.to_csv(filepath, index=False)
                print(f"Actualizado: {filename} (+{len(new_data)} filas nuevas)")

            else:
                # Si no hay filtro o archivo no existe: crear/reemplazar
                new_data.to_csv(filepath, index=False)
                print(f"Guardado: {filename} ({len(new_data)} filas)")


if __name__ == "__main__":
    symbols = ["SPX", "QQQ", "SPY", "RUT", "XSP"]
    estrategias = ["Vertical", "Iron Condor"]
    fecha_filtro = "12/05/2025"  # Puedes cambiarlo o poner None para todo

    for symbol_value in symbols:
        input_folder = f"/var/www/html/backtestingmarket/predictor_data/data/{symbol_value}"
        output_folder = f"/var/www/html/backtestingmarket/predictor_data/makekos/{symbol_value}"

        print(f"\n=== Procesando {symbol_value} ===")

        for name_value in estrategias:
            print(f"> Estrategia: {name_value}")
            procesar_por_horario_global(input_folder, output_folder, name_value, fecha_filtro=fecha_filtro)
