import requests
from datetime import datetime, timedelta
import csv
import os

# URL de tu endpoint Flask — ajusta puerto si hace falta
BASE_URL = "http://127.0.0.1:5000/backtestingIdea/get_backtesting_idea"

# 📁 Carpeta donde se guardan los detalles semanales
DETALLE_DIR = "detalle_semanal"
os.makedirs(DETALLE_DIR, exist_ok=True)

# 🗓️ Rango total a analizar esta corrida
DESDE_TOTAL = "2025-12-13"
HASTA_TOTAL = "2026-03-13"

# 🕒 Rango horario: 10:05 a 15:00 en pasos de 5 min
HORA_INICIO_STR = "10:05"
HORA_FIN_STR = "15:00"

# 📊 Configuración de estrategias y riesgos por símbolo
CONFIGURACIONES = {
    "Vertical": {
        "SPX": ["ultra_agresivo", "agresivo", "intermedio", "conservador"],
        "RUT": ["ultra_agresivo", "agresivo", "intermedio", "conservador"],
        "XSP": ["ultra_agresivo", "agresivo", "intermedio", "conservador"]
    },
    "IronCondor": {
        "SPX": ["ultra_agresivo", "agresivo", "intermedio", "conservador"],
        "RUT": ["ultra_agresivo", "agresivo", "intermedio", "conservador"],
        "XSP": ["ultra_agresivo", "agresivo", "intermedio", "conservador"]
    }
}

# ─────────────────────────────────────────────
# 🔧 Helpers
# ─────────────────────────────────────────────

def generar_semanas(desde_str, hasta_str):
    """
    Divide el rango total en semanas de sábado a viernes.
    La primera semana empieza en 'desde' (que siempre es sábado).
    """
    semanas = []
    inicio = datetime.strptime(desde_str, "%Y-%m-%d")
    hasta = datetime.strptime(hasta_str, "%Y-%m-%d")

    while inicio <= hasta:
        fin_semana = inicio + timedelta(days=6)
        if fin_semana > hasta:
            fin_semana = hasta
        semanas.append((
            inicio.strftime("%Y-%m-%d"),
            fin_semana.strftime("%Y-%m-%d")
        ))
        inicio += timedelta(days=7)

    return semanas


def nombre_detalle(estrategia, symbol, risk, desde, hasta):
    """Nombre del archivo de detalle semanal."""
    risk_short = risk[:4]
    return os.path.join(
        DETALLE_DIR,
        f"detalle_{risk_short}_{symbol}_{estrategia}_{desde}_{hasta}.csv"
    )


def semana_ya_guardada(estrategia, symbol, risk, desde, hasta):
    """Verifica si ya existe el archivo de detalle para esta semana."""
    return os.path.exists(nombre_detalle(estrategia, symbol, risk, desde, hasta))


def guardar_detalle_semana(estrategia, symbol, risk, desde, hasta, resultados):
    """Guarda el detalle de una semana en su archivo CSV."""
    path = nombre_detalle(estrategia, symbol, risk, desde, hasta)
    with open(path, "w", newline="") as csvfile:
        fieldnames = ["hora", "profit", "wins", "losses"]
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        for fila in resultados:
            writer.writerow(fila)
    print(f"   📁 Detalle guardado: {path}")


def consultar_semana(estrategia, symbol, risk, desde, hasta):
    """
    Consulta el endpoint para todas las horas de una semana.
    Devuelve lista de {hora, profit, wins, losses}.
    """
    hora_inicio = datetime.strptime(HORA_INICIO_STR, "%H:%M")
    hora_fin = datetime.strptime(HORA_FIN_STR, "%H:%M")
    resultados = []

    while hora_inicio <= hora_fin:
        hora_str = hora_inicio.strftime("%H%M")

        params = {
            "desde": desde,
            "hasta": hasta,
            "symbol": symbol,
            "estrategia": estrategia,
            "hora": hora_str,
            "risk": risk
        }

        print(f"   🕒 {hora_str} ...", end=" ")

        try:
            response = requests.get(BASE_URL, params=params, timeout=60)
            response.raise_for_status()
            data = response.json()

            profit = data.get("profit_total", 0)
            wins = data.get("wins", 0)
            losses = data.get("losses", 0)

            print(f"profit={profit} | wins={wins} | losses={losses}")

            resultados.append({
                "hora": hora_str,
                "profit": profit,
                "wins": wins,
                "losses": losses
            })

        except Exception as e:
            print(f"[ERROR] {e}")
            resultados.append({
                "hora": hora_str,
                "profit": 0,
                "wins": 0,
                "losses": 0
            })

        hora_inicio += timedelta(minutes=5)

    return resultados


def cargar_detalle(estrategia, symbol, risk, desde, hasta):
    """Carga el detalle de una semana desde su archivo CSV."""
    path = nombre_detalle(estrategia, symbol, risk, desde, hasta)
    resultados = []
    with open(path, newline="") as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            resultados.append({
                "hora": row["hora"],
                "profit": float(row["profit"]),
                "wins": int(row["wins"]),
                "losses": int(row["losses"])
            })
    return resultados


def sumar_semanas(lista_de_resultados):
    """
    Recibe una lista de semanas (cada una es lista de {hora, profit, wins, losses})
    y devuelve la suma total por hora.
    """
    totales = {}
    for semana in lista_de_resultados:
        for fila in semana:
            hora = fila["hora"]
            if hora not in totales:
                totales[hora] = {"hora": hora, "profit": 0, "wins": 0, "losses": 0}
            totales[hora]["profit"] += fila["profit"]
            totales[hora]["wins"] += fila["wins"]
            totales[hora]["losses"] += fila["losses"]

    # Devolver ordenado por hora
    return [totales[h] for h in sorted(totales.keys())]


def guardar_resultado_final(estrategia, symbol, risk, desde, hasta, resultados):
    """Guarda el CSV final acumulado (igual al formato original)."""
    filename = f"resultados_backtesting_{risk[:4]}_{symbol}_{desde}_{hasta}_{estrategia}.csv"
    with open(filename, "w", newline="") as csvfile:
        fieldnames = ["hora", "profit", "wins", "losses"]
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        for fila in resultados:
            writer.writerow(fila)
    print(f"\n   📊 Resultado final guardado: {filename}")

    # Mostrar mejor hora
    mejor = max(resultados, key=lambda x: x["profit"], default=None)
    if mejor:
        print(f"   🏆 Mejor hora: {mejor['hora']} | Profit: {mejor['profit']} | W:{mejor['wins']} L:{mejor['losses']}")


# ─────────────────────────────────────────────
# 🚀 Main
# ─────────────────────────────────────────────

start_time_global = datetime.now()

semanas = generar_semanas(DESDE_TOTAL, HASTA_TOTAL)

print(f"\n📅 Semanas detectadas ({len(semanas)}):")
for s in semanas:
    print(f"   {s[0]} → {s[1]}")

for estrategia, symbols_config in CONFIGURACIONES.items():
    for symbol, risks in symbols_config.items():
        for risk in risks:

            print(f"\n{'='*70}")
            print(f"📊 {symbol} | {estrategia} | {risk}")
            print(f"{'='*70}")

            semanas_data = []

            for desde_sem, hasta_sem in semanas:

                if semana_ya_guardada(estrategia, symbol, risk, desde_sem, hasta_sem):
                    print(f"\n   ⏭️  Semana {desde_sem} → {hasta_sem} ya existe, cargando...")
                    datos = cargar_detalle(estrategia, symbol, risk, desde_sem, hasta_sem)
                else:
                    print(f"\n   🔍 Consultando semana {desde_sem} → {hasta_sem}...")
                    datos = consultar_semana(estrategia, symbol, risk, desde_sem, hasta_sem)
                    guardar_detalle_semana(estrategia, symbol, risk, desde_sem, hasta_sem, datos)

                semanas_data.append(datos)

            # Sumar todas las semanas y generar CSV final
            total = sumar_semanas(semanas_data)
            guardar_resultado_final(estrategia, symbol, risk, DESDE_TOTAL, HASTA_TOTAL, total)

# Tiempo total
end_time_global = datetime.now()
elapsed = end_time_global - start_time_global
elapsed_str = str(elapsed).split(".")[0]
print(f"\n⏱️  Tiempo total transcurrido: {elapsed_str}\n")