"use client";

import {
  ArrowLeftRight,
  BarChart3,
  FileSpreadsheet,
  FileText,
  Globe2,
  Moon,
  Printer,
  RefreshCw,
  Search,
  Stethoscope,
  X,
} from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import type { ReactNode } from "react";
import { useRouter } from "next/navigation";

type ReportId =
  | "indicateurs-mensuels"
  | "elements-paie"
  | "avenant-equipe-nuit"
  | "salaries-sans-vm"
  | "registre-entrees-sorties"
  | "appels-offres-etrangers";

type NightRole = "OUVRIER" | "CHEF_EQUIPE";
type NightSelection = { cos: number; role: NightRole };
type EmployeeOption = {
  cos: number;
  title: string;
  lastName: string;
  firstName: string;
};
type IndicatorReport = {
  asOf: string;
  sectors: Array<{ sector: string; rows: Array<{ group: string; count: number }>; total: number }>;
  trades: Array<{ trade: string; count: number }>;
  hires: Array<{ contractType: string; count: number }>;
  exits: Array<{ contractType: string; count: number }>;
  disabledEmployees: Array<{ cos: number | null; name: string }>;
  total: number;
};
type PayrollReportData = {
  asOf: string;
  rows: Array<{
    cos: number | null; lastName: string; firstName: string; hireDate: string | null;
    contractType: string; qualification: string; grossSalary: number | null; monthlyHours: number | null;
    absences: Array<{ from: string | null; to: string | null; reason: string; hours: number | null }>;
  }>;
};
type WithoutMedicalVisitReportData = {
  asOf: string;
  rows: Array<{ cos: number | null; title: string; lastName: string; firstName: string; job: string; contractType: string; hireDate: string | null }>;
};
type RegisterRow = {
  contractId: number; cos: number | null | undefined; name: string; socialSecurityNumber: string;
  nationality: string; birthDate: string | null | undefined; job: string; qualification: string;
  hireDate: string | null; exitDate: string | null; contractType: string; exitReason: string;
  residencePermitType: string; residencePermitNumber: string;
};
type RegisterReportData = { from: string; to: string; entries: RegisterRow[]; exits: RegisterRow[] };
type ForeignTenderReportData = {
  asOf: string;
  employees: Array<{ cos: number | null; lastName: string; firstName: string; hireDate: string | null; nationality: string; residencePermitType: string; residencePermitNumber: string }>;
};
type NightTeamReportData = {
  startDate: string; endDate: string; returnDate: string; signedAt: string;
  company: string; director: string; companyAddress: string;
  documents: Array<{
    cos: number | null; role: NightRole; title: string; lastName: string; firstName: string;
    birthDate: string | null; birthPlace: string; nationality: string; socialSecurityNumber: string;
    address: string; postalCode: string; city: string;
  }>;
};
type ReportData = IndicatorReport | PayrollReportData | WithoutMedicalVisitReportData | RegisterReportData | ForeignTenderReportData | NightTeamReportData;

const REPORTS: Array<{
  id: ReportId;
  title: string;
  description: string;
  icon: typeof FileText;
}> = [
  {
    id: "elements-paie",
    title: "Éléments de paie LESQUIN",
    description: "Données contractuelles et variables du mois.",
    icon: FileSpreadsheet,
  },
  {
    id: "indicateurs-mensuels",
    title: "Indicateurs mensuels LESQUIN",
    description: "Effectifs, métiers, embauches, sorties et handicap.",
    icon: BarChart3,
  },
  {
    id: "avenant-equipe-nuit",
    title: "Avenant Équipe de nuit",
    description: "Avenants Ouvrier ou Chef d’équipe pour plusieurs salariés.",
    icon: Moon,
  },
  {
    id: "salaries-sans-vm",
    title: "Salariés sans VM",
    description: "Salariés actifs sans aucune visite médicale enregistrée.",
    icon: Stethoscope,
  },
  {
    id: "registre-entrees-sorties",
    title: "Registre Entrées/Sorties LESQUIN",
    description: "Mouvements du personnel sur une période choisie.",
    icon: ArrowLeftRight,
  },
  {
    id: "appels-offres-etrangers",
    title: "Documents pour appels d’offres (Étrangers)",
    description: "Attestation des salariés soumis à autorisation de travail.",
    icon: Globe2,
  },
];

function isoToday() {
  const now = new Date();
  const local = new Date(now.getTime() - now.getTimezoneOffset() * 60_000);
  return local.toISOString().slice(0, 10);
}

function firstDayOfMonth(value: string) {
  return `${value.slice(0, 7)}-01`;
}

function lastDayOfMonth(value: string) {
  const [year, month] = value.split("-").map(Number);
  return new Date(Date.UTC(year, month, 0)).toISOString().slice(0, 10);
}

function formatDate(value: string | null | undefined, long = false) {
  if (!value) return "";
  const date = new Date(value.length === 10 ? `${value}T12:00:00Z` : value);
  if (Number.isNaN(date.getTime())) return value;
  return new Intl.DateTimeFormat("fr-FR", {
    timeZone: "Europe/Paris",
    day: "2-digit",
    month: long ? "long" : "2-digit",
    year: "numeric",
  }).format(date);
}

function formatNumber(value: number | null | undefined) {
  if (value == null || Number.isNaN(value)) return "";
  return new Intl.NumberFormat("fr-FR", { maximumFractionDigits: 2 }).format(value);
}

function employeeLabel(employee: EmployeeOption) {
  return [employee.firstName, employee.lastName].filter(Boolean).join(" ") || `COS ${employee.cos}`;
}

function DataTable({
  headers,
  rows,
  compact = false,
}: {
  headers: string[];
  rows: Array<Array<ReactNode>>;
  compact?: boolean;
}) {
  return (
    <table className={`etat-table ${compact ? "etat-table-compact" : ""}`}>
      <thead><tr>{headers.map((header) => <th key={header}>{header}</th>)}</tr></thead>
      <tbody>
        {rows.length > 0 ? rows.map((row, index) => (
          <tr key={index}>{row.map((cell, cellIndex) => <td key={cellIndex}>{cell}</td>)}</tr>
        )) : <tr><td colSpan={headers.length} className="etat-empty">Aucune donnée</td></tr>}
      </tbody>
    </table>
  );
}

function IndicatorsReport({ report }: { report: IndicatorReport }) {
  return (
    <section className="etat-sheet etat-portrait">
      <h2 className="etat-title">INDICATEURS MENSUELS</h2>
      <p className="etat-subtitle">LESQUIN — Situation au {formatDate(report.asOf)}</p>
      <div className="etat-indicator-grid">
        <div className="etat-span-2">
          <h3>Répartition par secteur et contrat</h3>
          <DataTable headers={["Secteur", "Regroupement", "Effectif"]} rows={report.sectors.flatMap((sector) => [
            ...sector.rows.map((row) => [sector.sector, row.group, row.count]),
            ["", <strong key="total">TOTAL {sector.sector}</strong>, <strong key="count">{sector.total}</strong>],
          ])} compact />
          <p className="etat-grand-total">TOTAL GÉNÉRAL : {report.total}</p>
        </div>
        <div>
          <h3>Métiers</h3>
          <DataTable headers={["Métier", "Effectif"]} rows={report.trades.map((row) => [row.trade, row.count])} compact />
        </div>
        <div className="etat-stack">
          <div>
            <h3>Embauches du mois</h3>
            <DataTable headers={["Type de contrat", "Nombre"]} rows={report.hires.map((row) => [row.contractType, row.count])} compact />
          </div>
          <div>
            <h3>Sorties du mois</h3>
            <DataTable headers={["Type de contrat", "Nombre"]} rows={report.exits.map((row) => [row.contractType, row.count])} compact />
          </div>
          <div>
            <h3>Salariés reconnus handicapés</h3>
            <DataTable headers={["Salarié"]} rows={report.disabledEmployees.map((row) => [row.name])} compact />
            <p className="etat-count">Nombre : {report.disabledEmployees.length}</p>
          </div>
        </div>
      </div>
    </section>
  );
}

function PayrollReport({ report }: { report: PayrollReportData }) {
  return (
    <section className="etat-sheet etat-landscape etat-payroll">
      <h2 className="etat-title">ÉLÉMENTS DE PAIE — LESQUIN</h2>
      <p className="etat-subtitle">Mois se terminant le {formatDate(report.asOf)}</p>
      <DataTable
        compact
        headers={[
          "Nom", "Prénom", "Embauche", "Contrat", "Qualification", "Salaire brut", "Mensu.",
          "H. fériées non travaillées", "H. sup. 25 %", "Entrée mois : h. travaillées",
          "Congés du", "Congés au", "Congés h.", "Absence du", "Absence au", "Motif", "Absence h.",
          "Prime qualité", "Prime panier", "Acompte exceptionnel", "Observations",
        ]}
        rows={report.rows.map((row) => {
          const absence = row.absences[0];
          return [
            row.lastName, row.firstName, formatDate(row.hireDate), row.contractType, row.qualification,
            formatNumber(row.grossSalary), formatNumber(row.monthlyHours), "", "", "", "", "", "",
            formatDate(absence?.from), formatDate(absence?.to), absence?.reason ?? "", formatNumber(absence?.hours),
            "", "", "", row.absences.length > 1 ? `${row.absences.length} absences sur le mois` : "",
          ];
        })}
      />
      <p className="etat-footnote">Les éléments variables laissés vides sont à compléter par le service RH avant transmission à la paie.</p>
    </section>
  );
}

function WithoutMedicalVisitReport({ report }: { report: WithoutMedicalVisitReportData }) {
  return (
    <section className="etat-sheet etat-portrait">
      <h2 className="etat-title">Salariés en cours sans visite médicale</h2>
      <DataTable
        headers={["Salarié", "Poste", "Contrat", "Date d’embauche"]}
        rows={report.rows.map((row) => [
          [row.title, row.lastName, row.firstName].filter(Boolean).join(" "),
          row.job,
          row.contractType,
          formatDate(row.hireDate),
        ])}
      />
      <footer className="etat-footer">Édité le {formatDate(report.asOf)}</footer>
    </section>
  );
}

function RegisterRows({ title, rows }: { title: string; rows: RegisterRow[] }) {
  return (
    <div className="etat-register-block">
      <h3>{title}</h3>
      <DataTable
        compact
        headers={["Nom et prénoms", "N° Sécurité sociale", "Nationalité", "Naissance", "Poste", "Qualification", "Embauche", "Sortie", "Contrat", "Motif sortie", "Titre de séjour", "N° carte"]}
        rows={rows.map((row) => [
          row.name, row.socialSecurityNumber, row.nationality, formatDate(row.birthDate), row.job,
          row.qualification, formatDate(row.hireDate), formatDate(row.exitDate), row.contractType,
          row.exitReason, row.residencePermitType, row.residencePermitNumber,
        ])}
      />
    </div>
  );
}

function RegisterReport({ report }: { report: RegisterReportData }) {
  return (
    <section className="etat-sheet etat-landscape">
      <h2 className="etat-title">REGISTRE ENTRÉES / SORTIES — LESQUIN</h2>
      <p className="etat-subtitle">Du {formatDate(report.from)} au {formatDate(report.to)}</p>
      <RegisterRows title={`Entrées (${report.entries.length})`} rows={report.entries} />
      <RegisterRows title={`Sorties (${report.exits.length})`} rows={report.exits} />
    </section>
  );
}

function ForeignTenderReport({ report }: { report: ForeignTenderReportData }) {
  const hasEmployees = report.employees.length > 0;
  return (
    <section className="etat-sheet etat-portrait etat-tender">
      <div className="etat-brand">envie <span>2e</span></div>
      <h2>Liste des salariés soumis à autorisation de travail en France</h2>
      <p><strong>Je soussigné(e),</strong><br />Responsable des services administratifs de la société ENVIE 2E NORD SAS, sise 2 boulevard Thomson – CS 60500 – 59815 LESQUIN CEDEX, atteste sur l’honneur que :</p>
      <p className="etat-checkbox">{hasEmployees ? "☐" : "☒"} Notre entreprise n’a pas de salarié soumis à autorisation de travail.</p>
      <p className="etat-checkbox">{hasEmployees ? "☒" : "☐"} Notre entreprise emploie actuellement au moins un salarié originaire d’un pays hors Espace économique européen ou ressortissant d’un État de l’EEE en période transitoire, soumis à autorisation de travail en France.</p>
      <p>Je m’engage à actualiser immédiatement la présente lors du recrutement de tels salariés et à transmettre les informations et documents demandés par la réglementation en vigueur.</p>
      {hasEmployees && <>
        <h3>Liste établie à partir du registre unique du personnel</h3>
        <DataTable headers={["Nom", "Prénom", "Date d’embauche", "Nationalité", "Type ID", "Numéro ID"]} rows={report.employees.map((row) => [row.lastName, row.firstName, formatDate(row.hireDate), row.nationality, row.residencePermitType, row.residencePermitNumber])} compact />
      </>}
      <footer className="etat-footer">ENVIE 2E — 2 boulevard Thomson, 59815 LESQUIN CEDEX — Édité le {formatDate(report.asOf)}</footer>
    </section>
  );
}

function NightTeamReport({ report }: { report: NightTeamReportData }) {
  return <>{report.documents.map((employee) => {
    const name = [employee.title, employee.firstName, employee.lastName].filter(Boolean).join(" ");
    const address = [employee.address, [employee.postalCode, employee.city].filter(Boolean).join(" ")].filter(Boolean).join(", ");
    return (
      <section className="etat-sheet etat-portrait etat-night" key={employee.cos}>
        <div className="etat-night-address">{name}<br />{address}</div>
        <h2>AVENANT POUR CHANGEMENT D’HORAIRES</h2>
        <p>Entre la {report.company}, dont le siège est situé au {report.companyAddress}, représentée par la Direction du site,</p>
        <p>Et {name}, né(e) le {formatDate(employee.birthDate, true)} à {employee.birthPlace}, de nationalité {employee.nationality}, immatriculé(e) à la Sécurité sociale sous le n° {employee.socialSecurityNumber} et demeurant {address}.</p>
        <p>Il a été convenu ce qui suit :</p>
        <p>{name} effectuera de manière exceptionnelle, du <strong>{formatDate(report.startDate, true)}</strong> au <strong>{formatDate(report.endDate, true)}</strong>, les horaires suivants :</p>
        <div className="etat-night-hours">
          {employee.role === "CHEF_EQUIPE" ? <><strong>Équipe de nuit — Chef d’équipe</strong><br /></> : null}
          22h00 – 03h00<br />03h30 – 05h45
        </div>
        <p>La majoration de ces heures de nuit sera de 50 % et une indemnité de nuit est fixée à 5,12 € par nuit travaillée, conformément à la convention collective.</p>
        <p>Le <strong>{formatDate(report.returnDate, true)}</strong>, vous reprendrez vos horaires habituels, aux conditions fixées par votre contrat.</p>
        <p>Les autres dispositions du contrat initial resteront inchangées.</p>
        <p className="etat-night-signed">Fait à Lesquin, en double original, le {formatDate(report.signedAt, true)}</p>
        <div className="etat-signatures"><span>Le salarié<br />(Signature précédée de la mention « Lu et approuvé »)</span><span>{report.director}</span></div>
      </section>
    );
  })}</>;
}

function ReportPreview({ id, report }: { id: ReportId; report: ReportData }) {
  if (id === "indicateurs-mensuels") return <IndicatorsReport report={report as IndicatorReport} />;
  if (id === "elements-paie") return <PayrollReport report={report as PayrollReportData} />;
  if (id === "salaries-sans-vm") return <WithoutMedicalVisitReport report={report as WithoutMedicalVisitReportData} />;
  if (id === "registre-entrees-sorties") return <RegisterReport report={report as RegisterReportData} />;
  if (id === "appels-offres-etrangers") return <ForeignTenderReport report={report as ForeignTenderReportData} />;
  return <NightTeamReport report={report as NightTeamReportData} />;
}

export default function EtatsPanel() {
  const router = useRouter();
  const today = useMemo(isoToday, []);
  const [selectedReport, setSelectedReport] = useState<ReportId>("elements-paie");
  const [date, setDate] = useState(lastDayOfMonth(today));
  const [from, setFrom] = useState(firstDayOfMonth(today));
  const [to, setTo] = useState(lastDayOfMonth(today));
  const [nightStart, setNightStart] = useState(today);
  const [nightEnd, setNightEnd] = useState(today);
  const [nightReturn, setNightReturn] = useState(today);
  const [nightSignedAt, setNightSignedAt] = useState(today);
  const [employees, setEmployees] = useState<EmployeeOption[]>([]);
  const [employeeSearch, setEmployeeSearch] = useState("");
  const [nightEmployees, setNightEmployees] = useState<NightSelection[]>([]);
  const [report, setReport] = useState<ReportData | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;
    async function loadEmployees() {
      const token = localStorage.getItem("token");
      if (!token) return router.push("/login");
      const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/impressions/etats/avenant-equipe-nuit?${new URLSearchParams({ date: today })}`, {
        headers: { Authorization: `Bearer ${token}` }, cache: "no-store",
      });
      if (response.status === 401) return router.push("/login");
      const data = await response.json().catch(() => null);
      if (!cancelled && response.ok) setEmployees(data?.report?.employees ?? []);
    }
    void loadEmployees();
    return () => { cancelled = true; };
  }, [router, today]);

  const filteredEmployees = useMemo(() => {
    const needle = employeeSearch.trim().toLocaleLowerCase("fr");
    return employees
      .filter((employee) => !needle || `${employee.firstName} ${employee.lastName} ${employee.cos}`.toLocaleLowerCase("fr").includes(needle))
      .sort((left, right) => employeeLabel(left).localeCompare(employeeLabel(right), "fr"));
  }, [employeeSearch, employees]);

  function select(id: ReportId) {
    setSelectedReport(id);
    setReport(null);
    setError(null);
  }

  function addNightEmployee(employee: EmployeeOption) {
    setNightEmployees((current) => current.some((item) => item.cos === employee.cos)
      ? current
      : [...current, { cos: employee.cos, role: "OUVRIER" }]);
  }

  async function generate() {
    const token = localStorage.getItem("token");
    if (!token) return router.push("/login");
    setLoading(true);
    setError(null);
    setReport(null);
    try {
      let url = `${process.env.NEXT_PUBLIC_API_URL}/api/impressions/etats/${selectedReport}`;
      let init: RequestInit = { headers: { Authorization: `Bearer ${token}` }, cache: "no-store" };
      if (selectedReport === "registre-entrees-sorties") {
        url += `?${new URLSearchParams({ from, to })}`;
      } else if (selectedReport === "avenant-equipe-nuit") {
        init = {
          method: "POST",
          headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
          body: JSON.stringify({ startDate: nightStart, endDate: nightEnd, returnDate: nightReturn, signedAt: nightSignedAt, employees: nightEmployees }),
        };
      } else {
        url += `?${new URLSearchParams({ date })}`;
      }
      const response = await fetch(url, init);
      const data = await response.json().catch(() => null);
      if (response.status === 401) return router.push("/login");
      if (!response.ok) throw new Error(data?.message === "INVALID_RANGE" ? "Les dates saisies ne sont pas cohérentes." : data?.message === "EMPLOYEES_REQUIRED" ? "Sélectionnez au moins un salarié." : "Impossible de générer cet état.");
      setReport(data.report as ReportData);
    } catch (caught) {
      setError(caught instanceof Error ? caught.message : "Génération impossible.");
    } finally {
      setLoading(false);
    }
  }

  return (
    <main className="etats-app min-h-screen bg-slate-100 p-4 text-slate-900 md:p-6">
      <div className="mx-auto max-w-[1500px]">
        <div className="grid items-start gap-5 xl:grid-cols-[380px_minmax(0,1fr)]">
          <aside className="space-y-4">
            <section className="rounded-xl bg-white p-4 shadow-sm">
              <h2 className="mb-3 text-lg font-bold">États disponibles</h2>
              <div className="space-y-2">
                {REPORTS.map((item) => {
                  const Icon = item.icon;
                  return <button key={item.id} type="button" onClick={() => select(item.id)} className={`flex w-full items-start gap-3 rounded-lg border p-3 text-left transition ${selectedReport === item.id ? "border-blue-500 bg-blue-50 text-blue-900" : "border-slate-200 hover:bg-slate-50"}`}>
                    <Icon size={20} className="mt-0.5 shrink-0" />
                    <span><strong className="block text-sm">{item.title}</strong><span className="mt-0.5 block text-xs text-slate-500">{item.description}</span></span>
                  </button>;
                })}
              </div>
            </section>

            <section className="rounded-xl bg-white p-4 shadow-sm">
              <h2 className="mb-3 font-bold">Paramètres</h2>
              {selectedReport === "registre-entrees-sorties" ? <div className="grid grid-cols-2 gap-3">
                <DateField label="Du" value={from} onChange={setFrom} />
                <DateField label="Au" value={to} onChange={setTo} />
              </div> : selectedReport === "avenant-equipe-nuit" ? <div className="space-y-3">
                <div className="grid grid-cols-2 gap-3">
                  <DateField label="Début équipe nuit" value={nightStart} onChange={setNightStart} />
                  <DateField label="Fin équipe nuit" value={nightEnd} onChange={setNightEnd} />
                  <DateField label="Reprise du travail" value={nightReturn} onChange={setNightReturn} />
                  <DateField label="Fait le" value={nightSignedAt} onChange={setNightSignedAt} />
                </div>
                <label className="relative block">
                  <Search className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" size={16} />
                  <input value={employeeSearch} onChange={(event) => setEmployeeSearch(event.target.value)} placeholder="Rechercher un salarié..." className="w-full rounded-md border border-slate-300 py-2 pl-9 pr-3 text-sm" />
                </label>
                <div className="max-h-36 overflow-y-auto rounded-md border border-slate-200">
                  {filteredEmployees.map((employee) => <button key={employee.cos} type="button" onClick={() => addNightEmployee(employee)} className="block w-full border-b border-slate-100 px-3 py-2 text-left text-xs hover:bg-blue-50">{employeeLabel(employee)}</button>)}
                </div>
                <div className="space-y-2">
                  {nightEmployees.map((selection) => {
                    const employee = employees.find((item) => item.cos === selection.cos);
                    return <div key={selection.cos} className="flex items-center gap-2 rounded-md bg-slate-50 p-2 text-xs">
                      <span className="min-w-0 flex-1 truncate font-semibold">{employee ? employeeLabel(employee) : selection.cos}</span>
                      <select value={selection.role} onChange={(event) => setNightEmployees((current) => current.map((item) => item.cos === selection.cos ? { ...item, role: event.target.value as NightRole } : item))} className="rounded border border-slate-300 bg-white p-1">
                        <option value="OUVRIER">Ouvrier</option><option value="CHEF_EQUIPE">Chef d’équipe</option>
                      </select>
                      <button type="button" title="Retirer" onClick={() => setNightEmployees((current) => current.filter((item) => item.cos !== selection.cos))}><X size={16} /></button>
                    </div>;
                  })}
                </div>
              </div> : <DateField label={selectedReport === "indicateurs-mensuels" || selectedReport === "elements-paie" ? "Dernière date du mois" : "Situation au"} value={date} onChange={setDate} />}
              <button type="button" onClick={() => void generate()} disabled={loading || (selectedReport === "avenant-equipe-nuit" && nightEmployees.length === 0)} className="mt-4 inline-flex w-full items-center justify-center gap-2 rounded-md bg-blue-600 px-4 py-2.5 font-semibold text-white hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-50">
                <RefreshCw size={17} className={loading ? "animate-spin" : ""} />{loading ? "Génération..." : "Générer l’état"}
              </button>
              {selectedReport === "avenant-equipe-nuit" && <p className="mt-2 text-xs text-slate-500">La génération enregistre aussi les avenants dans l’historique Équipe de nuit.</p>}
            </section>
          </aside>

          <section>
            <div className="etats-screen mb-4 flex items-center justify-between rounded-xl bg-white p-4 shadow-sm">
              <div><h2 className="font-bold">Aperçu</h2><p className="text-sm text-slate-500">Imprimez ou choisissez « Enregistrer au format PDF » dans la fenêtre d’impression.</p></div>
              <button type="button" onClick={() => window.print()} disabled={!report} className="inline-flex items-center gap-2 rounded-md bg-slate-900 px-4 py-2 font-semibold text-white disabled:opacity-40"><Printer size={17} />Imprimer / PDF</button>
            </div>
            {error && <div className="etats-screen mb-4 rounded-md border border-red-300 bg-red-50 p-3 text-sm text-red-700">{error}</div>}
            <div className="etat-preview overflow-auto rounded-xl bg-slate-300 p-5 shadow-inner">
              {report ? <ReportPreview id={selectedReport} report={report} /> : <div className="etats-screen flex min-h-[520px] items-center justify-center rounded-lg bg-white text-center text-slate-500"><div><FileText className="mx-auto mb-3" size={42} /><p className="font-semibold">Choisissez les paramètres puis générez l’état.</p></div></div>}
            </div>
          </section>
        </div>
      </div>
    </main>
  );
}

function DateField({ label, value, onChange }: { label: string; value: string; onChange: (value: string) => void }) {
  return <label className="block text-sm font-semibold text-slate-700">{label}<input type="date" value={value} onChange={(event) => onChange(event.target.value)} className="mt-1 block w-full rounded-md border border-slate-300 bg-white px-3 py-2 font-normal" /></label>;
}
