// Budget2027.tsx — Page de construction du budget CAPEX DSI 2027
// Design: Corporate Modernism — Itinova Budget SI 2027
// Chaque directeur sélectionne son établissement et remplit les champs optionnels.
// Le renouvellement 2027 est pré-rempli depuis les données de vétusté.

import { useState, useMemo, useEffect } from 'react';
import { useLocation } from 'wouter';
import {
  Building2,
  ChevronDown,
  Monitor,
  PlusCircle,
  Bell,
  Phone,
  Wifi,
  Camera,
  Printer,
  Video,
  Package,
  Info,
  CheckCircle,
  FileText,
  RotateCcw,
  TrendingUp,
  AlertCircle,
} 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 budgetRaw from '../data_budget.json';
import { useParametres } from '../contexts/ParametresContext';
import { formatEuros } from '../lib/format';
import type { BP2027Data, EtablissementBP, BudgetFormValues } from '../types/bp2027';
import type { BudgetData } from '../types/budget';

const bp2027Data = bp2027Raw as BP2027Data;
const budgetData = budgetRaw as BudgetData;

// La clé de stockage est désormais dynamique par année (voir getCapexStorageKey)

// Icônes par clé de champ
const ICON_MAP: Record<string, React.ElementType> = {
  renouvellement_2027: Monitor,
  machines_supplementaires: PlusCircle,
  appel_malade: Bell,
  telephonie: Phone,
  wifi: Wifi,
  video_surveillance: Camera,
  copieurs: Printer,
  visio: Video,
  autres: Package,
};

// Couleurs par champ
const COLOR_MAP: Record<string, string> = {
  renouvellement_2027: 'blue',
  machines_supplementaires: 'indigo',
  appel_malade: 'red',
  telephonie: 'green',
  wifi: 'cyan',
  video_surveillance: 'orange',
  copieurs: 'purple',
  visio: 'teal',
  autres: 'slate',
};

const COLOR_CLASSES: Record<string, { bg: string; text: string; border: string; light: string }> = {
  blue:   { bg: 'bg-blue-600',   text: 'text-blue-700',   border: 'border-blue-200',   light: 'bg-blue-50' },
  indigo: { bg: 'bg-indigo-600', text: 'text-indigo-700', border: 'border-indigo-200', light: 'bg-indigo-50' },
  red:    { bg: 'bg-red-500',    text: 'text-red-700',    border: 'border-red-200',    light: 'bg-red-50' },
  green:  { bg: 'bg-emerald-600',text: 'text-emerald-700',border: 'border-emerald-200',light: 'bg-emerald-50' },
  cyan:   { bg: 'bg-cyan-600',   text: 'text-cyan-700',   border: 'border-cyan-200',   light: 'bg-cyan-50' },
  orange: { bg: 'bg-orange-500', text: 'text-orange-700', border: 'border-orange-200', light: 'bg-orange-50' },
  purple: { bg: 'bg-purple-600', text: 'text-purple-700', border: 'border-purple-200', light: 'bg-purple-50' },
  teal:   { bg: 'bg-teal-600',   text: 'text-teal-700',   border: 'border-teal-200',   light: 'bg-teal-50' },
  slate:  { bg: 'bg-slate-500',  text: 'text-slate-700',  border: 'border-slate-200',  light: 'bg-slate-50' },
};

const CHAMPS: { key: keyof BudgetFormValues; label: string; description: string }[] = [
  { key: 'renouvellement_2027', label: 'Renouvellement parc informatique', description: 'Pré-rempli depuis le calcul de vétusté — modifiable' },
  { key: 'machines_supplementaires', label: 'Acquisition machines supplémentaires', description: 'Nouveaux postes hors renouvellement' },
  { key: 'appel_malade', label: 'Système Appel Malade / Anti Fugue', description: 'Équipements d\'appel et de sécurité' },
  { key: 'telephonie', label: 'Installation téléphonique', description: 'Infrastructure téléphonique fixe et mobile' },
  { key: 'wifi', label: 'Réseau WiFi', description: 'Infrastructure réseau sans fil' },
  { key: 'video_surveillance', label: 'Vidéo Surveillance', description: 'Caméras et système de surveillance' },
  { key: 'copieurs', label: 'Copieurs', description: 'Imprimantes et copieurs multifonctions' },
  { key: 'visio', label: 'Équipement Visio Conférence', description: 'Matériel de visioconférence' },
  { key: 'autres', label: 'Autres investissements SI', description: 'Tout autre investissement informatique' },
];

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

function saveSaisiesForAnnee(annee: number, data: Record<string, Partial<BudgetFormValues>>) {
  try { localStorage.setItem(getCapexStorageKey(annee), JSON.stringify(data)); } catch {}
}

function getDefaultValues(etabCode: string, renouvellement2027: number): BudgetFormValues {
  return {
    renouvellement_2027: renouvellement2027,
    machines_supplementaires: 0,
    appel_malade: 0,
    telephonie: 0,
    wifi: 0,
    video_surveillance: 0,
    copieurs: 0,
    visio: 0,
    autres: 0,
    commentaires: '',
  };
}

// Calcule le budget de renouvellement 2027 depuis les données de vétusté
function getBudgetRenouvellement2027(code: string, parametres: { coutFixe: number; coutPortable: number; seuilFixesAns: number; seuilPortablesAns: number }): number {
  const etab = budgetData.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 CurrencyInput({
  value,
  onChange,
  placeholder = '0',
  disabled = false,
}: {
  value: number;
  onChange: (v: number) => void;
  placeholder?: string;
  disabled?: boolean;
}) {
  const [raw, setRaw] = useState(value === 0 ? '' : String(value));

  useEffect(() => {
    setRaw(value === 0 ? '' : String(value));
  }, [value]);

  return (
    <div className="relative">
      <input
        type="number"
        min={0}
        step={100}
        value={raw}
        placeholder={placeholder}
        disabled={disabled}
        onChange={e => {
          setRaw(e.target.value);
          const v = parseFloat(e.target.value);
          onChange(isNaN(v) || v < 0 ? 0 : Math.round(v));
        }}
        onBlur={() => setRaw(value === 0 ? '' : String(value))}
        className={`w-full pl-8 pr-12 py-2.5 text-sm border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary tabular-nums transition-colors ${
          disabled ? 'bg-muted/50 text-muted-foreground cursor-not-allowed' : 'bg-background'
        }`}
      />
      <span className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground text-sm">€</span>
      <span className="absolute right-3 top-1/2 -translate-y-1/2 text-xs text-muted-foreground">TTC</span>
    </div>
  );
}

export default function Budget2027() {
  const [, navigate] = useLocation();
  const { parametres } = useParametres();
  const { annee } = useAnnee();
  const [selectedCode, setSelectedCode] = useState<string>('');
  const [saisies, setSaisies] = useState<Record<string, Partial<BudgetFormValues>>>(() => loadSaisiesForAnnee(annee));
  const [saved, setSaved] = useState(false);
  const [searchEtab, setSearchEtab] = useState('');
  const [dropdownOpen, setDropdownOpen] = useState(false);

  // Établissement sélectionné (depuis BP2027)
  const selectedBP = useMemo(
    () => bp2027Data.etablissements.find(e => e.code === selectedCode) ?? null,
    [selectedCode]
  );

  // Budget renouvellement 2027 calculé par vétusté
  const renouvellement2027Calcule = useMemo(
    () => selectedCode ? getBudgetRenouvellement2027(selectedCode, parametres) : 0,
    [selectedCode, parametres]
  );

  // Valeurs du formulaire pour l'établissement sélectionné
  const formValues = useMemo<BudgetFormValues>(() => {
    const defaults = getDefaultValues(selectedCode, renouvellement2027Calcule);
    const saved = saisies[selectedCode] ?? {};
    return {
      ...defaults,
      ...saved,
      // Si pas encore saisi, on prend le calculé
      renouvellement_2027: saved.renouvellement_2027 !== undefined ? saved.renouvellement_2027 : renouvellement2027Calcule,
    };
  }, [selectedCode, saisies, renouvellement2027Calcule]);

  // Total BP 2027
  const totalBP2027 = useMemo(() => {
    const v = formValues;
    return (
      v.renouvellement_2027 +
      v.machines_supplementaires +
      v.appel_malade +
      v.telephonie +
      v.wifi +
      v.video_surveillance +
      v.copieurs +
      v.visio +
      v.autres
    );
  }, [formValues]);

  // Recharger les saisies quand l'année change
  useEffect(() => {
    setSaisies(loadSaisiesForAnnee(annee));
    setSelectedCode('');
  }, [annee]);

  const updateField = (key: keyof BudgetFormValues, value: number | string) => {
    setSaisies(prev => {
      const next = {
        ...prev,
        [selectedCode]: {
          ...(prev[selectedCode] ?? {}),
          [key]: value,
        },
      };
      saveSaisiesForAnnee(annee, next);
      return next;
    });
    setSaved(false);
  };

  const handleSave = () => {
    saveSaisiesForAnnee(annee, saisies);
    setSaved(true);
    setTimeout(() => setSaved(false), 2500);
  };

  const handleReset = () => {
    setSaisies(prev => {
      const next = { ...prev };
      delete next[selectedCode];
      saveSaisiesForAnnee(annee, next);
      return next;
    });
  };

  // Établissements filtrés pour le dropdown
  const etabsFiltres = useMemo(() => {
    const q = searchEtab.toLowerCase();
    return bp2027Data.etablissements.filter(
      e => e.nom.toLowerCase().includes(q) || e.code.toLowerCase().includes(q)
    );
  }, [searchEtab]);

  // Nb d'établissements avec saisie
  const nbSaisies = Object.keys(saisies).length;

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

      {/* Contenu principal */}
      <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">
            <div>
              <h1 className="text-xl font-bold text-foreground" style={{ fontFamily: 'Sora, sans-serif' }}>
                CAPEX - Construction {annee}
              </h1>
              <p className="text-sm text-muted-foreground mt-0.5">
                Campagne budgétaire CAPEX DSI — Prévisionnel {annee}
              </p>
            </div>
            <div className="flex items-center gap-3">
              <AnneeSelectorBar />
            </div>
            {selectedCode && (
              <div className="flex items-center gap-2">
                <button
                  onClick={handleReset}
                  className="flex items-center gap-2 px-3 py-2 text-sm rounded-lg border border-border bg-card hover:bg-muted transition-colors text-muted-foreground"
                >
                  <RotateCcw className="w-3.5 h-3.5" />
                  Réinitialiser
                </button>
                <button
                  onClick={handleSave}
                  className={`flex items-center gap-2 px-4 py-2 text-sm rounded-lg font-medium transition-all ${
                    saved ? 'bg-emerald-600 text-white' : 'bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm'
                  }`}
                >
                  {saved ? <><CheckCircle className="w-3.5 h-3.5" />Enregistré</> : <><CheckCircle className="w-3.5 h-3.5" />Enregistrer</>}
                </button>
              </div>
            )}
          </div>
        </header>

        <div className="flex-1 overflow-y-auto px-6 py-6 space-y-6">

          {/* Sélection établissement */}
          <section className="bg-card border border-border rounded-xl p-5">
            <div className="flex items-center gap-2 mb-4">
              <Building2 className="w-4 h-4 text-muted-foreground" />
              <h2 className="font-semibold text-foreground" style={{ fontFamily: 'Sora, sans-serif' }}>
                Sélection de l'établissement
              </h2>
            </div>

            <div className="relative">
              <button
                onClick={() => setDropdownOpen(!dropdownOpen)}
                className="w-full flex items-center justify-between px-4 py-3 border border-border rounded-lg bg-background hover:bg-muted/50 transition-colors text-left"
              >
                {selectedBP ? (
                  <div className="flex items-center gap-3">
                    <span className="font-mono text-xs bg-primary/10 text-primary px-2 py-0.5 rounded">{selectedBP.code}</span>
                    <span className="font-medium text-foreground">{selectedBP.nom}</span>
                  </div>
                ) : (
                  <span className="text-muted-foreground">Choisir un établissement...</span>
                )}
                <ChevronDown className={`w-4 h-4 text-muted-foreground transition-transform ${dropdownOpen ? 'rotate-180' : ''}`} />
              </button>

              {dropdownOpen && (
                <div className="absolute z-50 top-full left-0 right-0 mt-1 bg-card border border-border rounded-xl shadow-lg overflow-hidden">
                  <div className="p-2 border-b border-border">
                    <input
                      type="text"
                      placeholder="Rechercher..."
                      value={searchEtab}
                      onChange={e => setSearchEtab(e.target.value)}
                      className="w-full px-3 py-2 text-sm border border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/30"
                      autoFocus
                    />
                  </div>
                  <div className="max-h-64 overflow-y-auto">
                    {etabsFiltres.length === 0 ? (
                      <p className="px-4 py-3 text-sm text-muted-foreground">Aucun résultat</p>
                    ) : (
                      etabsFiltres.map(e => (
                        <button
                          key={e.code}
                          onClick={() => { setSelectedCode(e.code); setDropdownOpen(false); setSearchEtab(''); }}
                          className={`w-full flex items-center gap-3 px-4 py-2.5 text-left hover:bg-muted/50 transition-colors ${
                            selectedCode === e.code ? 'bg-primary/5' : ''
                          }`}
                        >
                          <span className="font-mono text-xs bg-muted text-muted-foreground px-1.5 py-0.5 rounded flex-shrink-0">{e.code}</span>
                          <span className="text-sm text-foreground">{e.nom}</span>
                          {saisies[e.code] && (
                            <CheckCircle className="w-3.5 h-3.5 text-emerald-500 ml-auto flex-shrink-0" />
                          )}
                        </button>
                      ))
                    )}
                  </div>
                </div>
              )}
            </div>
          </section>

          {/* Formulaire (visible uniquement si établissement sélectionné) */}
          {!selectedCode && (
            <div className="flex flex-col items-center justify-center py-16 text-center">
              <div className="w-16 h-16 rounded-2xl bg-muted flex items-center justify-center mb-4">
                <FileText className="w-8 h-8 text-muted-foreground" />
              </div>
              <h3 className="font-semibold text-foreground mb-2" style={{ fontFamily: 'Sora, sans-serif' }}>
                Sélectionnez un établissement
              </h3>
              <p className="text-sm text-muted-foreground max-w-sm">
                Choisissez votre établissement dans la liste ci-dessus pour accéder au formulaire de construction budgétaire.
              </p>
            </div>
          )}

          {selectedCode && selectedBP && (
            <>
              {/* Données informatives 2026 */}
              <section className="bg-amber-50 border border-amber-200 rounded-xl p-5">
                <div className="flex items-start gap-3 mb-4">
                  <Info className="w-4 h-4 text-amber-600 mt-0.5 flex-shrink-0" />
                  <div>
                    <h3 className="font-semibold text-amber-900" style={{ fontFamily: 'Sora, sans-serif' }}>
                      Données historiques — à titre informatif
                    </h3>
                    <p className="text-sm text-amber-700 mt-0.5">
                      Enveloppes de renouvellement allouées par le Siège Itinova (non modifiables)
                    </p>
                  </div>
                </div>
                <div className="bg-white/70 rounded-lg px-4 py-3 border border-amber-200">
                  <p className="text-xs text-amber-600 font-medium uppercase tracking-wide">Renouvellement 2026</p>
                  <p className="text-xl font-bold text-amber-900 mt-1 tabular-nums">
                    {selectedBP.renouvellement_2026 > 0 ? formatEuros(selectedBP.renouvellement_2026) : '—'}
                  </p>
                  <p className="text-xs text-amber-600 mt-0.5">Enveloppe Siège</p>
                </div>
              </section>

              {/* Formulaire de saisie */}
              <section className="space-y-3">
                <div className="flex items-center gap-2 pb-2 border-b border-border">
                  <TrendingUp className="w-4 h-4 text-muted-foreground" />
                  <h2 className="font-semibold text-foreground" style={{ fontFamily: 'Sora, sans-serif' }}>
                    Budget prévisionnel 2027 — Saisie directeur
                  </h2>
                  <span className="text-xs text-muted-foreground ml-1">(tous les champs sont optionnels)</span>
                </div>

                {CHAMPS.map(champ => {
                  const Icon = ICON_MAP[champ.key] ?? Package;
                  const color = COLOR_MAP[champ.key] ?? 'slate';
                  const cls = COLOR_CLASSES[color];
                  const isRenouvellement = champ.key === 'renouvellement_2027';
                  const val = formValues[champ.key];
                  const numVal = typeof val === 'number' ? val : 0;

                  return (
                    <div
                      key={champ.key}
                      className={`bg-card border rounded-xl p-4 transition-colors ${
                        numVal > 0 ? `${cls.border} ${cls.light}` : 'border-border'
                      }`}
                    >
                      <div className="flex items-start gap-3">
                        <div className={`w-9 h-9 rounded-lg flex items-center justify-center flex-shrink-0 ${cls.light} border ${cls.border}`}>
                          <Icon className={`w-4 h-4 ${cls.text}`} />
                        </div>
                        <div className="flex-1 min-w-0">
                          <div className="flex items-center gap-2 mb-1">
                            <p className="font-medium text-sm text-foreground">{champ.label}</p>
                            {isRenouvellement && (
                              <span className="text-[10px] bg-blue-100 text-blue-700 px-1.5 py-0.5 rounded font-medium">
                                Pré-rempli
                              </span>
                            )}
                          </div>
                          <p className="text-xs text-muted-foreground mb-2">{champ.description}</p>
                          {isRenouvellement && renouvellement2027Calcule > 0 && (
                            <div className="flex items-center gap-1.5 mb-2">
                              <AlertCircle className="w-3 h-3 text-blue-500" />
                              <p className="text-xs text-blue-600">
                                Proposé par vétusté : <strong>{formatEuros(renouvellement2027Calcule)}</strong>
                                {formValues.renouvellement_2027 !== renouvellement2027Calcule && (
                                  <span className="ml-1 text-orange-500">(modifié)</span>
                                )}
                              </p>
                            </div>
                          )}
                          <CurrencyInput
                            value={numVal}
                            onChange={v => updateField(champ.key, v)}
                          />
                        </div>
                        {numVal > 0 && (
                          <div className="flex-shrink-0 text-right">
                            <span className={`text-sm font-bold ${cls.text} tabular-nums`}>
                              {formatEuros(numVal)}
                            </span>
                          </div>
                        )}
                      </div>
                    </div>
                  );
                })}

                {/* Commentaires */}
                <div className="bg-card border border-border rounded-xl p-4">
                  <div className="flex items-center gap-2 mb-2">
                    <FileText className="w-4 h-4 text-muted-foreground" />
                    <p className="font-medium text-sm text-foreground">Commentaires</p>
                    <span className="text-xs text-muted-foreground">(optionnel)</span>
                  </div>
                  <textarea
                    rows={3}
                    value={formValues.commentaires}
                    onChange={e => updateField('commentaires', e.target.value as unknown as number)}
                    placeholder="Précisions, justifications, contexte particulier..."
                    className="w-full px-3 py-2 text-sm border border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary resize-none"
                  />
                </div>
              </section>

              {/* Récapitulatif total */}
              <section className="bg-gradient-to-br from-slate-800 to-slate-900 rounded-xl p-6 text-white">
                <div className="flex items-center justify-between mb-5">
                  <div>
                    <h3 className="font-bold text-lg" style={{ fontFamily: 'Sora, sans-serif' }}>
                      Total BP 2027
                    </h3>
                    <p className="text-white/60 text-sm mt-0.5">{selectedBP.nom}</p>
                  </div>
                  <div className="text-right">
                    <p className="text-3xl font-bold tabular-nums text-white">
                      {formatEuros(totalBP2027)}
                    </p>
                    <p className="text-white/50 text-xs mt-0.5">TTC — exercice 2027</p>
                  </div>
                </div>

                {/* Détail des lignes non nulles */}
                <div className="space-y-2 border-t border-white/10 pt-4">
                  {CHAMPS.map(champ => {
                    const val = formValues[champ.key];
                    const numVal = typeof val === 'number' ? val : 0;
                    if (numVal === 0) return null;
                    const color = COLOR_MAP[champ.key] ?? 'slate';
                    const cls = COLOR_CLASSES[color];
                    return (
                      <div key={champ.key} className="flex items-center justify-between text-sm">
                        <span className="text-white/70">{champ.label}</span>
                        <span className="font-medium tabular-nums text-white">{formatEuros(numVal)}</span>
                      </div>
                    );
                  })}
                  {totalBP2027 === 0 && (
                    <p className="text-white/40 text-sm text-center py-2">
                      Aucun montant saisi — remplissez les champs ci-dessus
                    </p>
                  )}
                </div>

                {/* Comparaison avec 2026 */}
                {selectedBP.renouvellement_2026 > 0 && totalBP2027 > 0 && (
                  <div className="mt-4 pt-4 border-t border-white/10 flex items-center justify-between text-sm">
                    <span className="text-white/50">vs Enveloppe 2026</span>
                    <div className="flex items-center gap-2">
                      <span className="text-white/50">{formatEuros(selectedBP.renouvellement_2026)}</span>
                      <span className={`font-medium ${totalBP2027 > selectedBP.renouvellement_2026 ? 'text-red-400' : 'text-emerald-400'}`}>
                        {totalBP2027 > selectedBP.renouvellement_2026 ? '+' : ''}
                        {formatEuros(totalBP2027 - selectedBP.renouvellement_2026)}
                      </span>
                    </div>
                  </div>
                )}
              </section>
            </>
          )}
        </div>
      </main>
    </div>
  );
}
