// DsiCapex.tsx — DSI CAPEX : Tableau consolidé des budgets prévisionnels 2027
// Design: Corporate Modernism — Itinova Budget SI 2027
// Reprend les saisies de la page "Construction Budget 2027" sous forme de tableau
// au format du fichier BP2027-Prévisionnel2027CAPEXDSIétablissements.xlsx

import { useState, useMemo, useEffect } from 'react';
import {
  Search,
  ArrowUpDown,
  CheckCircle,
  Clock,
  Euro,
  Building2,
  FileSpreadsheet,
  RefreshCw,
  ChevronUp,
  ChevronDown,
  Info,
} from 'lucide-react';
import { AppSidebar } from '../components/AppSidebar';
import { AnneeSelectorBar } from '../components/AnneeSelectorBar';
import { useAnnee, getCapexStorageKey } from '../contexts/AnneeContext';
import bp2027Raw from '../data_bp2027.json';
import { useParametres } from '../contexts/ParametresContext';
import { formatEuros } from '../lib/format';
import type { BP2027Data, BudgetFormValues } from '../types/bp2027';
import type { BudgetData } from '../types/budget';

const bp2027Data = bp2027Raw as BP2027Data;

function loadInventaireData(annee: number): BudgetData | null {
  try {
    const raw = localStorage.getItem(`budgetsi_inventaire_data_${annee}`);
    return raw ? JSON.parse(raw) as BudgetData : null;
  } catch { return null; }
}
// Clé de stockage dynamique par année (voir getCapexStorageKey)

// Colonnes du tableau (correspondance exacte avec le fichier Excel BP2027)
const COLONNES = [
  { key: 'renouvellement_2027',       shortLabel: 'Renouvellement\nParc Info',  color: 'blue' },
  { key: 'machines_supplementaires',  shortLabel: 'Machines\nSuppl.',           color: 'indigo' },
  { key: 'appel_malade',              shortLabel: 'Appel\nMalade',              color: 'red' },
  { key: 'telephonie',                shortLabel: 'Téléphonie',                 color: 'green' },
  { key: 'wifi',                      shortLabel: 'WiFi',                       color: 'cyan' },
  { key: 'video_surveillance',        shortLabel: 'Vidéo\nSurveill.',           color: 'orange' },
  { key: 'copieurs',                  shortLabel: 'Copieurs',                   color: 'purple' },
  { key: 'visio',                     shortLabel: 'Visio',                      color: 'teal' },
  { key: 'autres',                    shortLabel: 'Autres\nInvest. SI',         color: 'slate' },
] as const;

type ColKey = typeof COLONNES[number]['key'];

const COL_COLORS: Record<string, { header: string; cell: string; total: string }> = {
  blue:   { header: 'bg-blue-600 text-white',     cell: 'text-blue-700',    total: 'bg-blue-50 text-blue-800 font-semibold' },
  indigo: { header: 'bg-indigo-600 text-white',   cell: 'text-indigo-700',  total: 'bg-indigo-50 text-indigo-800 font-semibold' },
  red:    { header: 'bg-red-500 text-white',       cell: 'text-red-700',     total: 'bg-red-50 text-red-800 font-semibold' },
  green:  { header: 'bg-emerald-600 text-white',   cell: 'text-emerald-700', total: 'bg-emerald-50 text-emerald-800 font-semibold' },
  cyan:   { header: 'bg-cyan-600 text-white',      cell: 'text-cyan-700',    total: 'bg-cyan-50 text-cyan-800 font-semibold' },
  orange: { header: 'bg-orange-500 text-white',    cell: 'text-orange-700',  total: 'bg-orange-50 text-orange-800 font-semibold' },
  purple: { header: 'bg-purple-600 text-white',    cell: 'text-purple-700',  total: 'bg-purple-50 text-purple-800 font-semibold' },
  teal:   { header: 'bg-teal-600 text-white',      cell: 'text-teal-700',    total: 'bg-teal-50 text-teal-800 font-semibold' },
  slate:  { header: 'bg-slate-500 text-white',     cell: 'text-slate-700',   total: 'bg-slate-50 text-slate-800 font-semibold' },
};

function loadSaisiesForAnnee(annee: number): Record<string, Partial<BudgetFormValues>> {
  try {
    const raw = localStorage.getItem(getCapexStorageKey(annee));
    return raw ? JSON.parse(raw) : {};
  } catch { return {}; }
}

function getBudgetRenouvellement2027(
  code: string,
  parametres: { coutFixe: number; coutPortable: number; seuilFixesAns: number; seuilPortablesAns: number },
  inventaire: BudgetData | null
): number {
  if (!inventaire) return 0;
  const etab = inventaire.etablissements.find(e => e.code === code);
  if (!etab) return 0;
  const nbFixesR = (etab.fixes ?? []).filter(f => f.age_ans !== null && f.age_ans >= parametres.seuilFixesAns).length;
  const nbPortablesR = (etab.portables ?? []).filter(p => p.age_ans !== null && p.age_ans >= parametres.seuilPortablesAns).length;
  return nbFixesR * parametres.coutFixe + nbPortablesR * parametres.coutPortable;
}

function fmtCell(v: number): string {
  if (!v || v === 0) return '—';
  return new Intl.NumberFormat('fr-FR', { minimumFractionDigits: 0, maximumFractionDigits: 0 }).format(v) + ' €';
}

type SortDir = 'asc' | 'desc';

export default function DsiCapex() {
  const { parametres } = useParametres();
  const { annee } = useAnnee();
  const [saisies, setSaisies] = useState<Record<string, Partial<BudgetFormValues>>>({});
  const [search, setSearch] = useState('');
  const [sortCol, setSortCol] = useState<string>('nom');
  const [sortDir, setSortDir] = useState<SortDir>('asc');
  const [showOnlyFilled, setShowOnlyFilled] = useState(false);
  const [lastRefresh, setLastRefresh] = useState(Date.now());
  const [inventaire, setInventaire] = useState<BudgetData | null>(() => loadInventaireData(annee));

  useEffect(() => {
    setSaisies(loadSaisiesForAnnee(annee));
  }, [lastRefresh, annee]);

  // Recharger l'inventaire quand l'année change
  useEffect(() => {
    setInventaire(loadInventaireData(annee));
  }, [annee]);

  useEffect(() => {
    const onImport = (e: Event) => {
      const detail = (e as CustomEvent).detail;
      if (!detail || detail.annee === annee) setInventaire(loadInventaireData(annee));
    };
    const onStorage = (e: StorageEvent) => {
      if (e.key === `budgetsi_inventaire_data_${annee}`) setInventaire(loadInventaireData(annee));
    };
    window.addEventListener('budgetsi_inventaire_updated', onImport);
    window.addEventListener('storage', onStorage);
    return () => {
      window.removeEventListener('budgetsi_inventaire_updated', onImport);
      window.removeEventListener('storage', onStorage);
    };
  }, [annee]);

  const handleRefresh = () => setLastRefresh(Date.now());

  // Construire les lignes du tableau
  const lignes = useMemo(() => {
    return bp2027Data.etablissements.map(etab => {
      const saisie = saisies[etab.code] || {};
      const renouv = saisie.renouvellement_2027 !== undefined
        ? saisie.renouvellement_2027
        : getBudgetRenouvellement2027(etab.code, parametres, inventaire);

      const valeurs: Record<ColKey, number> = {
        renouvellement_2027:      renouv,
        machines_supplementaires: saisie.machines_supplementaires ?? 0,
        appel_malade:             saisie.appel_malade ?? 0,
        telephonie:               saisie.telephonie ?? 0,
        wifi:                     saisie.wifi ?? 0,
        video_surveillance:       saisie.video_surveillance ?? 0,
        copieurs:                 saisie.copieurs ?? 0,
        visio:                    saisie.visio ?? 0,
        autres:                   saisie.autres ?? 0,
      };

      const total = Object.values(valeurs).reduce((s, v) => s + (v || 0), 0);
      const hasSaisie = Object.keys(saisies).includes(etab.code);

      return {
        code: etab.code,
        nom: etab.nom,
        valeurs,
        total,
        hasSaisie,
        commentaires: saisie.commentaires || '',
      };
    });
  }, [saisies, parametres]);

  const filteredLignes = useMemo(() => {
    return lignes.filter(l => {
      if (showOnlyFilled && !l.hasSaisie) return false;
      if (search && !l.nom.toLowerCase().includes(search.toLowerCase()) &&
          !l.code.toLowerCase().includes(search.toLowerCase())) return false;
      return true;
    });
  }, [lignes, search, showOnlyFilled]);

  const sortedLignes = useMemo(() => {
    const arr = [...filteredLignes];
    arr.sort((a, b) => {
      let va: number | string, vb: number | string;
      if (sortCol === 'nom') { va = a.nom; vb = b.nom; }
      else if (sortCol === 'code') { va = a.code; vb = b.code; }
      else if (sortCol === 'total') { va = a.total; vb = b.total; }
      else {
        va = a.valeurs[sortCol as ColKey] ?? 0;
        vb = b.valeurs[sortCol as ColKey] ?? 0;
      }
      if (typeof va === 'string') {
        return sortDir === 'asc' ? va.localeCompare(vb as string) : (vb as string).localeCompare(va);
      }
      return sortDir === 'asc' ? (va as number) - (vb as number) : (vb as number) - (va as number);
    });
    return arr;
  }, [filteredLignes, sortCol, sortDir]);

  const totauxColonnes = useMemo(() => {
    const t: Record<ColKey, number> = {} as Record<ColKey, number>;
    for (const col of COLONNES) {
      t[col.key] = sortedLignes.reduce((s, l) => s + (l.valeurs[col.key] || 0), 0);
    }
    return t;
  }, [sortedLignes]);

  const totalGeneral = useMemo(() => sortedLignes.reduce((s, l) => s + l.total, 0), [sortedLignes]);
  const nbFilled = useMemo(() => lignes.filter(l => l.hasSaisie).length, [lignes]);

  // La synthèse affiche les données si un inventaire a été importé ou si des saisies CAPEX existent
  const hasDonnees = inventaire !== null || nbFilled > 0;

  const handleSort = (col: string) => {
    if (sortCol === col) setSortDir(d => d === 'asc' ? 'desc' : 'asc');
    else { setSortCol(col); setSortDir('asc'); }
  };

  const SortIcon = ({ col }: { col: string }) => {
    if (sortCol !== col) return <ArrowUpDown className="w-3 h-3 opacity-40" />;
    return sortDir === 'asc'
      ? <ChevronUp className="w-3 h-3" />
      : <ChevronDown className="w-3 h-3" />;
  };

  return (
    <div className="min-h-screen flex bg-background">
      <AppSidebar />

      <main className="flex-1 flex flex-col min-w-0 overflow-hidden">
        {/* En-tête */}
        <header className="bg-card border-b border-border px-6 py-4 flex-shrink-0">
          <div className="flex items-center justify-between gap-4 flex-wrap">
            <div>
              <h1 className="text-xl font-bold text-foreground" style={{ fontFamily: 'Sora, sans-serif' }}>
                CAPEX - Synthèse {annee}
              </h1>
              <p className="text-sm text-muted-foreground mt-0.5">
                Tableau consolidé des investissements SI par établissement
              </p>
            </div>
            <div className="flex items-center gap-3">
              <AnneeSelectorBar />
              <button
                onClick={handleRefresh}
                className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg border border-border text-sm text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors"
              >
                <RefreshCw className="w-4 h-4" />
                Actualiser
              </button>
            </div>
          </div>
        </header>

        {/* KPIs — uniquement si données saisies pour cette année */}
        {hasDonnees && (
        <div className="px-6 py-4 border-b border-border bg-muted/20 flex-shrink-0">
          <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
            <div className="bg-card border border-border rounded-xl p-4">
              <div className="flex items-center gap-2 mb-1">
                <Euro className="w-4 h-4 text-orange-500" />
                <span className="text-xs text-muted-foreground uppercase tracking-wide font-medium">Total CAPEX {annee}</span>
              </div>
              <p className="text-2xl font-bold text-orange-600 tabular-nums" style={{ fontFamily: 'Sora, sans-serif' }}>
                {formatEuros(totalGeneral)}
              </p>
              <p className="text-xs text-muted-foreground mt-0.5">Tous établissements affichés</p>
            </div>
            <div className="bg-card border border-border rounded-xl p-4">
              <div className="flex items-center gap-2 mb-1">
                <Building2 className="w-4 h-4 text-blue-500" />
                <span className="text-xs text-muted-foreground uppercase tracking-wide font-medium">Établissements</span>
              </div>
              <p className="text-2xl font-bold text-blue-600 tabular-nums" style={{ fontFamily: 'Sora, sans-serif' }}>
                {bp2027Data.etablissements.length}
              </p>
              <p className="text-xs text-muted-foreground mt-0.5">dans le périmètre</p>
            </div>
            <div className="bg-card border border-border rounded-xl p-4">
              <div className="flex items-center gap-2 mb-1">
                <CheckCircle className="w-4 h-4 text-emerald-500" />
                <span className="text-xs text-muted-foreground uppercase tracking-wide font-medium">Budgets saisis</span>
              </div>
              <p className="text-2xl font-bold text-emerald-600 tabular-nums" style={{ fontFamily: 'Sora, sans-serif' }}>
                {nbFilled}
              </p>
              <p className="text-xs text-muted-foreground mt-0.5">
                sur {bp2027Data.etablissements.length} ({Math.round(nbFilled / bp2027Data.etablissements.length * 100)}%)
              </p>
            </div>
            <div className="bg-card border border-border rounded-xl p-4">
              <div className="flex items-center gap-2 mb-1">
                <Clock className="w-4 h-4 text-amber-500" />
                <span className="text-xs text-muted-foreground uppercase tracking-wide font-medium">En attente</span>
              </div>
              <p className="text-2xl font-bold text-amber-600 tabular-nums" style={{ fontFamily: 'Sora, sans-serif' }}>
                {bp2027Data.etablissements.length - nbFilled}
              </p>
              <p className="text-xs text-muted-foreground mt-0.5">budgets non encore saisis</p>
            </div>
          </div>
        </div>
        )}

        {/* Barre d'outils — uniquement si données saisies */}
        {hasDonnees && (
        <div className="px-6 py-3 border-b border-border bg-background flex-shrink-0 flex flex-wrap items-center gap-3">
          <div className="relative flex-1 min-w-48 max-w-72">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
            <input
              type="text"
              placeholder="Rechercher un établissement..."
              value={search}
              onChange={e => setSearch(e.target.value)}
              className="w-full pl-9 pr-3 py-2 text-sm border border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/30"
            />
          </div>
          <label className="flex items-center gap-2 text-sm text-muted-foreground cursor-pointer select-none">
            <input
              type="checkbox"
              checked={showOnlyFilled}
              onChange={e => setShowOnlyFilled(e.target.checked)}
              className="rounded border-border"
            />
            Afficher uniquement les budgets saisis
          </label>
          <div className="ml-auto flex items-center gap-1.5 text-xs text-muted-foreground">
            <Info className="w-3.5 h-3.5" />
            <span>{sortedLignes.length} établissement{sortedLignes.length > 1 ? 's' : ''} affichés</span>
          </div>
        </div>
        )}

        {/* Tableau principal — scroll horizontal ou état vide */}
        <div className="flex-1 overflow-auto px-6 py-4">
          {!hasDonnees ? (
            <div className="flex flex-col items-center justify-center py-20 text-center">
              <div className="w-16 h-16 rounded-2xl bg-muted/40 flex items-center justify-center mb-4">
                <FileSpreadsheet className="w-8 h-8 text-muted-foreground/40" />
              </div>
              <p className="text-lg font-semibold text-foreground" style={{ fontFamily: 'Sora, sans-serif' }}>
                Aucun inventaire importé
              </p>
              <p className="text-sm text-muted-foreground mt-2 max-w-sm">
                Importez l'export ISI-APP via le bouton <strong>Imports &amp; Données</strong> pour pré-remplir les budgets de renouvellement, puis saisissez les autres postes CAPEX via la page <strong>CAPEX - Construction</strong>.
              </p>
            </div>
          ) : (
          <div className="min-w-max">
            <table className="w-full text-xs border-collapse shadow-sm">
              <thead>
                {/* Ligne 1 : Titre général + en-têtes colorés */}
                <tr>
                  <td
                    colSpan={2}
                    className="bg-slate-800 text-white text-center font-bold py-2 px-4 border border-slate-600 align-middle"
                    style={{ fontFamily: 'Sora, sans-serif', fontSize: '13px', minWidth: '280px' }}
                  >
                    Campagne budgétaire — <span className="text-orange-300">CAPEX {annee}</span>
                  </td>
                  {COLONNES.map(col => (
                    <td
                      key={col.key}
                      className={`text-center font-bold py-2 px-2 border border-slate-600 leading-tight ${COL_COLORS[col.color].header}`}
                      style={{ minWidth: '90px' }}
                    >
                      {col.shortLabel.split('\n').map((line, i) => (
                        <span key={i} className="block">{line}</span>
                      ))}
                    </td>
                  ))}
                  <td className="bg-slate-800 text-white text-center font-bold py-2 px-3 border border-slate-600 leading-tight" style={{ minWidth: '100px' }}>
                    Total <span className="text-orange-300">BP {annee}</span>
                  </td>
                  <td className="bg-slate-600 text-slate-200 text-center font-bold py-2 px-3 border border-slate-500 leading-tight" style={{ minWidth: '120px' }}>
                    Commentaires
                  </td>
                </tr>
                {/* Ligne 3 : En-têtes de tri */}
                <tr className="bg-muted/50">
                  <th className="text-left px-3 py-2 font-medium text-muted-foreground border border-border/50 w-24">
                    <button onClick={() => handleSort('code')} className="flex items-center gap-1 hover:text-foreground transition-colors">
                      Code <SortIcon col="code" />
                    </button>
                  </th>
                  <th className="text-left px-3 py-2 font-medium text-muted-foreground border border-border/50" style={{ minWidth: '200px' }}>
                    <button onClick={() => handleSort('nom')} className="flex items-center gap-1 hover:text-foreground transition-colors">
                      Établissement <SortIcon col="nom" />
                    </button>
                  </th>
                  {COLONNES.map(col => (
                    <th key={col.key} className="text-right px-2 py-2 font-medium text-muted-foreground border border-border/50">
                      <button onClick={() => handleSort(col.key)} className="flex items-center gap-1 justify-end w-full hover:text-foreground transition-colors">
                        <SortIcon col={col.key} />
                      </button>
                    </th>
                  ))}
                  <th className="text-right px-3 py-2 font-medium text-muted-foreground border border-border/50">
                    <button onClick={() => handleSort('total')} className="flex items-center gap-1 justify-end w-full hover:text-foreground transition-colors">
                      Total <SortIcon col="total" />
                    </button>
                  </th>
                  <th className="text-left px-3 py-2 font-medium text-muted-foreground border border-border/50">
                    Commentaires
                  </th>
                </tr>
              </thead>

              <tbody>
                {sortedLignes.map((ligne, idx) => (
                  <tr
                    key={ligne.code}
                    className={`border-b border-border/40 hover:bg-primary/5 transition-colors ${
                      idx % 2 === 0 ? 'bg-background' : 'bg-muted/10'
                    }`}
                  >
                    {/* Code */}
                    <td className="px-3 py-2 border border-border/30">
                      <div className="flex items-center gap-1.5">
                        {ligne.hasSaisie
                          ? <CheckCircle className="w-3 h-3 text-emerald-500 flex-shrink-0" />
                          : <Clock className="w-3 h-3 text-amber-400 flex-shrink-0" />
                        }
                        <span className="font-mono text-muted-foreground">{ligne.code}</span>
                      </div>
                    </td>
                    {/* Nom */}
                    <td className="px-3 py-2 font-medium text-foreground border border-border/30">
                      <span className="block truncate max-w-48" title={ligne.nom}>{ligne.nom}</span>
                    </td>
                    {/* Colonnes de valeurs */}
                    {COLONNES.map(col => {
                      const val = ligne.valeurs[col.key];
                      return (
                        <td
                          key={col.key}
                          className={`px-2 py-2 text-right tabular-nums border border-border/30 ${
                            val > 0 ? COL_COLORS[col.color].cell : 'text-muted-foreground/30'
                          }`}
                        >
                          {fmtCell(val)}
                        </td>
                      );
                    })}
                    {/* Total */}
                    <td className={`px-3 py-2 text-right font-bold tabular-nums border border-border/30 ${
                      ligne.total > 0 ? 'text-orange-600' : 'text-muted-foreground/30'
                    }`}>
                      {fmtCell(ligne.total)}
                    </td>
                    {/* Commentaires */}
                    <td className="px-3 py-2 text-muted-foreground border border-border/30">
                      <span className="block truncate max-w-28 text-xs" title={ligne.commentaires}>
                        {ligne.commentaires || '—'}
                      </span>
                    </td>
                  </tr>
                ))}
              </tbody>

              {/* Ligne de totaux */}
              <tfoot>
                <tr>
                  <td
                    colSpan={2}
                    className="px-3 py-3 font-bold text-white bg-slate-800 border border-slate-700"
                    style={{ fontFamily: 'Sora, sans-serif', fontSize: '12px' }}
                  >
                    TOTAL — {sortedLignes.length} établissement{sortedLignes.length > 1 ? 's' : ''}
                  </td>
                  {COLONNES.map(col => (
                    <td
                      key={col.key}
                      className={`px-2 py-3 text-right font-bold tabular-nums border border-slate-600 ${COL_COLORS[col.color].total}`}
                    >
                      {totauxColonnes[col.key] > 0
                        ? new Intl.NumberFormat('fr-FR', { minimumFractionDigits: 0, maximumFractionDigits: 0 }).format(totauxColonnes[col.key]) + ' €'
                        : '—'}
                    </td>
                  ))}
                  <td className="px-3 py-3 text-right font-bold text-orange-600 tabular-nums border border-slate-600 bg-orange-50 text-sm">
                    {formatEuros(totalGeneral)}
                  </td>
                  <td className="px-3 py-3 bg-slate-700 border border-slate-600" />
                </tr>
              </tfoot>
            </table>
          </div>
          )}

          {/* Message si aucun résultat (visible uniquement quand hasDonnees=true mais filtre vide) */}
          {hasDonnees && sortedLignes.length === 0 && (
            <div className="flex flex-col items-center justify-center py-16 text-center">
              <FileSpreadsheet className="w-12 h-12 text-muted-foreground/30 mb-3" />
              <p className="text-muted-foreground font-medium">Aucun établissement trouvé</p>
              <p className="text-sm text-muted-foreground/70 mt-1">
                {showOnlyFilled ? 'Aucun budget n\'a encore été saisi.' : 'Modifiez votre recherche.'}
              </p>
            </div>
          )}

          {/* Légende */}
          <div className="mt-6 flex flex-wrap items-center gap-4 text-xs text-muted-foreground border-t border-border pt-4">
            <div className="flex items-center gap-1.5">
              <CheckCircle className="w-3.5 h-3.5 text-emerald-500" />
              <span>Budget saisi via "Construction BP 2027"</span>
            </div>
            <div className="flex items-center gap-1.5">
              <Clock className="w-3.5 h-3.5 text-amber-400" />
              <span>Budget non encore saisi (renouvellement calculé par vétusté)</span>
            </div>
            <div className="ml-auto flex items-center gap-1.5">
              <RefreshCw className="w-3.5 h-3.5" />
              <span>Cliquez sur "Actualiser" pour recharger les dernières saisies</span>
            </div>
          </div>
        </div>
      </main>
    </div>
  );
}
