import { useEffect, useState, useRef, useMemo } from 'react';
import { api } from '../api.js';
import { useInteretsChart } from '../context/InteretsChartContext.jsx';
import { fmtEUR, fmtPct } from '../utils/format.js';

const ICONS_BASE = '/api/icons-files/';
const MOIS_LONG  = ['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre'];

function hexToRgba(hex, a) {
  if (!hex || hex.length < 7) return `rgba(79,168,232,${a})`;
  const r = parseInt(hex.slice(1,3),16), g = parseInt(hex.slice(3,5),16), b = parseInt(hex.slice(5,7),16);
  return `rgba(${r},${g},${b},${a})`;
}

function ChevronDown({ size = 10 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M6 9l6 6 6-6"/>
    </svg>
  );
}

/* ── Fusionne deux maps de remboursements ou projections ── */
function mergeMaps(mapA, mapB) {
  const result = {};
  const keys = new Set([...Object.keys(mapA || {}), ...Object.keys(mapB || {})]);
  for (const k of keys) {
    const a = mapA?.[k] || {};
    const b = mapB?.[k] || {};
    result[k] = {
      interets_bruts:  (a.interets_bruts  || 0) + (b.interets_bruts  || 0),
      interets_nets:   (a.interets_nets   || 0) + (b.interets_nets   || 0),
      cashback:        (a.cashback        || 0) + (b.cashback        || 0),
      capital:         (a.capital         || 0) + (b.capital         || 0),
      interets_prevus: (a.interets_prevus || 0) + (b.interets_prevus || 0),
      capital_prevu:   (a.capital_prevu   || 0) + (b.capital_prevu   || 0),
    };
  }
  return result;
}

export default function TableauInteretsPlateforme({ activeView, activeId, pfuRates, onCapitalMensuel, expandButton, onCellClick, activeCell }) {
  const {
    annee, setAnnee, availableYears,
    inclureInterets, setInclureInterets,
    inclureCapital,  setInclureCapital,
    inclureCashback, setInclureCashback,
    netMode,
    showActual, toggleActual,
    showProjected, toggleProjected,
    modeGlobal, toggleModeGlobal,
    currentYear, currentMonth,
    chartInterets, chartCapital, chartCashback,
  } = useInteretsChart();

  const [data,        setData]        = useState(null);
  const [libIcons,    setLibIcons]    = useState({});
  const [windowStart, setWindowStart] = useState(0);
  const initializedRef = useRef(false);

  /* ── Toggle consolidation détenteurs (clé partagée avec CapitalMensuelTable) ── */
  const [groupByNom, setGroupByNom] = useState(() => {
    try { return localStorage.getItem('cl_tip_group_by_nom') === 'true'; } catch { return false; }
  });
  const toggleGroupByNom = () => {
    setGroupByNom(v => {
      const next = !v;
      try { localStorage.setItem('cl_tip_group_by_nom', String(next)); } catch {}
      return next;
    });
  };

  /* ── Icônes bibliothèque ─────────────────────────────────────── */
  useEffect(() => {
    api.get('/icons').then(rows => {
      const m = {};
      rows.forEach(r => { m[r.name] = r.filename; });
      setLibIcons(m);
    }).catch(() => {});
  }, []);

  /* ── Fenêtre années ──────────────────────────────────────────── */
  const canPrev      = windowStart > 0;
  const canNext      = windowStart + 3 < availableYears.length;
  const visibleYears = availableYears.length ? availableYears.slice(windowStart, windowStart + 3) : [annee];

  useEffect(() => {
    if (!availableYears.length || initializedRef.current) return;
    initializedRef.current = true;
    const idx  = availableYears.indexOf(annee);
    const safe = idx >= 0 ? idx : availableYears.length - 1;
    setWindowStart(Math.max(0, Math.min(availableYears.length - 3, safe - 1)));
  }, [availableYears]);

  /* ── Réduction PFU ───────────────────────────────────────────── */
  const pfuReduction = useMemo(() => {
    if (!pfuRates?.length) return 0;
    const r = pfuRates.find(r => r.annee === annee)
      ?? pfuRates.reduce((best, r) => r.annee > best.annee ? r : best, pfuRates[0]);
    return (r.prelev_sociaux + r.impot_revenu) / 100;
  }, [pfuRates, annee]);

  /* ── Fetch données ───────────────────────────────────────────── */
  useEffect(() => {
    if (modeGlobal) { setData(null); onCapitalMensuel?.([]); return; }
    const params = { annee, ...(activeView === 'all' ? { scope: 'all' } : {}) };
    api.get('/dashboard/interets-par-plateforme', params)
      .then(d => { setData(d); onCapitalMensuel?.(d.capitalMensuel ?? []); })
      .catch(() => {});
  }, [annee, activeView, activeId, modeGlobal]);

  /* ── Helpers affichage ───────────────────────────────────────── */
  const AppIcon = ({ name, size = 28, active = false }) => {
    const filename = libIcons[name];
    if (filename) return (
      <img src={ICONS_BASE + filename} className="app-lib-icon" width={size} height={size}
        aria-hidden="true"
        style={{ opacity: active ? 1 : 0.35, display: 'block', transition: 'opacity .15s' }} />
    );
    return <span style={{ width: size, height: size, display: 'block', borderRadius: 4,
      background: 'var(--text-muted)', opacity: active ? 0.55 : 0.2, transition: 'opacity .15s' }} />;
  };

  const plateformes    = data?.plateformes ?? [];
  const capitalMensuel = data?.capitalMensuel ?? [];

  // N'afficher le détenteur que s'il y en a plusieurs distincts (pattern multiDetenteur)
  const multiDetenteur = new Set(plateformes.map(p => p.detenteur_nom).filter(Boolean)).size > 1;

  /* ── Consolidation par nom si demandée ──────────────────────── */
  const displayPlateformes = useMemo(() => {
    if (!groupByNom || !multiDetenteur) return plateformes;
    const byNom = {};
    for (const plat of plateformes) {
      if (!byNom[plat.nom]) {
        byNom[plat.nom] = {
          ...plat,
          id:   plat.nom,
          _ids: [plat.id],          // ← tous les IDs numériques fusionnés
          detenteur_nom: null,
          rembourses:   { ...plat.rembourses },
          projections:  { ...plat.projections },
        };
      } else {
        byNom[plat.nom]._ids.push(plat.id);
        byNom[plat.nom].rembourses  = mergeMaps(byNom[plat.nom].rembourses,  plat.rembourses);
        byNom[plat.nom].projections = mergeMaps(byNom[plat.nom].projections, plat.projections);
      }
    }
    return Object.values(byNom);
  }, [plateformes, groupByNom, multiDetenteur]);

  if (modeGlobal || !data || plateformes.length === 0) {
    return null;
  }

  /* ── Valeurs par plateforme/mois ────────────────────────────────
   *  getCellValue  : pour l'affichage (interets + cashback + capital selon toggles)
   *  getPerfValue  : pour la performance (interets + cashback uniquement, jamais capital)
   * ─────────────────────────────────────────────────────────────── */
  const buildValue = (plat, mIdx, { withCapital }) => {
    const m       = mIdx + 1;
    const moisStr = `${annee}-${String(m).padStart(2, '0')}`;
    const isFuture  = annee > currentYear || (annee === currentYear && m > currentMonth);
    const isCurrent = annee === currentYear && m === currentMonth;

    if (isFuture) {
      if (!showProjected) return null;
      const proj = plat.projections[moisStr];
      if (!proj) return null;
      let v = 0;
      if (inclureInterets) v += netMode ? proj.interets_prevus * (1 - pfuReduction) : proj.interets_prevus;
      if (withCapital && inclureCapital) v += proj.capital_prevu ?? 0;
      return v > 0 ? { value: v, projected: true } : null;
    }

    if (isCurrent) {
      const remb = plat.rembourses[moisStr];
      const proj = plat.projections[moisStr];
      let real = 0;
      if (showActual && remb) {
        if (inclureInterets)               real += netMode ? remb.interets_nets : remb.interets_bruts;
        if (inclureCashback)               real += remb.cashback ?? 0;
        if (withCapital && inclureCapital)  real += remb.capital ?? 0;
      }
      let projAmt = 0;
      // Les projections backend sont déjà filtrées NOT EXISTS par investissement → pas de double-comptage
      if (showProjected && proj) {
        if (inclureInterets)               projAmt += netMode ? proj.interets_prevus * (1 - pfuReduction) : proj.interets_prevus;
        if (withCapital && inclureCapital)  projAmt += proj.capital_prevu ?? 0;
      }
      const val = real + projAmt;
      return val > 0 ? { value: val, projected: projAmt > 0 } : null;
    }

    // Mois passé
    if (!showActual) return null;
    const remb = plat.rembourses[moisStr];
    if (!remb) return null;
    let v = 0;
    if (inclureInterets)               v += netMode ? remb.interets_nets : remb.interets_bruts;
    if (inclureCashback)               v += remb.cashback ?? 0;
    if (withCapital && inclureCapital)  v += remb.capital ?? 0;
    return v > 0 ? { value: v, projected: false } : null;
  };

  const getCellValue = (plat, mIdx) => buildValue(plat, mIdx, { withCapital: true });
  const getPerfValue = (plat, mIdx) => buildValue(plat, mIdx, { withCapital: false });

  /* ── Grille ──────────────────────────────────────────────────── */
  const grid = displayPlateformes.map(plat => ({
    ...plat,
    months: Array.from({ length: 12 }, (_, i) => getCellValue(plat, i)),
  }));

  const monthTotals = Array.from({ length: 12 }, (_, i) =>
    grid.reduce((s, row) => s + (row.months[i]?.value ?? 0), 0));
  const platTotals  = grid.map(row =>
    row.months.reduce((s, v) => s + (v?.value ?? 0), 0));
  const grandTotal  = monthTotals.reduce((s, v) => s + v, 0);

  /* Totaux pour la performance : intérêts + cashback uniquement (sans capital) */
  const perfMonthTotals = Array.from({ length: 12 }, (_, i) =>
    displayPlateformes.reduce((s, plat) => s + (getPerfValue(plat, i)?.value ?? 0), 0));
  const perfGrandTotal  = perfMonthTotals.reduce((s, v) => s + v, 0);

  /* ── Capital et performances ─────────────────────────────────── */
  const capitalValues = capitalMensuel.map(c => c.capital);
  const nonZeroCap    = capitalValues.filter(v => v > 0);
  const avgCapital    = nonZeroCap.length ? nonZeroCap.reduce((s, v) => s + v, 0) / nonZeroCap.length : 0;
  const lastCapital   = [...capitalValues].reverse().find(v => v > 0) ?? avgCapital;

  const perfMensuelle  = Array.from({ length: 12 }, (_, i) =>
    capitalValues[i] > 0 ? perfMonthTotals[i] / capitalValues[i] : null);
  const perfAnnualisee = perfMensuelle.map(p => p !== null ? p * 12 : null);
  const perfAnnTotale  = lastCapital > 0 ? perfGrandTotal / lastCapital : null;

  /* ── Label total header ──────────────────────────────────────── */
  const activeTypes = [
    inclureInterets && { color: chartInterets, label: netMode ? 'Intérêts nets' : 'Intérêts bruts' },
    inclureCapital  && { color: chartCapital,  label: 'Capital' },
    inclureCashback && { color: chartCashback, label: 'Cashback' },
  ].filter(Boolean);

  /* ── Rendu ───────────────────────────────────────────────────── */
  return (
    <div className="solde-chart-wrap" style={{ padding: '24px 24px 16px', marginBottom: 24 }}>

      {/* ── Header identique au bar chart ── */}
      <div className="solde-chart-header">
        <div className="solde-chart-info">
          <div style={{ display:'flex', alignItems:'center', gap:5, flexWrap:'wrap', marginBottom:2 }}>
            {inclureInterets && (
              <span style={{ display:'inline-flex', alignItems:'center', gap:4,
                background:hexToRgba(chartInterets,0.12), borderRadius:5, padding:'3px 8px' }}>
                <span style={{ width:7, height:7, borderRadius:2, background:chartInterets, flexShrink:0 }}/>
                <span style={{ fontSize:13, color:chartInterets, fontWeight:600 }}>
                  {netMode ? 'Intérêts nets' : 'Intérêts bruts'}
                </span>
              </span>
            )}
            {inclureCapital && (
              <span style={{ display:'inline-flex', alignItems:'center', gap:4,
                background:hexToRgba(chartCapital,0.12), borderRadius:5, padding:'3px 8px' }}>
                <span style={{ width:7, height:7, borderRadius:2, background:chartCapital, flexShrink:0 }}/>
                <span style={{ fontSize:13, color:chartCapital, fontWeight:600 }}>Capital</span>
              </span>
            )}
            {inclureCashback && (
              <span style={{ display:'inline-flex', alignItems:'center', gap:4,
                background:hexToRgba(chartCashback,0.12), borderRadius:5, padding:'3px 8px' }}>
                <span style={{ width:7, height:7, borderRadius:2, background:chartCashback, flexShrink:0 }}/>
                <span style={{ fontSize:13, color:chartCashback, fontWeight:600 }}>Cashback</span>
              </span>
            )}
            {!inclureInterets && !inclureCapital && !inclureCashback && (
              <span style={{ fontSize:13, color:'var(--text-muted)' }}>—</span>
            )}
            <span style={{ fontSize:13, color:'var(--text-muted)' }}>· {annee}</span>
          </div>
          <div className="solde-chart-value">{fmtEUR(grandTotal)}</div>
        </div>

        <div className="solde-chart-controls">
          {/* Bouton intérêts */}
          <button
            title={inclureInterets ? 'Intérêts inclus — cliquer pour exclure' : 'Cliquer pour inclure les intérêts'}
            onClick={() => setInclureInterets(v => !v)}
            style={{ background: inclureInterets ? hexToRgba(chartInterets,0.13) : 'none',
              border:'1px solid '+(inclureInterets ? chartInterets : 'transparent'),
              borderRadius:8, padding:'4px 6px', cursor:'pointer', display:'flex', alignItems:'center',
              transition:'background .15s,border-color .15s', marginRight:2 }}>
            <AppIcon name="interets" active={inclureInterets} />
          </button>
          {/* Bouton capital */}
          <button
            title={inclureCapital ? 'Capital inclus — cliquer pour exclure' : 'Cliquer pour inclure le capital'}
            onClick={() => setInclureCapital(v => !v)}
            style={{ background: inclureCapital ? hexToRgba(chartCapital,0.13) : 'none',
              border:'1px solid '+(inclureCapital ? chartCapital : 'transparent'),
              borderRadius:8, padding:'4px 6px', cursor:'pointer', display:'flex', alignItems:'center',
              transition:'background .15s,border-color .15s', marginRight:2 }}>
            <AppIcon name="capital" active={inclureCapital} />
          </button>
          {/* Bouton cashback */}
          <button
            title={inclureCashback ? 'Cashback inclus — cliquer pour exclure' : 'Cliquer pour inclure le cashback'}
            onClick={() => setInclureCashback(v => !v)}
            style={{ background: inclureCashback ? hexToRgba(chartCashback,0.13) : 'none',
              border:'1px solid '+(inclureCashback ? chartCashback : 'transparent'),
              borderRadius:8, padding:'4px 6px', cursor:'pointer', display:'flex', alignItems:'center',
              transition:'background .15s,border-color .15s', marginRight:2 }}>
            <AppIcon name="cashback" active={inclureCashback} />
          </button>

          {/* Sélecteur d'années */}
          <div className="solde-chart-ranges">
            <button className="solde-range-btn"
              onClick={() => setWindowStart(w => Math.max(0, w-1))}
              disabled={!canPrev} style={{ opacity: canPrev ? 1 : 0.3 }}>‹</button>
            {visibleYears.map(y => (
              <button key={y} className={`solde-range-btn${annee === y ? ' active' : ''}`}
                onClick={() => setAnnee(y)}>
                {y}
              </button>
            ))}
            <button className="solde-range-btn"
              onClick={() => setWindowStart(w => Math.min(Math.max(0, availableYears.length - 3), w+1))}
              disabled={!canNext} style={{ opacity: canNext ? 1 : 0.3 }}>›</button>
            <button className={`solde-range-btn${modeGlobal ? ' active' : ''}`}
              onClick={() => toggleModeGlobal()}>
              TOUT
            </button>
            {expandButton}
          </div>
        </div>
      </div>

      {/* ── Tableau ── */}
      <div style={{ overflowX: 'auto', marginTop: 20, position: 'relative', zIndex: 0 }}>
        <table className="tip-table">
          <thead>
            <tr>
              <th className="tip-th-empty" />
              <th className="tip-th-year" colSpan={12}>{annee}</th>
              <th className="tip-th-empty" />
              <th className="tip-th-empty" />
            </tr>
            <tr>
              <th className="tip-th-name tip-th-name-amber">
                <span style={{ display:'flex', alignItems:'center', gap:6 }}>
                  Plateforme
                  {multiDetenteur && (
                    <button
                      onClick={() => toggleGroupByNom()}
                      title={groupByNom ? 'Vue consolidée — cliquer pour détailler par détenteur' : 'Vue détaillée — cliquer pour consolider par plateforme'}
                      style={{
                        display:'inline-flex', alignItems:'center', gap:3,
                        background:'rgba(255,255,255,0.15)', border:'1px solid rgba(255,255,255,0.3)',
                        borderRadius:4, padding:'2px 5px', cursor:'pointer',
                        fontSize:10, fontWeight:600, color:'#fff', letterSpacing:'.03em',
                        lineHeight:1.4, whiteSpace:'nowrap', transition:'background .15s',
                      }}>
                      {groupByNom ? 'Consolidé' : 'Détaillé'}
                      <span style={{ display:'inline-flex', transition:'transform .2s', transform: groupByNom ? 'rotate(180deg)' : 'rotate(0deg)' }}>
                        <ChevronDown size={9} />
                      </span>
                    </button>
                  )}
                </span>
              </th>
              {MOIS_LONG.map((m, i) => (
                <th key={m} className={`tip-th-month${annee === currentYear && i === currentMonth - 1 ? ' tip-th-month-current' : ''}`}>{m}</th>
              ))}
              <th className="tip-th-total">Total</th>
              <th className="tip-th-avg">Moy. mensuelle</th>
            </tr>
          </thead>

          <tbody>
            {grid.map((plat, pi) => (
              <tr key={plat.id} className="tip-row-plat">
                <td className="tip-td-name">
                  {plat.nom}
                  {!groupByNom && multiDetenteur && plat.detenteur_nom && (
                    <span style={{ marginLeft: 6, fontSize: 'var(--fs-xs)', color: 'var(--text-muted)', fontWeight: 400 }}>
                      {plat.detenteur_nom}
                    </span>
                  )}
                </td>
                {plat.months.map((v, mi) => {
                  const isCurrent = annee === currentYear && mi === currentMonth - 1;
                  const cellKey   = `${plat.id}:${annee}-${String(mi + 1).padStart(2,'0')}`;
                  const isActive  = activeCell?.key === cellKey;
                  const clickable = !!v;
                  return (
                    <td key={mi}
                      className={`tip-td-num${v?.projected ? ' tip-projected' : ''}${isCurrent ? ' tip-col-current' : ''}${isActive ? ' tip-td-active' : ''}${clickable ? ' tip-td-clickable' : ''}`}
                      onClick={() => clickable && onCellClick && onCellClick({
                        key:      cellKey,
                        platId:   plat._ids ? plat._ids[0] : plat.id,  // toujours numérique
                        platIds:  plat._ids ?? [plat.id],               // tous les IDs (consolidé)
                        platNom:  plat.nom,
                        annee,
                        mois:     String(mi + 1).padStart(2, '0'),
                        moisLabel: MOIS_LONG[mi],
                      })}
                    >
                      {v ? fmtEUR(v.value) : <span className="tip-dash">—</span>}
                    </td>
                  );
                })}
                <td className="tip-td-total">
                  {platTotals[pi] > 0 ? fmtEUR(platTotals[pi]) : <span className="tip-dash">—</span>}
                </td>
                <td className="tip-td-avg">
                  {platTotals[pi] > 0 ? fmtEUR(platTotals[pi] / 12) : <span className="tip-dash">—</span>}
                </td>
              </tr>
            ))}
          </tbody>

          <tfoot>
            <tr className="tip-footer-total">
              <td className="tip-td-name">Toutes les plateformes</td>
              {monthTotals.map((v, i) => (
                <td key={i} className={`tip-td-num${annee === currentYear && i === currentMonth - 1 ? ' tip-col-current' : ''}`}>
                  {v > 0 ? fmtEUR(v) : <span className="tip-dash">—</span>}
                </td>
              ))}
              <td className="tip-td-total">{fmtEUR(grandTotal)}</td>
              <td className="tip-td-avg">{grandTotal > 0 ? fmtEUR(grandTotal / 12) : <span className="tip-dash">—</span>}</td>
            </tr>
            <tr className="tip-footer-capital">
              <td className="tip-td-name">Capital investi</td>
              {capitalValues.map((v, i) => (
                <td key={i} className={`tip-td-num${annee === currentYear && i === currentMonth - 1 ? ' tip-col-current' : ''}`}>
                  {v > 0 ? fmtEUR(v) : <span className="tip-dash">—</span>}
                </td>
              ))}
              <td className="tip-td-total">{lastCapital > 0 ? fmtEUR(lastCapital) : <span className="tip-dash">—</span>}</td>
              <td className="tip-td-void" />
            </tr>
            <tr className="tip-footer-perf">
              <td className="tip-td-name">{netMode ? "Performance nette mensuelle" : "Performance brute mensuelle"}</td>
              {perfMensuelle.map((v, i) => (
                <td key={i} className={`tip-td-num${annee === currentYear && i === currentMonth - 1 ? ' tip-col-current' : ''}`}>
                  {v !== null ? fmtPct(v * 100) : <span className="tip-dash">—</span>}
                </td>
              ))}
              <td className="tip-td-total">
                {perfAnnTotale !== null ? fmtPct((perfAnnTotale / 12) * 100) : <span className="tip-dash">—</span>}
              </td>
              <td className="tip-td-void" />
            </tr>
            <tr className="tip-footer-perf">
              <td className="tip-td-name">{netMode ? "Performance nette annualisée" : "Performance brute annualisée"}</td>
              {perfAnnualisee.map((v, i) => (
                <td key={i} className={`tip-td-num${annee === currentYear && i === currentMonth - 1 ? ' tip-col-current' : ''}`}>
                  {v !== null ? fmtPct(v * 100) : <span className="tip-dash">—</span>}
                </td>
              ))}
              <td className="tip-td-total">
                {perfAnnTotale !== null ? fmtPct(perfAnnTotale * 100) : <span className="tip-dash">—</span>}
              </td>
              <td className="tip-td-void" />
            </tr>
          </tfoot>
        </table>
      </div>

      {/* ── Sélecteur Reçu / Projeté ── */}
      <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginTop:12, gap:12, flexWrap:'wrap' }}>
        <div style={{
          display:'inline-flex',
          background:'#f0f0f0',
          borderRadius:8,
          padding:3,
          gap:2,
          flexShrink:0,
        }}>
          {[
            { key:'actual',    label:'Reçu',    active:showActual,    toggle:toggleActual },
            { key:'projected', label:'Projeté', active:showProjected, toggle:toggleProjected },
          ].map(btn => (
            <button key={btn.key} onClick={() => btn.toggle()} style={{
              border:'none', cursor:'pointer', padding:'5px 14px', borderRadius:6,
              fontSize:'var(--fs-sm)',
              fontWeight: btn.active ? 600 : 400,
              background: btn.active ? '#ffffff' : 'transparent',
              color:      btn.active ? '#1a1a2e' : '#9ca3af',
              boxShadow:  btn.active ? '0 1px 3px rgba(0,0,0,0.13)' : 'none',
              transition: 'all .15s', lineHeight: 1.4,
            }}>{btn.label}</button>
          ))}
        </div>
      </div>

    </div>
  );
}
