import { useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { api } from '../api.js';
import { useInvestisseur } from '../context/InvestisseurContext.jsx';
import { fmtDate } from '../utils/format.js';
import ResultBanner from '../components/ResultBanner.jsx';

const MODULES = {
  depots_retraits: {
    label: 'Dépôts / Retraits',
    required: ['date_operation', 'type', 'montant'],
    optional: ['plateforme_id', 'libelle', 'reference'],
    needsInvestisseur: true,
  },
  investissements: {
    label: 'Investissements',
    required: ['nom_projet', 'date_souscription', 'montant_investi'],
    optional: ['plateforme_id', 'emetteur', 'date_premiere_echeance', 'date_cible', 'taux_interet', 'duree_mois', 'type_remb', 'freq_interets', 'statut', 'reference'],
    needsInvestisseur: true,
  },
  remboursements: {
    label: 'Remboursements',
    required: ['investissement_id', 'date_remb'],
    optional: ['capital', 'interets_bruts', 'prelev_sociaux', 'prelev_forfaitaire', 'net_recu', 'statut'],
    needsInvestisseur: true,
  },
  plateformes: {
    label: 'Plateformes',
    required: ['nom'],
    optional: ['url', 'notes'],
    needsInvestisseur: false,
    note: 'Les plateformes dont le nom existe déjà seront ignorées (pas d\'écrasement).',
  },
  taux_pfu: {
    label: 'Flat Tax — Taux PFU',
    required: ['annee', 'pfu_total', 'impot_revenu', 'prelev_sociaux'],
    optional: [],
    needsInvestisseur: false,
    global: true,
    note: 'Table de référence globale. Si une année existe déjà, ses taux seront mis à jour (upsert).',
  },
};

const MODULE_LABEL = {
  depots_retraits: 'Dépôts / Retraits',
  investissements: 'Investissements',
  remboursements:  'Remboursements',
  plateformes:     'Plateformes',
  taux_pfu:        'Flat Tax — Taux PFU',
};

export default function Imports() {
  const { activeId } = useInvestisseur();
  const navigate = useNavigate();

  // ── Import classique (xlsx/csv/json) ──────────────────────────
  const [module,         setModule]         = useState('depots_retraits');
  const [file,           setFile]           = useState(null);
  const [preview,        setPreview]        = useState(null);
  const [mapping,        setMapping]        = useState({});
  const [defaults,       setDefaults]       = useState({});
  const [plats,          setPlats]          = useState([]);
  const [investissements,setInvestissements] = useState([]);
  const [history,        setHistory]        = useState([]);
  const [result,         setResult]         = useState(null);
  const [busy,           setBusy]           = useState(false);
  const [err,            setErr]            = useState(null);

  // ── Import dossier investissement ─────────────────────────────
  const [dossierFile,    setDossierFile]    = useState(null);
  const [dossierPreview, setDossierPreview] = useState(null); // parsed JSON for review
  const [dossierResult,  setDossierResult]  = useState(null);
  const [dossierBusy,    setDossierBusy]    = useState(false);
  const [dossierErr,     setDossierErr]     = useState(null);
  const dossierInputRef = useRef(null);

  // History + plateformes sont user-scoped → chargement sans activeId
  useEffect(() => {
    api.get('/imports/history').then(setHistory).catch(() => {});
    api.get('/plateformes').then(setPlats).catch(() => {});
  }, []);

  // Investissements sont investisseur-scoped → besoin de activeId
  useEffect(() => {
    if (!activeId) return;
    api.get('/investissements').then(setInvestissements).catch(() => {});
  }, [activeId]);

  const def         = MODULES[module];
  const allTargets  = def ? [...def.required, ...def.optional] : [];
  const missingInv  = def?.needsInvestisseur && !activeId;

  const onPreview = async () => {
    if (!file) return;
    setBusy(true); setErr(null); setResult(null);
    try {
      const fd = new FormData();
      fd.append('file', file);
      const r = await api.upload('/imports/preview', fd);
      setPreview(r);
      // Auto-map colonnes dont le nom correspond à une cible
      const auto = {};
      for (const t of allTargets) {
        const col = r.headers.find(h => h.toLowerCase().replace(/\W/g, '_') === t);
        if (col) auto[t] = col;
      }
      setMapping(auto);
    } catch (e) { setErr(e.message); }
    finally { setBusy(false); }
  };

  const apply = async () => {
    setBusy(true); setErr(null);
    try {
      const r = await api.post('/imports/apply', {
        tempId: preview.tempId, module, mapping, defaults,
        originalFilename: file?.name ?? preview.filename,
      });
      setResult({
        ok: true,
        msg: `✔ Import terminé : ${r.inserted} / ${r.total} lignes insérées${r.skipped > 0 ? `, ${r.skipped} ignorées` : ''}.${r.errors?.length > 0 ? ` (${r.errors.length} avertissement(s))` : ''}`,
      });
      setPreview(null); setFile(null); setMapping({}); setDefaults({});
      api.get('/imports/history').then(setHistory).catch(() => {});
      // Recharger les plateformes si c'est ce qui vient d'être importé
      if (module === 'plateformes') {
        api.get('/plateformes').then(setPlats).catch(() => {});
      }
    } catch (e) { setErr(e.message); }
    finally { setBusy(false); }
  };

  return (
    <>
      <div className="topbar"><h2>Import Données</h2></div>

      <div className="card">
        <h3 style={{ marginTop: 0 }}>1. Fichier source</h3>
        <div className="row">
          <div>
            <label>Module cible</label>
            <select value={module} onChange={e => {
              setModule(e.target.value);
              setPreview(null); setMapping({}); setResult(null); setErr(null);
            }}>
              {Object.entries(MODULES).map(([k, v]) => (
                <option key={k} value={k}>{v.label}</option>
              ))}
            </select>
          </div>
          <div style={{ flex: 2 }}>
            <label>Fichier .xlsx, .csv ou .json</label>
            <input type="file" accept=".xlsx,.xls,.csv,.json" onChange={e => {
              setFile(e.target.files[0]);
              setPreview(null); setResult(null); setErr(null);
            }} />
          </div>
          <div>
            <button className="primary" onClick={onPreview}
              disabled={!file || busy || missingInv}>
              {busy ? '…' : 'Analyser'}
            </button>
          </div>
        </div>

        {/* Note contextuelle du module sélectionné */}
        {def?.note && (
          <div className="import-module-note">
            {def.global && (
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none"
                stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
                style={{ flexShrink: 0, marginTop: 1, color: 'var(--warning)' }}>
                <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/>
                <line x1="12" y1="16" x2="12.01" y2="16"/>
              </svg>
            )}
            {def.note}
          </div>
        )}

        {/* Avertissement si module investisseur-scoped mais aucun investisseur actif */}
        {missingInv && (
          <div className="error" style={{ marginTop: 10 }}>
            Sélectionnez un investisseur actif avant d'importer ce module.
          </div>
        )}

        {err    && <div className="error"      style={{ marginTop: 12 }}>{err}</div>}
        <ResultBanner result={result} onDismiss={() => setResult(null)} style={{ marginTop: 12 }} />
      </div>

      {preview && (
        <>
          <div className="card">
            <h3 style={{ marginTop: 0 }}>2. Mappage des colonnes</h3>
            <p className="text-muted" style={{ fontSize: 12 }}>
              Fichier : <strong>{preview.filename}</strong> — feuille <em>{preview.sheetName}</em> — {preview.allRowCount} lignes.
              {' '}Champs marqués <span style={{ color: 'var(--danger)' }}>*</span> obligatoires.
              {' '}Si la colonne n'existe pas, fournissez une valeur par défaut.
            </p>
            <table>
              <thead>
                <tr>
                  <th>Champ cible</th>
                  <th>Colonne Excel</th>
                  <th>Valeur par défaut</th>
                </tr>
              </thead>
              <tbody>
                {allTargets.map(t => {
                  const isReq = def.required.includes(t);
                  return (
                    <tr key={t}>
                      <td>
                        <code style={{ fontSize: 11 }}>{t}</code>
                        {isReq && <span style={{ color: 'var(--danger)' }}> *</span>}
                      </td>
                      <td>
                        <select value={mapping[t] || ''}
                          onChange={e => setMapping({ ...mapping, [t]: e.target.value })}>
                          <option value="">— ignorer —</option>
                          {preview.headers.map(h => <option key={h} value={h}>{h}</option>)}
                        </select>
                      </td>
                      <td>
                        {t === 'plateforme_id' ? (
                          <select value={defaults[t] || ''}
                            onChange={e => setDefaults({ ...defaults, [t]: e.target.value })}>
                            <option value="">—</option>
                            {plats.map(p => <option key={p.id} value={p.id}>{p.nom}{multiDetenteur && p.investisseur_nom ? ` — ${p.investisseur_nom}` : ''}</option>)}
                          </select>
                        ) : t === 'investissement_id' ? (
                          <select value={defaults[t] || ''}
                            onChange={e => setDefaults({ ...defaults, [t]: e.target.value })}>
                            <option value="">—</option>
                            {investissements.map(i => <option key={i.id} value={i.id}>{i.nom_projet}</option>)}
                          </select>
                        ) : (
                          <input value={defaults[t] || ''}
                            onChange={e => setDefaults({ ...defaults, [t]: e.target.value })}
                            placeholder={t === 'statut' ? 'ex. en_cours' : t === 'type' ? 'ex. depot' : ''} />
                        )}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
            <div style={{ marginTop: 12, display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
              <button onClick={() => { setPreview(null); setMapping({}); }}>Annuler</button>
              <button className="primary" onClick={apply} disabled={busy || missingInv}>
                {busy ? '…' : `Importer ${preview.allRowCount} lignes`}
              </button>
            </div>
          </div>

          <div className="card">
            <h3 style={{ marginTop: 0 }}>Aperçu (10 premières lignes)</h3>
            <div style={{ overflowX: 'auto' }}>
              <table>
                <thead>
                  <tr>{preview.headers.map(h => <th key={h}>{h}</th>)}</tr>
                </thead>
                <tbody>
                  {preview.sampleRows.map((r, i) => (
                    <tr key={i}>{preview.headers.map(h => <td key={h}>{String(r[h] ?? '')}</td>)}</tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        </>
      )}

      {/* ── Import Dossier Investissement ──────────────────────── */}
      <DossierImport
        activeId={activeId}
        navigate={navigate}
        dossierFile={dossierFile}
        setDossierFile={setDossierFile}
        dossierPreview={dossierPreview}
        setDossierPreview={setDossierPreview}
        dossierResult={dossierResult}
        setDossierResult={setDossierResult}
        dossierBusy={dossierBusy}
        setDossierBusy={setDossierBusy}
        dossierErr={dossierErr}
        setDossierErr={setDossierErr}
        dossierInputRef={dossierInputRef}
        reloadHistory={() => api.get('/imports/history').then(setHistory).catch(() => {})}
      />

      <div className="card">
        <h3 style={{ marginTop: 0 }}>Historique des imports</h3>
        <table>
          <thead>
            <tr>
              <th>Date</th>
              <th>Module</th>
              <th>Fichier</th>
              <th className="num">Total</th>
              <th className="num">OK</th>
              <th className="num">KO</th>
            </tr>
          </thead>
          <tbody>
            {history.length === 0 && (
              <tr><td colSpan={6} className="text-muted" style={{ textAlign: 'center' }}>Aucun import</td></tr>
            )}
            {history.map(h => (
              <tr key={h.id}>
                <td>{fmtDate(h.created_at)}</td>
                <td>{MODULE_LABEL[h.module] ?? h.module}</td>
                <td className="text-muted" style={{ fontSize: 11 }}>{h.filename}</td>
                <td className="num">{h.rows_total}</td>
                <td className="num" style={{ color: 'var(--success)' }}>{h.rows_inserted}</td>
                <td className="num" style={{ color: h.rows_skipped > 0 ? 'var(--warning)' : undefined }}>
                  {h.rows_skipped}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </>
  );
}

/* ── Composant import dossier ──────────────────────────────────── */
function DossierImport({
  activeId, navigate,
  dossierFile, setDossierFile,
  dossierPreview, setDossierPreview,
  dossierResult, setDossierResult,
  dossierBusy, setDossierBusy,
  dossierErr, setDossierErr,
  dossierInputRef, reloadHistory,
}) {
  const missingInv = !activeId;

  const onFileChange = (e) => {
    const f = e.target.files[0];
    setDossierFile(f || null);
    setDossierPreview(null);
    setDossierResult(null);
    setDossierErr(null);
    if (!f) return;
    const reader = new FileReader();
    reader.onload = (ev) => {
      try {
        const parsed = JSON.parse(ev.target.result);
        if (parsed.type !== 'dossier_investissement') {
          setDossierErr('Ce fichier n\'est pas un dossier investissement valide (type incorrect).');
          return;
        }
        setDossierPreview(parsed);
      } catch {
        setDossierErr('Fichier JSON invalide — vérifiez la syntaxe.');
      }
    };
    reader.readAsText(f);
  };

  const onImport = async () => {
    if (!dossierPreview) return;
    setDossierBusy(true); setDossierErr(null); setDossierResult(null);
    try {
      const r = await api.post('/imports/dossier', { dossier: dossierPreview });
      setDossierResult(r);
      setDossierFile(null); setDossierPreview(null);
      if (dossierInputRef.current) dossierInputRef.current.value = '';
      reloadHistory();
    } catch (e) { setDossierErr(e.message); }
    finally { setDossierBusy(false); }
  };

  const dp = dossierPreview;
  const inv = dp?.investissement;
  const multiDetenteur = new Set(plats.map(p => p.investisseur_id)).size > 1;

  return (
    <div className="card">
      <h3 style={{ marginTop: 0 }}>Import — Dossier investissement</h3>
      <p className="text-muted" style={{ fontSize: 'var(--fs-sm)', marginBottom: 12 }}>
        Restaure ou migre un dossier complet (investissement + remboursements + historique) depuis un fichier
        <code style={{ margin: '0 4px' }}>.json</code> exporté par cette application.
        Si le dossier existe déjà, il sera mis à jour ; sinon il sera créé.
      </p>

      {missingInv && (
        <div className="error" style={{ marginBottom: 10 }}>
          Sélectionnez un investisseur actif avant d'importer un dossier.
        </div>
      )}

      <div className="row" style={{ gap: 10, alignItems: 'flex-end' }}>
        <div style={{ flex: 1 }}>
          <label>Fichier dossier <code>.json</code></label>
          <input
            ref={dossierInputRef}
            type="file" accept=".json"
            disabled={missingInv}
            onChange={onFileChange}
          />
        </div>
      </div>

      {dossierErr && <div className="error" style={{ marginTop: 10 }}>{dossierErr}</div>}

      {/* Aperçu du dossier avant import */}
      {dp && inv && (
        <div style={{ marginTop: 16, borderTop: '1px solid var(--border)', paddingTop: 14 }}>
          <h4 style={{ margin: '0 0 10px', fontSize: 'var(--fs-sm)' }}>Aperçu du dossier</h4>
          <table style={{ marginBottom: 0 }}>
            <tbody>
              <tr><td style={{ width: 200 }}>Projet</td><td><strong>{inv.nom_projet}</strong></td></tr>
              <tr><td>Plateforme</td><td>{dp.plateforme?.nom}</td></tr>
              <tr><td>Date souscription</td><td>{fmtDate(inv.date_souscription)}</td></tr>
              <tr><td>Montant investi</td><td>{inv.montant_investi} €</td></tr>
              <tr><td>Statut</td><td>{inv.statut}</td></tr>
              <tr><td>Remboursements</td><td>{dp.remboursements?.length ?? 0} enregistrement(s)</td></tr>
              <tr><td>Projections</td><td>{dp.projections?.length ?? 0} échéance(s)</td></tr>
              <tr><td>Historique</td><td>{dp.historique?.length ?? 0} entrée(s)</td></tr>
              <tr><td>Exporté le</td><td className="text-muted" style={{ fontSize: 11 }}>{dp.exported_at}</td></tr>
            </tbody>
          </table>
          <div style={{ marginTop: 12, display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
            <button onClick={() => { setDossierFile(null); setDossierPreview(null); if (dossierInputRef.current) dossierInputRef.current.value = ''; }}>
              Annuler
            </button>
            <button className="primary" onClick={onImport} disabled={dossierBusy || missingInv}>
              {dossierBusy ? '…' : 'Importer ce dossier'}
            </button>
          </div>
        </div>
      )}

      {dossierResult && (
        <div className="success-msg" style={{ marginTop: 12 }}>
          {dossierResult.action === 'created'
            ? '✔ Dossier créé avec succès.'
            : '✔ Dossier mis à jour avec succès.'
          }
          {' '}
          <button
            style={{ marginLeft: 8, fontSize: 'var(--fs-xs)', padding: '2px 8px' }}
            onClick={() => navigate(`/investissements/${dossierResult.investissementId}`)}
          >
            Ouvrir le dossier →
          </button>
        </div>
      )}
    </div>
  );
}
