import pandas as pd
import numpy as np
from datetime import datetime


def detectar_outliers_y_borrar(
    archivo_csv,
    columnas_interes=None,
    umbrales_relativos=None,
    epsilon=1e-3,
    hora_inicio="09:35:00",
    modo_interactivo=True  # Si es False, elimina automáticamente sin preguntar
):
    if columnas_interes is None:
        columnas_interes = [
            'bid_call', 'ask_call', 'bid_put', 'ask_put',
            'delta_call', 'delta_put', 'gamma_call', 'open_interest_call',
            'volume_call', 'gamma_put', 'open_interest_put', 'volume_put'
        ]

    if umbrales_relativos is None:
        umbrales_relativos = {
            'bid_call': 0.5, 'ask_call': 0.5,
            'bid_put': 0.5, 'ask_put': 0.5,
            'delta_call': 0.5, 'delta_put': 0.5,
            'gamma_call': 1.0, 'open_interest_call': 1.0, 'volume_call': 1.0,
            'gamma_put': 1.0, 'open_interest_put': 1.0, 'volume_put': 1.0
        }

    df = pd.read_csv(archivo_csv)
    for col in columnas_interes:
        df[col] = pd.to_numeric(df[col], errors='coerce')

    df['timestamp'] = pd.to_datetime(df['timestamp'])
    df = df[df['timestamp'].dt.strftime("%H:%M:%S") >= hora_inicio]
    df.sort_values(by=['timestamp', 'strike'], inplace=True)

    original_len = len(df)

    timestamps = df['timestamp'].drop_duplicates().to_list()

    for i in range(1, len(timestamps)):
        t_anterior = timestamps[i - 1]
        t_actual = timestamps[i]
        print(f"⏱️ Comparando {t_anterior.time()} vs {t_actual.time()}...")

        df_anterior = df[df['timestamp'] == t_anterior].set_index('strike')
        df_actual = df[df['timestamp'] == t_actual].set_index('strike')

        strikes_comunes = df_anterior.index.intersection(df_actual.index)

        for strike in strikes_comunes:
            for col in columnas_interes:
                try:
                    val_anterior = df_anterior.at[strike, col]
                    val_actual = df_actual.at[strike, col]

                    if pd.isna(val_anterior) or pd.isna(val_actual):
                        continue
                    if abs(val_anterior) < epsilon and abs(val_actual) < epsilon:
                        continue
                    if max(abs(val_anterior), abs(val_actual)) < 10:
                        continue

                    threshold = umbrales_relativos.get(col, 1.0)
                    cambio = abs(val_anterior - val_actual) / max(abs(val_anterior), abs(val_actual))

                    if cambio > threshold:
                        print(f"\n⚠️ Outlier en '{col}' | Strike: {strike}")
                        print(f"  ↪ {t_anterior.time()} ➝ {t_actual.time()}")
                        print(f"  ↪ Valor anterior: {val_anterior} | actual: {val_actual}")
                        print(f"  ↪ Cambio: {round(cambio * 100, 2)}%")

                        match = (
                            (df['timestamp'] == t_actual) &
                            (np.isclose(df['strike'], strike, atol=1e-4))
                        )

                        index_to_drop = df[match].index

                        if modo_interactivo:
                            resp = input("¿Eliminar esta fila? (s/n): ").strip().lower()
                            if resp == 's':
                                df.drop(index=index_to_drop, inplace=True)
                                print(f"✅ Fila eliminada ({len(index_to_drop)} fila/s eliminada/s).")
                        else:
                            df.drop(index=index_to_drop, inplace=True)
                            print(f"✅ Fila eliminada automáticamente ({len(index_to_drop)} fila/s).")

                except Exception as e:
                    print(f"⚠️ Error al comparar {col} en strike {strike}: {e}")
                    continue

    df.sort_values(by=['timestamp', 'strike'], inplace=True)

    nuevo_archivo = archivo_csv.replace(".csv", "_clean.csv")
    df.to_csv(nuevo_archivo, index=False)

    print(f"\n💾 Guardado en: {nuevo_archivo}")
    print(f"📊 Filas originales: {original_len} | Filas finales: {len(df)}")


if __name__ == "__main__":
    symbol = "SPY"
    fecha = "2025-08-08"
    archivo = f"/var/www/html/flask_project/chains/optionChain_{symbol}_{fecha}.csv"
    detectar_outliers_y_borrar(archivo, modo_interactivo=True)
