#!/usr/bin/env python3
"""
generar_dashboard.py
────────────────────
Genera un dashboard HTML interactivo comparando dos estrategias de opciones
(IronCondor vs Vertical) a partir de dos archivos CSV.

Uso:
    1. Completá archivoIC y archivoVer con las rutas de tus CSVs
    2. Ejecutá:  python generar_dashboard.py

El HTML se guarda en el mismo directorio donde se ejecuta el script.

Formato esperado del nombre de archivo:
    P_L_IronCondor_XSP_HORA_1020_20250512_20260302_inte_CT_50.csv
    P_L_Vertical_XSP_HORA_1020_20250512_20260302_agre_CT_50.csv
"""

# ══════════════════════════════════════════════
# ARCHIVOS DE ENTRADA — completá las rutas aquí
# ══════════════════════════════════════════════
archivoIC  = "resultados/P&L_IronCondor_SPX_HORA_1020_20250512_20260305_agre_CT_250.csv"
archivoVer = "resultados/P&L_Vertical_SPX_HORA_DINAMICA_20250512_20260305_ultr_CT_250.csv"
# ══════════════════════════════════════════════

import sys
import os
import re
import json
import pandas as pd
from datetime import datetime
from pathlib import Path


RISK_NAMES = {
    'ultr': 'Ultra Agresivo',
    'agre': 'Agresivo',
    'inte': 'Intermedio',
    'cons': 'Conservador',
}

MONTH_NAMES_ES = {
    '01': 'Ene', '02': 'Feb', '03': 'Mar', '04': 'Abr',
    '05': 'May', '06': 'Jun', '07': 'Jul', '08': 'Ago',
    '09': 'Sep', '10': 'Oct', '11': 'Nov', '12': 'Dic',
}


def parse_filename(path):
    name = Path(path).stem
    info = {
        'estrategia': 'Estrategia',
        'simbolo':    'SYM',
        'hora':       '--:--',
        'hora_raw':   '----',
        'fecha_desde': '',
        'fecha_hasta': '',
        'riesgo':     '',
        'riesgo_full': '',
        'ct':         '0',
    }
    pat = re.compile(
        r'P[_\-&]L[_\-](?P<strat>.+?)[_\-](?P<sym>[A-Z0-9]{2,6})[_\-]HORA[_\-]'
        r'(?P<hora>[0-9A-Z]+)[_\-](?P<d1>\d{8})[_\-](?P<d2>\d{8})[_\-]'
        r'(?P<risk>[a-z]+)[_\-]CT[_\-](?P<ct>\d+)',
        re.IGNORECASE
    )
    m = pat.search(name)
    if m:
        info['estrategia'] = m.group('strat').replace('_', ' ').replace('-', ' ')
        info['simbolo']    = m.group('sym').upper()
        hora_raw           = m.group('hora').upper()
        info['hora_raw']   = hora_raw
        if hora_raw == 'DINAMICA':
            info['hora'] = 'Mejores Horarios'
        else:
            try:
                info['hora'] = f"{hora_raw[:2]}:{hora_raw[2:4]}"
            except Exception:
                info['hora'] = hora_raw
        d1 = m.group('d1')
        d2 = m.group('d2')
        info['fecha_desde']  = f"{d1[:4]}-{d1[4:6]}-{d1[6:8]}"
        info['fecha_hasta']  = f"{d2[:4]}-{d2[4:6]}-{d2[6:8]}"
        risk = m.group('risk').lower()
        info['riesgo']       = risk
        info['riesgo_full']  = RISK_NAMES.get(risk, risk.capitalize())
        info['ct']           = m.group('ct')
    return info


def fmt_date_es(date_str):
    try:
        d = datetime.strptime(date_str, '%Y-%m-%d')
        return f"{d.day} {MONTH_NAMES_ES[f'{d.month:02d}']} {d.year}"
    except Exception:
        return date_str


def process_csvs(ic_path, vt_path):
    date_re = re.compile(r'^\d{4}-\d{2}-\d{2}$')

    ic_df = pd.read_csv(ic_path)
    vt_df = pd.read_csv(vt_path)

    ic_df = ic_df[ic_df['Day'].astype(str).str.match(date_re)].copy()
    vt_df = vt_df[vt_df['Day'].astype(str).str.match(date_re)].copy()

    ic_df['P/L'] = pd.to_numeric(ic_df['P/L'], errors='coerce').fillna(0)
    vt_df['P/L'] = pd.to_numeric(vt_df['P/L'], errors='coerce').fillna(0)

    ic_df['month'] = pd.to_datetime(ic_df['Day']).dt.to_period('M').astype(str)
    vt_df['month'] = pd.to_datetime(vt_df['Day']).dt.to_period('M').astype(str)
    ic_m_ser = ic_df.groupby('month')['P/L'].sum()
    vt_m_ser = vt_df.groupby('month')['P/L'].sum()
    months = sorted(set(ic_m_ser.index) | set(vt_m_ser.index))

    month_labels = [
        MONTH_NAMES_ES.get(m.split('-')[1], m.split('-')[1]) + ' ' + m.split('-')[0][-2:]
        for m in months
    ]
    ic_m = [round(float(ic_m_ser.get(m, 0)), 2) for m in months]
    vt_m = [round(float(vt_m_ser.get(m, 0)), 2) for m in months]

    ic_d  = ic_df[['Day', 'P/L', 'Exit']].rename(columns={'P/L': 'ic_pl', 'Exit': 'ic_exit'})
    vt_d  = vt_df[['Day', 'P/L', 'Exit']].rename(columns={'P/L': 'vt_pl', 'Exit': 'vt_exit'})
    daily = (
        pd.merge(ic_d, vt_d, on='Day', how='outer')
        .sort_values('Day')
        .fillna({'ic_pl': 0, 'vt_pl': 0, 'ic_exit': 'NO_ENTRY', 'vt_exit': 'NO_ENTRY'})
    )
    daily['ic_cum']   = daily['ic_pl'].cumsum().round(2)
    daily['vt_cum']   = daily['vt_pl'].cumsum().round(2)
    daily['both_cum'] = (daily['ic_pl'] + daily['vt_pl']).cumsum().round(2)

    table = []
    for _, r in daily.iterrows():
        io = 0 if str(r['ic_exit']) == 'NO_ENTRY' else 1
        vo = 0 if str(r['vt_exit']) == 'NO_ENTRY' else 1
        table.append([
            str(r['Day']),
            io, round(float(r['ic_pl']), 2) if io else None,
            vo, round(float(r['vt_pl']), 2) if vo else None,
        ])

    all_days = sorted(daily['Day'].tolist())
    return {
        'month_labels': month_labels,
        'ic_m':         ic_m,
        'vt_m':         vt_m,
        'days':         list(daily['Day']),
        'ic_cum':       list(daily['ic_cum']),
        'vt_cum':       list(daily['vt_cum']),
        'both_cum':     list(daily['both_cum']),
        'table':        table,
        'date_desde':   fmt_date_es(all_days[0]),
        'date_hasta':   fmt_date_es(all_days[-1]),
        'total_days':   len(table),
    }


def build_html(ic_info, vt_info, data):
    simbolo   = ic_info['simbolo']
    ic_hora   = ic_info['hora']
    vt_hora   = vt_info['hora']
    horas_iguales = ic_hora == vt_hora
    if horas_iguales:
        ic_name = f"{ic_info['estrategia']} {ic_info['riesgo_full']}"
        vt_name = f"{vt_info['estrategia']} {vt_info['riesgo_full']}"
        hora_str = f"Hora {ic_hora}"
    else:
        ic_name = f"{ic_info['estrategia']} {ic_info['riesgo_full']} ({ic_hora})"
        vt_name = f"{vt_info['estrategia']} {vt_info['riesgo_full']} ({vt_hora})"
        hora_str = f"IC {ic_hora} · VT {vt_hora}"
    ct        = ic_info['ct']
    titulo    = f"Dashboard — {ic_info['estrategia']} {ic_info['riesgo_full']} vs {vt_info['estrategia']} {vt_info['riesgo_full']}"
    subtitulo = f"{simbolo} · {hora_str} · Credit Target ${ct} · {data['date_desde']} – {data['date_hasta']}"

    def js(v):      return json.dumps(v)
    def js_table(rows): return '[\n  ' + ',\n  '.join(json.dumps(r) for r in rows) + '\n]'

    return f"""<!DOCTYPE html>
<html lang="es" data-theme="light">
<head>
<meta charset="UTF-8">
<title>{titulo}</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.2.0/chartjs-plugin-datalabels.min.js"></script>
<style>
  /* ── Variables de tema ─────────────────────────────── */
  :root, [data-theme="light"] {{
    --bg:          #f4f6f9;
    --bg-card:     #ffffff;
    --bg-thead:    #f0f2f6;
    --bg-hover:    #f7f8fb;
    --bg-input:    #ffffff;
    --border:      #dde2ec;
    --border-btn:  #d0d6e4;
    --text:        #1e2535;
    --text-sub:    #6b7a99;
    --text-muted:  #9aa3b8;
    --text-btn:    #6b7a99;
    --text-btn-act:#1e2535;
    --bg-btn-act:  #e8ecf5;
    --grid:        #e8ecf5;
    --none-color:  #94a3b8;
    --pl-none-bg:  rgba(148,163,184,.10);
    --pl-none-col: #94a3b8;
    --pl-none-bd:  rgba(148,163,184,.25);
    --pnl-filter:  #9aa3b8;
  }}
  [data-theme="dark"] {{
    --bg:          #080c14;
    --bg-card:     #0f1623;
    --bg-thead:    #0a0f1a;
    --bg-hover:    #0d1220;
    --bg-input:    #0f1623;
    --border:      #1a2236;
    --border-btn:  #1a2236;
    --text:        #cbd5e1;
    --text-sub:    #475569;
    --text-muted:  #334155;
    --text-btn:    #475569;
    --text-btn-act:#e2e8f0;
    --bg-btn-act:  #1a2236;
    --grid:        #0d1524;
    --none-color:  #334155;
    --pl-none-bg:  rgba(30,41,59,.30);
    --pl-none-col: #334155;
    --pl-none-bd:  rgba(30,41,59,.5);
    --pnl-filter:  #1e293b;
  }}

  /* ── Reset y base ──────────────────────────────────── */
  *, *::before, *::after {{ box-sizing: border-box; }}
  body {{ font-family: 'Segoe UI', sans-serif; background: var(--bg); color: var(--text);
          margin: 0; padding: 24px 28px; transition: background .25s, color .25s; }}

  /* ── Header ────────────────────────────────────────── */
  .top-bar {{ display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 4px; }}
  h1 {{ font-size: 1.45rem; color: var(--text); margin: 0; }}
  p.sub {{ color: var(--text-sub); font-size: 0.84rem; margin: 2px 0 22px; }}

  /* ── Toggle dark/light ─────────────────────────────── */
  .theme-toggle {{
    display: flex; align-items: center; gap: 7px; cursor: pointer;
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 20px; padding: 5px 12px 5px 8px;
    font-size: 0.78rem; color: var(--text-sub);
    transition: all .2s; user-select: none; white-space: nowrap; flex-shrink: 0;
  }}
  .theme-toggle:hover {{ border-color: var(--text-sub); }}
  .toggle-track {{
    width: 32px; height: 18px; background: var(--border);
    border-radius: 9px; position: relative; transition: background .2s;
  }}
  [data-theme="dark"] .toggle-track {{ background: #38bdf8; }}
  .toggle-thumb {{
    width: 13px; height: 13px; background: #fff;
    border-radius: 50%; position: absolute; top: 2.5px; left: 2.5px;
    transition: transform .2s; box-shadow: 0 1px 3px rgba(0,0,0,.3);
  }}
  [data-theme="dark"] .toggle-thumb {{ transform: translateX(14px); }}

  /* ── Cards de conteo ───────────────────────────────── */
  .cards {{ display: flex; gap: 12px; margin-bottom: 28px; flex-wrap: wrap; }}
  .card {{ background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px;
           padding: 14px 20px; min-width: 128px; text-align: center; transition: background .25s, border-color .25s; }}
  .card .num {{ font-size: 1.9rem; font-weight: 700; }}
  .card .lbl {{ font-size: 0.72rem; color: var(--text-sub); margin-top: 3px; text-transform: uppercase; letter-spacing: .04em; }}
  .card.ambos .num {{ color: #16a34a; }}
  [data-theme="dark"] .card.ambos .num {{ color: #4ade80; }}
  .card.ic    .num {{ color: #0284c7; }}
  [data-theme="dark"] .card.ic .num {{ color: #38bdf8; }}
  .card.vt    .num {{ color: #ea6c00; }}
  [data-theme="dark"] .card.vt .num {{ color: #fb923c; }}
  .card.none  .num {{ color: var(--none-color); }}

  /* ── PnL bar ───────────────────────────────────────── */
  .pnl-bar {{ display: flex; gap: 12px; margin-bottom: 28px; flex-wrap: wrap; }}
  .pnl-card {{ background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px;
               padding: 12px 20px; flex: 1; min-width: 150px; display: flex; flex-direction: column;
               gap: 3px; transition: background .25s, border-color .25s; }}
  .pnl-card .pnl-label {{ font-size: 0.72rem; color: var(--text-sub); text-transform: uppercase; letter-spacing: .04em; }}
  .pnl-card .pnl-value {{ font-size: 1.55rem; font-weight: 700; font-family: monospace; transition: color .2s; }}
  .pnl-card .pnl-filter {{ font-size: 0.7rem; color: var(--pnl-filter); margin-top: 1px; }}
  .pnl-pos {{ color: #16a34a; }}
  [data-theme="dark"] .pnl-pos {{ color: #4ade80; }}
  .pnl-neg {{ color: #dc2626; }}
  [data-theme="dark"] .pnl-neg {{ color: #f87171; }}

  /* ── Charts ────────────────────────────────────────── */
  .charts-row {{ display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 28px; }}
  @media (max-width: 860px) {{ .charts-row {{ grid-template-columns: 1fr; }} }}
  .chart-box {{ background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px;
                padding: 18px 20px; transition: background .25s, border-color .25s; }}
  .chart-box h2 {{ font-size: 0.88rem; color: var(--text-muted); font-weight: 600;
                   margin: 0 0 14px; text-transform: uppercase; letter-spacing: .05em; }}

  /* ── Toolbar ───────────────────────────────────────── */
  .toolbar {{ display: flex; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; align-items: center; }}
  .toolbar input {{ background: var(--bg-input); border: 1px solid var(--border-btn); color: var(--text);
                    border-radius: 6px; padding: 6px 12px; font-size: 0.84rem; outline: none;
                    transition: background .25s, border-color .25s, color .25s; }}
  .toolbar button {{ background: var(--bg-card); border: 1px solid var(--border-btn); color: var(--text-btn);
                     border-radius: 6px; padding: 6px 14px; font-size: 0.81rem; cursor: pointer; transition: all .15s; }}
  .toolbar button:hover, .toolbar button.active {{ background: var(--bg-btn-act); color: var(--text-btn-act); }}

  /* ── Tabla ─────────────────────────────────────────── */
  .wrap {{ overflow-x: auto; }}
  table {{ border-collapse: collapse; width: 100%; min-width: 580px; font-size: 0.86rem; }}
  thead th {{ background: var(--bg-thead); padding: 10px 14px; text-align: left; color: var(--text-sub);
              font-weight: 600; font-size: 0.76rem; text-transform: uppercase; letter-spacing: .04em;
              position: sticky; top: 0; z-index: 2; transition: background .25s; }}
  tbody tr {{ border-bottom: 1px solid var(--border); transition: background .1s; }}
  tbody tr:hover {{ background: var(--bg-hover); }}
  td {{ padding: 8px 14px; }}
  td.day {{ font-family: monospace; color: var(--text-muted); }}

  /* ── Badges ────────────────────────────────────────── */
  .pl-badge {{ display: inline-block; padding: 3px 9px; border-radius: 5px; font-size: 0.82rem;
               font-weight: 600; font-family: monospace; white-space: nowrap; }}
  .badge-estado {{ display: inline-block; padding: 2px 9px; border-radius: 5px; font-size: 0.78rem; font-weight: 600; }}
  .b-ambos  {{ background: rgba(22,163,74,.10);   color: #16a34a; border: 1px solid rgba(22,163,74,.25); }}
  [data-theme="dark"] .b-ambos  {{ background: rgba(74,222,128,.10);  color: #4ade80; border-color: rgba(74,222,128,.22); }}
  .b-soloic {{ background: rgba(2,132,199,.10);   color: #0284c7; border: 1px solid rgba(2,132,199,.25); }}
  [data-theme="dark"] .b-soloic {{ background: rgba(56,189,248,.10);  color: #38bdf8; border-color: rgba(56,189,248,.22); }}
  .b-solovt {{ background: rgba(234,108,0,.10);   color: #ea6c00; border: 1px solid rgba(234,108,0,.25); }}
  [data-theme="dark"] .b-solovt {{ background: rgba(251,146,60,.10);  color: #fb923c; border-color: rgba(251,146,60,.22); }}
  .b-none   {{ background: rgba(148,163,184,.10); color: #64748b; border: 1px solid rgba(148,163,184,.25); }}
  [data-theme="dark"] .b-none   {{ background: rgba(51,65,85,.10);    color: #334155; border-color: rgba(51,65,85,.25); }}
  .pl-pos   {{ background: rgba(22,163,74,.08);   color: #16a34a; border: 1px solid rgba(22,163,74,.22); }}
  [data-theme="dark"] .pl-pos   {{ background: rgba(74,222,128,.08);  color: #4ade80; border-color: rgba(74,222,128,.18); }}
  .pl-neg   {{ background: rgba(220,38,38,.08);   color: #dc2626; border: 1px solid rgba(220,38,38,.22); }}
  [data-theme="dark"] .pl-neg   {{ background: rgba(248,113,113,.08); color: #f87171; border-color: rgba(248,113,113,.18); }}
  .pl-none  {{ background: var(--pl-none-bg); color: var(--pl-none-col); border: 1px solid var(--pl-none-bd);
               font-weight: 400; font-size: 0.75rem; }}
</style>
</head>
<body>

<div class="top-bar">
  <div>
    <h1>{titulo}</h1>
    <p class="sub">{subtitulo}</p>
  </div>
  <div class="theme-toggle" onclick="toggleTheme()" title="Cambiar tema">
    <div class="toggle-track"><div class="toggle-thumb"></div></div>
    <span id="theme-label">Modo oscuro</span>
  </div>
</div>

<div class="cards">
  <div class="card ambos"><div class="num" id="c-ambos"></div><div class="lbl">✅ Ambos</div></div>
  <div class="card vt">   <div class="num" id="c-vt"></div>   <div class="lbl">⚠️ Solo {vt_info['estrategia']}</div></div>
  <div class="card ic">   <div class="num" id="c-ic"></div>   <div class="lbl">⚠️ Solo IC</div></div>
  <div class="card none"> <div class="num" id="c-none"></div> <div class="lbl">❌ Ninguno</div></div>
</div>

<div class="pnl-bar">
  <div class="pnl-card">
    <div class="pnl-label">P&amp;L Total — {ic_name}</div>
    <div class="pnl-value" id="pnl-ic">$0.00</div>
    <div class="pnl-filter" id="pnl-ic-filter">Todos los días</div>
  </div>
  <div class="pnl-card">
    <div class="pnl-label">P&amp;L Total — {vt_name}</div>
    <div class="pnl-value" id="pnl-vt">$0.00</div>
    <div class="pnl-filter" id="pnl-vt-filter">Todos los días</div>
  </div>
  <div class="pnl-card" style="border-color:#2e2050;">
    <div class="pnl-label">P&amp;L Total — Combinado</div>
    <div class="pnl-value" id="pnl-both">$0.00</div>
    <div class="pnl-filter" id="pnl-both-filter">Todos los días</div>
  </div>
</div>

<div class="charts-row">
  <div class="chart-box">
    <h2>P&amp;L Mensual</h2>
    <canvas id="chartMonthly" height="220"></canvas>
  </div>
  <div class="chart-box">
    <h2>Curva de Rendimiento (Acumulado)</h2>
    <canvas id="chartEquity" height="220"></canvas>
  </div>
</div>

<div class="toolbar">
  <input type="text" id="search" placeholder="🔍 Buscar fecha…" oninput="applyFilters()">
  <button onclick="setFilter('all')"    id="btn-all"    class="active">Todos</button>
  <button onclick="setFilter('ambos')"  id="btn-ambos">✅ Ambos</button>
  <button onclick="setFilter('solovt')" id="btn-solovt">Solo {vt_info['estrategia']}</button>
  <button onclick="setFilter('soloic')" id="btn-soloic">Solo IC</button>
  <button onclick="setFilter('none')"   id="btn-none">Ninguno</button>
</div>

<div class="wrap">
<table>
  <thead>
    <tr><th>Fecha</th><th>{ic_name}</th><th>{vt_name}</th><th>Estado</th></tr>
  </thead>
  <tbody id="tbody"></tbody>
</table>
</div>

<script>
const monthLabels = {js(data['month_labels'])};
const tableData   = {js_table(data['table'])};
const LABEL_IC    = {js(ic_name)};
const LABEL_VT    = {js(vt_name)};

const MONTH_IDX = {{}};
[...new Set(tableData.map(r => r[0].slice(0,7)))].sort().forEach((m,i) => {{ MONTH_IDX[m]=i; }});

function getStatusKey(ic,vt) {{
  if(ic&&vt)  return 'ambos';
  if(ic&&!vt) return 'soloic';
  if(!ic&&vt) return 'solovt';
  return 'none';
}}

function calcChartData(filter) {{
  const icM = new Array(monthLabels.length).fill(0);
  const vtM = new Array(monthLabels.length).fill(0);
  const icC=[], vtC=[], bothC=[], filteredDays=[];
  let icAcc=0, vtAcc=0;
  tableData.forEach(([day,ic,ic_pl,vt,vt_pl]) => {{
    const status  = getStatusKey(ic,vt);
    const visible = filter==='all' || status===filter;
    const mi      = MONTH_IDX[day.slice(0,7)];
    const icVal   = visible&&ic  ? (ic_pl ??0):0;
    const vtVal   = visible&&vt  ? (vt_pl ??0):0;
    if(mi!==undefined){{ icM[mi]+=icVal; vtM[mi]+=vtVal; }}
    icAcc+=icVal; vtAcc+=vtVal;
    filteredDays.push(day);
    icC.push(+icAcc.toFixed(2));
    vtC.push(+vtAcc.toFixed(2));
    bothC.push(+(icAcc+vtAcc).toFixed(2));
  }});
  return {{ icM:icM.map(v=>+v.toFixed(2)), vtM:vtM.map(v=>+v.toFixed(2)), filteredDays, icC, vtC, bothC }};
}}

// Colores solidos con alpha — sin patterns
const C={{
  ic_pos:   'rgba(56,189,248,0.78)',
  ic_neg:   'rgba(248,113,113,0.78)',
  ic_bd_pos:'rgba(56,189,248,1)',
  ic_bd_neg:'rgba(248,113,113,1)',
  vt_pos:   'rgba(251,146,60,0.78)',
  vt_neg:   'rgba(239,68,68,0.60)',
  vt_bd_pos:'rgba(251,146,60,1)',
  vt_bd_neg:'rgba(239,68,68,1)',
  bo_pos:   'rgba(34,197,94,0.65)',
  bo_neg:   'rgba(248,113,113,0.55)',
  bo_bd_pos:'rgba(34,197,94,1)',
  bo_bd_neg:'rgba(248,113,113,1)',
}};
const icBg=v=>v.map(x=>x>=0?C.ic_pos:C.ic_neg);
const icBd=v=>v.map(x=>x>=0?C.ic_bd_pos:C.ic_bd_neg);
const vtBg=v=>v.map(x=>x>=0?C.vt_pos:C.vt_neg);
const vtBd=v=>v.map(x=>x>=0?C.vt_bd_pos:C.vt_bd_neg);
const bothBg=v=>v.map(x=>x>=0?C.bo_pos:C.bo_neg);
const bothBd=v=>v.map(x=>x>=0?C.bo_bd_pos:C.bo_bd_neg);
const bothM=(a,b)=>a.map((v,i)=>+(v+b[i]).toFixed(2));

const initBar=calcChartData('all');
const barChart=new Chart(document.getElementById('chartMonthly').getContext('2d'),{{
  type:'bar',
  data:{{
    labels:monthLabels,
    datasets:[
      {{label:LABEL_IC,   data:initBar.icM,  backgroundColor:icBg(initBar.icM),  borderColor:icBd(initBar.icM),  borderWidth:1.5,borderRadius:4,order:2,clip:false}},
      {{label:LABEL_VT,   data:initBar.vtM,  backgroundColor:vtBg(initBar.vtM),  borderColor:vtBd(initBar.vtM),  borderWidth:1.5,borderRadius:4,order:3,clip:false}},
      {{label:'Combinado',data:bothM(initBar.icM,initBar.vtM),backgroundColor:bothBg(bothM(initBar.icM,initBar.vtM)),borderColor:bothBd(bothM(initBar.icM,initBar.vtM)),borderWidth:1.5,borderRadius:4,order:1,clip:false}}
    ]
  }},
  options:{{
    responsive:true,
    clip:false,
    layout:{{padding:{{top:30,bottom:30}}}},
    plugins:{{
      legend:{{
        labels:{{
          color:'#64748b',font:{{size:11}},boxWidth:22,boxHeight:14,
          generateLabels:(chart)=>[
            {{text:LABEL_IC,   fillStyle:'rgba(56,189,248,0.78)',  strokeStyle:'rgba(56,189,248,1)',  lineWidth:1.5,fontColor:'#64748b',hidden:!chart.isDatasetVisible(0),datasetIndex:0}},
            {{text:LABEL_VT,   fillStyle:'rgba(251,146,60,0.78)',  strokeStyle:'rgba(251,146,60,1)',  lineWidth:1.5,fontColor:'#64748b',hidden:!chart.isDatasetVisible(1),datasetIndex:1}},
            {{text:'Combinado',fillStyle:'rgba(34,197,94,0.65)',   strokeStyle:'rgba(34,197,94,1)',   lineWidth:1.5,fontColor:'#64748b',hidden:!chart.isDatasetVisible(2),datasetIndex:2}}
          ],color:'#64748b',
        }},
        onClick:(e,item,legend)=>{{const ci=legend.chart;ci.getDatasetMeta(item.datasetIndex).hidden=!ci.getDatasetMeta(item.datasetIndex).hidden;ci.update();}}
      }},
      tooltip:{{callbacks:{{label:ctx=>` ${{ctx.dataset.label}}: $${{ctx.parsed.y.toFixed(2)}}`}}}},
      datalabels:{{
        clip:false,
        display:ctx=>ctx.dataset.data[ctx.dataIndex]!==0,
        anchor:ctx=>ctx.dataset.data[ctx.dataIndex]>=0?'end':'start',
        align: ctx=>ctx.dataset.data[ctx.dataIndex]>=0?'end':'start',
        offset:4,
        color:ctx=>ctx.dataset.data[ctx.dataIndex]>=0?'#16a34a':'#dc2626',
        font:{{size:8.5,weight:'700',family:'monospace'}},
        formatter:v=>v===0?'':(v>0?'+':'')+'$'+v.toFixed(0),
        rotation:0,
      }}
    }},
    scales:{{
      x:{{ticks:{{font:{{size:10}},color:'#334155'}},grid:{{color:'#0d1524'}}}},
      y:{{ticks:{{callback:v=>'$'+v,font:{{size:10}},color:'#334155'}},grid:{{color:'#0d1524'}},border:{{dash:[4,4]}}}}
    }}
  }}
}});

const ctxEq=document.getElementById('chartEquity').getContext('2d');
const initEq=calcChartData('all');
function makeGradient(ctx,top,bot){{const g=ctx.createLinearGradient(0,0,0,300);g.addColorStop(0,top);g.addColorStop(1,bot);return g;}}
const eqChart=new Chart(ctxEq,{{
  type:'line',
  data:{{
    labels:initEq.filteredDays,
    datasets:[
      {{label:'Combinado',data:initEq.bothC,borderColor:'#22c55e',backgroundColor:makeGradient(ctxEq,'rgba(34,197,94,0.18)','rgba(34,197,94,0.01)'),borderWidth:2.5,pointRadius:0,tension:0.3,fill:true,order:1}},
      {{label:LABEL_IC,   data:initEq.icC,  borderColor:'#38bdf8',backgroundColor:'transparent',borderWidth:2,pointRadius:0,tension:0.3,borderDash:[6,3],order:2}},
      {{label:LABEL_VT,   data:initEq.vtC,  borderColor:'#fb923c',backgroundColor:'transparent',borderWidth:2,pointRadius:0,tension:0.3,borderDash:[3,3],order:3}}
    ]
  }},
  options:{{
    responsive:true,interaction:{{mode:'index',intersect:false}},
    plugins:{{
      legend:{{labels:{{color:'#64748b',font:{{size:11}},boxWidth:14}}}},
      datalabels:{{display:false}},
      tooltip:{{callbacks:{{title:i=>i[0].label,label:ctx=>` ${{ctx.dataset.label}}: $${{ctx.parsed.y.toFixed(2)}}`}}}}
    }},
    scales:{{
      x:{{ticks:{{maxTicksLimit:10,font:{{size:9.5}},color:'#334155',callback:function(_,i){{const l=this.chart.data.labels[i];return l?l.slice(5):'';}} }},grid:{{color:'#0d1524'}}}},
      y:{{ticks:{{callback:v=>'$'+v,font:{{size:10}},color:'#334155'}},grid:{{color:'#0d1524'}},border:{{dash:[4,4]}}}}
    }}
  }}
}});

function updateCharts(filter){{
  const d=calcChartData(filter);
  barChart.data.datasets[0].data=d.icM;   barChart.data.datasets[0].backgroundColor=icBg(d.icM);   barChart.data.datasets[0].borderColor=icBd(d.icM);
  barChart.data.datasets[1].data=d.vtM;   barChart.data.datasets[1].backgroundColor=vtBg(d.vtM);   barChart.data.datasets[1].borderColor=vtBd(d.vtM);
  const bm=bothM(d.icM,d.vtM);
  barChart.data.datasets[2].data=bm;      barChart.data.datasets[2].backgroundColor=bothBg(bm);     barChart.data.datasets[2].borderColor=bothBd(bm);
  barChart.update();
  eqChart.data.labels=d.filteredDays;
  eqChart.data.datasets[0].data=d.bothC;
  eqChart.data.datasets[1].data=d.icC;
  eqChart.data.datasets[2].data=d.vtC;
  eqChart.update();
}}

const FILTER_LABELS={{all:'Todos los días',ambos:'Solo días: Ambos abrieron',soloic:'Solo días: Solo IC abrió',solovt:'Solo días: Solo Vertical abrió',none:'Solo días: Ninguno abrió'}};

function updatePNL(filter){{
  const d=calcChartData(filter);
  const icT=d.icC[d.icC.length-1]??0;
  const vtT=d.vtC[d.vtC.length-1]??0;
  const bT=d.bothC[d.bothC.length-1]??0;
  const lbl=FILTER_LABELS[filter]||'Todos los días';
  const fmt=v=>(v>=0?'+':'')+'$'+v.toFixed(2);
  const cls=v=>v>=0?'pnl-pos':'pnl-neg';
  ['pnl-ic','pnl-vt','pnl-both'].forEach(id=>{{document.getElementById(id).className='pnl-value';}});
  const eIC=document.getElementById('pnl-ic');
  const eVT=document.getElementById('pnl-vt');
  const eBT=document.getElementById('pnl-both');
  eIC.textContent=fmt(icT); eIC.classList.add(cls(icT));
  eVT.textContent=fmt(vtT); eVT.classList.add(cls(vtT));
  eBT.textContent=fmt(bT);  eBT.classList.add(cls(bT));
  document.getElementById('pnl-ic-filter').textContent=lbl;
  document.getElementById('pnl-vt-filter').textContent=lbl;
  document.getElementById('pnl-both-filter').textContent=lbl;
}}

let currentFilter='all';
function getStatus(ic,vt){{
  if(ic&&vt)  return{{key:'ambos', label:'✅ Ambos',         cls:'b-ambos'}};
  if(ic&&!vt) return{{key:'soloic',label:'⚠️ Solo IC',       cls:'b-soloic'}};
  if(!ic&&vt) return{{key:'solovt',label:'⚠️ Solo Vertical', cls:'b-solovt'}};
  return        {{key:'none',  label:'❌ Ninguno',        cls:'b-none'}};
}}
function plBadge(open,pl){{
  if(!open) return`<span class="pl-badge pl-none">— No abrió</span>`;
  const sign=pl>=0?'+':'';const cls=pl>=0?'pl-pos':'pl-neg';const icon=pl>=0?'▲':'▼';
  return`<span class="pl-badge ${{cls}}">${{icon}} ${{sign}}$${{pl.toFixed(2)}}</span>`;
}}
function buildTable(){{
  const tbody=document.getElementById('tbody');tbody.innerHTML='';
  let counts={{ambos:0,soloic:0,solovt:0,none:0}};
  tableData.forEach(([day,ic,ic_pl,vt,vt_pl])=>{{
    const s=getStatus(ic,vt);counts[s.key]++;
    const tr=document.createElement('tr');tr.dataset.status=s.key;tr.dataset.day=day;
    tr.innerHTML=`<td class="day">${{day}}</td><td>${{plBadge(ic,ic_pl)}}</td><td>${{plBadge(vt,vt_pl)}}</td><td><span class="badge-estado ${{s.cls}}">${{s.label}}</span></td>`;
    tbody.appendChild(tr);
  }});
  document.getElementById('c-ambos').textContent=counts.ambos;
  document.getElementById('c-ic').textContent=counts.soloic;
  document.getElementById('c-vt').textContent=counts.solovt;
  document.getElementById('c-none').textContent=counts.none;
}}
function applyFilters(){{
  const q=document.getElementById('search').value.toLowerCase();
  document.querySelectorAll('#tbody tr').forEach(tr=>{{
    tr.style.display=(currentFilter==='all'||tr.dataset.status===currentFilter)&&(!q||tr.dataset.day.includes(q))?'':'none';
  }});
}}
function setFilter(f){{
  currentFilter=f;
  document.querySelectorAll('.toolbar button').forEach(b=>b.classList.remove('active'));
  document.getElementById('btn-'+f).classList.add('active');
  applyFilters();updateCharts(f);updatePNL(f);
}}
buildTable();
updatePNL('all');

// ── Theme toggle ────────────────────────────────────────
function getThemeColors() {{
  const dark = document.documentElement.getAttribute('data-theme') === 'dark';
  return {{
    grid:    dark ? '#0d1524'  : '#e8ecf5',
    tick:    dark ? '#334155'  : '#9aa3b8',
    legend:  dark ? '#64748b'  : '#6b7a99',
    dlabel:  dark ? '#64748b'  : '#9aa3b8',
    icLine:  dark ? '#38bdf8'  : '#0284c7',
    vtLine:  dark ? '#fb923c'  : '#ea6c00',
    boLine:  dark ? '#22c55e'  : '#16a34a',
    boGradT: dark ? 'rgba(34,197,94,0.18)' : 'rgba(22,163,74,0.12)',
    boGradB: dark ? 'rgba(34,197,94,0.01)' : 'rgba(22,163,74,0.01)',
  }};
}}
function applyThemeToCharts() {{
  const t = getThemeColors();
  const ctx = document.getElementById('chartEquity').getContext('2d');
  const newGrad = makeGradient(ctx, t.boGradT, t.boGradB);

  // Bar chart
  [barChart, eqChart].forEach(ch => {{
    ch.options.scales.x.grid.color  = t.grid;
    ch.options.scales.y.grid.color  = t.grid;
    ch.options.scales.x.ticks.color = t.tick;
    ch.options.scales.y.ticks.color = t.tick;
    ch.options.plugins.legend.labels.color = t.legend;
  }});
  barChart.options.plugins.datalabels.color = t.dlabel;

  eqChart.data.datasets[0].borderColor      = t.boLine;
  eqChart.data.datasets[0].backgroundColor  = newGrad;
  eqChart.data.datasets[1].borderColor      = t.icLine;
  eqChart.data.datasets[2].borderColor      = t.vtLine;

  barChart.update(); eqChart.update();
}}
function toggleTheme() {{
  const html  = document.documentElement;
  const isDark = html.getAttribute('data-theme') === 'dark';
  html.setAttribute('data-theme', isDark ? 'light' : 'dark');
  document.getElementById('theme-label').textContent = isDark ? 'Modo oscuro' : 'Modo claro';
  applyThemeToCharts();
}}
// Inicializar colores de charts con el tema por defecto (light)
applyThemeToCharts();
</script>
</body>
</html>
"""


def main():
    print("=" * 60)
    print("  Dashboard Generator — IC vs Vertical")
    print("=" * 60)

    ic_path = archivoIC
    vt_path = archivoVer

    if not ic_path or not vt_path:
        print("\n❌ Completá archivoIC y archivoVer al inicio del script.")
        sys.exit(1)

    for p in [ic_path, vt_path]:
        if not os.path.isfile(p):
            print(f"\n❌ Archivo no encontrado: {p}")
            sys.exit(1)

    print(f"\n📂 IC      : {Path(ic_path).name}")
    print(f"📂 Vertical: {Path(vt_path).name}")

    ic_info = parse_filename(ic_path)
    vt_info = parse_filename(vt_path)

    print(f"\n🔍 Detectado:")
    print(f"   Estrategia IC  : {ic_info['estrategia']}")
    print(f"   Estrategia VT  : {vt_info['estrategia']} {vt_info['riesgo_full']}")
    print(f"   Símbolo        : {ic_info['simbolo']}")
    print(f"   Hora           : {ic_info['hora']}")
    print(f"   CT             : ${ic_info['ct']}")

    print("\n⚙️  Procesando datos...")
    data = process_csvs(ic_path, vt_path)

    print(f"   Días totales   : {data['total_days']}")
    print(f"   Período        : {data['date_desde']} → {data['date_hasta']}")
    print(f"   Meses          : {len(data['month_labels'])}")

    html = build_html(ic_info, vt_info, data)

    sym   = ic_info['simbolo']
    strat = f"{ic_info['estrategia'].replace(' ','')}{ic_info['riesgo_full'].replace(' ','')}_vs_{vt_info['estrategia'].replace(' ','')}{vt_info['riesgo_full'].replace(' ','')}"
    d1    = ic_info['fecha_desde'].replace('-','')
    d2    = ic_info['fecha_hasta'].replace('-','')
    out_name = f"dashboard_{sym}_{strat}_{d1}_{d2}.html"
    out_path = Path.cwd() / out_name

    with open(out_path, 'w', encoding='utf-8') as f:
        f.write(html)

    print(f"\n✅ Dashboard generado:")
    print(f"   {out_path}")
    print(f"\n🌐 Abrí el archivo en tu navegador para verlo.")


if __name__ == '__main__':
    main()