"use client";

/* eslint-disable @next/next/no-img-element */

import { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import "./gestion.css";

type CreatedDossierResult = {
  reference: string;
  portalUrl: string;
  driveFolderUrl: string;
  driveFolderName: string;
  mondayItemUrl: string;
};

type MissionKey = "ppr" | "re" | "resp" | "rga";
type ProjectKey = "Maison neuve" | "Extension" | "Autre";

type DossierGroup = "in_progress" | "completed" | "cancelled";

type AdminDossier = {
  reference: string;
  firstName: string;
  lastName: string;
  email: string;
  city: string;
  projectType: string;
  projectDetail: string;
  createdSurface: number;
  daactCode: string;
  status: string;
  group: DossierGroup;
  piecesReceived: number;
  filesReceived: number;
  piecesExpected: number;
  completeness: number;
  quoteNumber: string;
  quoteStatus: string;
  depositInvoiceNumber: string;
  depositInvoiceStatus: string;
  balanceInvoiceNumber: string;
  balanceInvoiceStatus: string;
  paymentWaiting: boolean;
  reminderObject: string;
  reminderDate: string;
  lastUpdate: string;
  portalUrl: string;
  driveFolderUrl: string;
  mondayItemUrl: string;
  lastError: string;
};

type DossierSummary = {
  inProgress: number;
  completed: number;
  cancelled: number;
  completeToProcess: number;
  reminders: number;
  paymentsWaiting: number;
  toVerify: number;
};

type DossierListResult = {
  dossiers: AdminDossier[];
  summary: DossierSummary;
  generatedAt: string;
};

const missions: Record<MissionKey, {
  label: string;
  code: string;
  icon: string;
  description: string;
  documents: number;
  photos: number;
  manual?: number;
}> = {
  ppr: {
    label: "DAACT Sismique",
    code: "PPR",
    icon: "/risks/sismique.jpg",
    description: "Contrôle parasismique de fin de chantier",
    documents: 18,
    photos: 7,
  },
  re: {
    label: "DAACT RE2020",
    code: "RE",
    icon: "/risks/re2020.jpg",
    description: "RE2020 complète avec suivi de visite",
    documents: 17,
    photos: 9,
    manual: 1,
  },
  resp: {
    label: "DAACT RE simplifiée",
    code: "RESP",
    icon: "/risks/re2020.jpg",
    description: "Checklist adaptée aux travaux concernés",
    documents: 7,
    photos: 8,
  },
  rga: {
    label: "DAACT RGA",
    code: "RGA",
    icon: "/risks/rga.jpg",
    description: "Retrait-gonflement des argiles",
    documents: 15,
    photos: 11,
  },
};

function Icon({ name }: { name: string }) {
  const p = {
    width: 22,
    height: 22,
    viewBox: "0 0 24 24",
    fill: "none",
    stroke: "currentColor",
    strokeWidth: 1.8,
    strokeLinecap: "round" as const,
    strokeLinejoin: "round" as const,
    "aria-hidden": true,
  };
  if (name === "folder") return <svg {...p}><path d="M3.5 6.5h6l2 2h9v10h-17z" /><path d="M3.5 9h17" /></svg>;
  if (name === "plus") return <svg {...p}><path d="M12 5v14M5 12h14" /></svg>;
  if (name === "bell") return <svg {...p}><path d="M6.5 10a5.5 5.5 0 0 1 11 0c0 6 2.5 6 2.5 6H4s2.5 0 2.5-6Z" /><path d="M10 19h4" /></svg>;
  if (name === "check") return <svg {...p}><path d="m5 12 4 4L19 6" /></svg>;
  if (name === "search") return <svg {...p}><circle cx="10.5" cy="10.5" r="6.5" /><path d="m15.5 15.5 4 4" /></svg>;
  if (name === "link") return <svg {...p}><path d="M10 13.5a4 4 0 0 0 5.7 0l2.5-2.5a4 4 0 0 0-5.7-5.7L11 6.8" /><path d="M14 10.5a4 4 0 0 0-5.7 0L5.8 13a4 4 0 0 0 5.7 5.7l1.5-1.5" /></svg>;
  if (name === "copy") return <svg {...p}><rect x="8" y="8" width="11" height="11" rx="2" /><path d="M16 8V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h3" /></svg>;
  if (name === "calendar") return <svg {...p}><rect x="3.5" y="5.5" width="17" height="15" rx="2" /><path d="M7 3v5M17 3v5M3.5 10h17" /></svg>;
  if (name === "settings") return <svg {...p}><circle cx="12" cy="12" r="3" /><path d="M19 13.5v-3l-2-.7-.6-1.5.9-1.9-2.1-2.1-1.9.9-1.5-.6-.7-2h-3l-.7 2-1.5.6-1.9-.9-2.1 2.1.9 1.9-.6 1.5-2 .7v3l2 .7.6 1.5-.9 1.9 2.1 2.1 1.9-.9 1.5.6.7 2h3l.7-2 1.5-.6 1.9.9 2.1-2.1-.9-1.9.6-1.5z" /></svg>;
  return <svg {...p}><path d="M5 3.5h14v17H5z" /><path d="M8 8h8M8 12h8M8 16h5" /></svg>;
}

function clean(value: string) {
  return value
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .replace(/[^a-zA-Z0-9]+/g, "_")
    .replace(/^_|_$/g, "")
    .toUpperCase();
}

function missionKeyFromCode(code: string): MissionKey {
  const normalized = code.toUpperCase();
  if (normalized === "RE") return "re";
  if (normalized === "RESP") return "resp";
  if (normalized === "RGA") return "rga";
  return "ppr";
}

function initials(firstName: string, lastName: string) {
  return `${firstName.trim().charAt(0)}${lastName.trim().charAt(0)}`.toUpperCase() || "—";
}

function formatAdminDate(value: string) {
  if (!value) return "—";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return new Intl.DateTimeFormat("fr-FR", { day: "numeric", month: "short", year: "numeric" }).format(date);
}

const emptySummary: DossierSummary = {
  inProgress: 0,
  completed: 0,
  cancelled: 0,
  completeToProcess: 0,
  reminders: 0,
  paymentsWaiting: 0,
  toVerify: 0,
};

export default function GestionPage() {
  const [wizardOpen, setWizardOpen] = useState(false);
  const [activityOpen, setActivityOpen] = useState<AdminDossier | null>(null);
  const [linkRegenerationPending, setLinkRegenerationPending] = useState(false);
  const [linkRegenerationError, setLinkRegenerationError] = useState<string | null>(null);
  const [dossiers, setDossiers] = useState<AdminDossier[]>([]);
  const [summary, setSummary] = useState<DossierSummary>(emptySummary);
  const [listPending, setListPending] = useState(true);
  const [listError, setListError] = useState<string | null>(null);
  const [search, setSearch] = useState("");
  const [typeFilter, setTypeFilter] = useState<"all" | MissionKey>("all");
  const [step, setStep] = useState(1);
  const [created, setCreated] = useState(false);
  const [creationBlocked, setCreationBlocked] = useState(false);
  const [creationPending, setCreationPending] = useState(false);
  const [creationError, setCreationError] = useState<string | null>(null);
  const [createdDossier, setCreatedDossier] = useState<CreatedDossierResult | null>(null);
  const [copied, setCopied] = useState(false);
  const [activeGroup, setActiveGroup] = useState<"cours" | "termines" | "annules">("cours");
  const [mission, setMission] = useState<MissionKey>("ppr");
  const [projectType, setProjectType] = useState<ProjectKey>("Maison neuve");
  const [firstName, setFirstName] = useState("");
  const [lastName, setLastName] = useState("");
  const [city, setCity] = useState("");
  const [email, setEmail] = useState("");
  const [surface, setSurface] = useState("");
  const [detail, setDetail] = useState("");
  const [quoteNumber, setQuoteNumber] = useState("");
  const [quoteStatus, setQuoteStatus] = useState("Accepté");
  const [depositNumber, setDepositNumber] = useState("");
  const [depositStatus, setDepositStatus] = useState("Payée");
  const [balanceNumber, setBalanceNumber] = useState("");
  const [balanceStatus, setBalanceStatus] = useState("Envoyée");
  const [reminderType, setReminderType] = useState("Pièces manquantes");
  const [reminderDate, setReminderDate] = useState("");

  const loadDossiers = useCallback(async () => {
    try {
      const response = await fetch("/api/dossiers", { cache: "no-store" });
      const payload = await response.json();
      if (!response.ok || !payload.ok) throw new Error(payload.error || "Liste indisponible.");
      const result = payload.data as DossierListResult;
      setDossiers(result.dossiers || []);
      setSummary(result.summary || emptySummary);
      setListError(null);
    } catch (error) {
      setListError(error instanceof Error ? error.message : "Liste indisponible.");
    } finally {
      setListPending(false);
    }
  }, []);

  useEffect(() => {
    let cancelled = false;
    fetch("/api/dossiers", { cache: "no-store" })
      .then(async (response) => {
        const payload = await response.json();
        if (!response.ok || !payload.ok) throw new Error(payload.error || "Liste indisponible.");
        return payload.data as DossierListResult;
      })
      .then((result) => {
        if (cancelled) return;
        setDossiers(result.dossiers || []);
        setSummary(result.summary || emptySummary);
        setListError(null);
      })
      .catch((error) => {
        if (!cancelled) setListError(error instanceof Error ? error.message : "Liste indisponible.");
      })
      .finally(() => {
        if (!cancelled) setListPending(false);
      });
    return () => { cancelled = true; };
  }, []);

  const visibleDossiers = useMemo(() => {
    const group: DossierGroup = activeGroup === "cours" ? "in_progress" : activeGroup === "termines" ? "completed" : "cancelled";
    const query = clean(search);
    return dossiers.filter((dossier) => {
      if (dossier.group !== group) return false;
      if (typeFilter !== "all" && missionKeyFromCode(dossier.daactCode) !== typeFilter) return false;
      if (!query) return true;
      return clean(`${dossier.firstName} ${dossier.lastName} ${dossier.city} ${dossier.reference} ${dossier.email}`).includes(query);
    });
  }, [activeGroup, dossiers, search, typeFilter]);

  const reference = createdDossier?.reference ?? "Référence générée automatiquement";
  const missionData = missions[mission];
  const folderName = useMemo(
    () => `${reference}_${clean(lastName)}_${clean(firstName)}_${clean(city)}_${missionData.code}`,
    [reference, firstName, lastName, city, missionData.code],
  );
  const clientLink = createdDossier?.portalUrl ?? "";

  const resetWizard = () => {
    setWizardOpen(false);
    setCreated(false);
    setCreationBlocked(false);
    setCreationPending(false);
    setCreationError(null);
    setCreatedDossier(null);
    setCopied(false);
    setStep(1);
  };

  const handleCopy = async () => {
    if (!clientLink) return;
    try { await navigator.clipboard.writeText(clientLink); } catch { /* preview fallback */ }
    setCopied(true);
  };

  const handleRegenerateLink = async () => {
    if (!activityOpen || linkRegenerationPending) return;
    const accepted = window.confirm("Régénérer ce lien ? L’ancien lien client cessera immédiatement de fonctionner.");
    if (!accepted) return;
    setLinkRegenerationPending(true);
    setLinkRegenerationError(null);
    try {
      const response = await fetch(`/api/admin/dossiers/${encodeURIComponent(activityOpen.reference)}/regenerate`, { method: "POST" });
      const payload = await response.json();
      if (!response.ok || !payload.ok) throw new Error(payload.error || "Régénération impossible.");
      const portalUrl = String(payload.data?.portalUrl || "");
      const updated = { ...activityOpen, portalUrl, lastUpdate: new Date().toISOString() };
      setActivityOpen(updated);
      setDossiers((current) => current.map((dossier) => dossier.reference === updated.reference ? updated : dossier));
    } catch (error) {
      setLinkRegenerationError(error instanceof Error ? error.message : "Régénération impossible.");
    } finally {
      setLinkRegenerationPending(false);
    }
  };

  const handleCreateDossier = async () => {
    setCreationPending(true);
    setCreationBlocked(false);
    setCreationError(null);

    try {
      const response = await fetch("/api/dossiers", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({
          requestId: crypto.randomUUID(),
          firstName,
          lastName,
          email,
          city,
          projectType,
          projectDetail: detail,
          createdSurface: Number(surface),
          daactCode: missionData.code,
          quoteNumber,
          quoteStatus: quoteNumber ? quoteStatus : "",
          depositInvoiceNumber: depositNumber,
          depositInvoiceStatus: depositNumber ? depositStatus : "",
          balanceInvoiceNumber: balanceNumber,
          balanceInvoiceStatus: balanceNumber ? balanceStatus : "",
          reminderObject: reminderDate ? reminderType : "",
          reminderDate,
        }),
      });

      const payload = await response.json();
      if (!response.ok || !payload.ok) throw new Error(payload.error || "Création impossible.");

      setCreatedDossier(payload.data as CreatedDossierResult);
      setCreated(true);
      void loadDossiers();
    } catch (error) {
      setCreationError(error instanceof Error ? error.message : "Création impossible.");
      setCreationBlocked(true);
    } finally {
      setCreationPending(false);
    }
  };

  return (
    <main className="admin-shell">
      <aside className="admin-sidebar">
        <Link className="admin-brand" href="/" aria-label="Portail ENRGETIC"><img src="/brand/enrgetic-logo.png" alt="ENRGETIC" /></Link>
        <div className="admin-label">Gestion DAACT</div>
        <nav className="admin-nav" aria-label="Navigation administration">
          <button className="active" type="button"><Icon name="folder" />Dossiers<span>{dossiers.length}</span></button>
          <button type="button" onClick={() => setWizardOpen(true)}><Icon name="plus" />Nouveau dossier</button>
          <button type="button"><Icon name="bell" />Relances<span className="warning">{summary.reminders}</span></button>
          <button type="button"><Icon name="document" />À vérifier<span>{summary.toVerify}</span></button>
        </nav>
        <div className="admin-spacer" />
        <Link className="sidebar-settings" href="/gestion/parametres"><Icon name="settings" />Paramètres</Link>
        <div className="admin-user"><span>AA</span><div><strong>Agent administratif</strong><small>Administration</small></div></div>
      </aside>

      <section className="admin-content">
        <header className="admin-topbar">
          <div><p className="admin-eyebrow">Pilotage documentaire</p><h1>Dossiers conformité</h1></div>
          <div className="admin-top-actions">
            <label className="search-box"><Icon name="search" /><input value={search} onChange={(event) => setSearch(event.target.value)} placeholder="Rechercher un client, une ville…" /></label>
            <button className="new-case-button" type="button" onClick={() => setWizardOpen(true)}><Icon name="plus" />Créer un dossier</button>
          </div>
        </header>

        <section className="admin-kpis" aria-label="Synthèse">
          <article><span className="kpi-icon petrol"><Icon name="folder" /></span><div><strong>{summary.inProgress}</strong><p>Dossiers en cours</p></div><em>Données réelles</em></article>
          <article><span className="kpi-icon green"><Icon name="check" /></span><div><strong>{summary.completeToProcess}</strong><p>Complets à traiter</p></div><em>Action interne</em></article>
          <article><span className="kpi-icon orange"><Icon name="bell" /></span><div><strong>{summary.reminders}</strong><p>Relances prévues</p></div><em>Aucune automatique</em></article>
          <article><span className="kpi-icon purple">€</span><div><strong>{summary.paymentsWaiting}</strong><p>Paiements attendus</p></div><em>Double contrôle</em></article>
        </section>

        <section className="cases-panel">
          <div className="cases-toolbar">
            <div className="group-tabs">
              <button type="button" className={activeGroup === "cours" ? "active" : ""} onClick={() => setActiveGroup("cours")}>En cours <span>{summary.inProgress}</span></button>
              <button type="button" className={activeGroup === "termines" ? "active" : ""} onClick={() => setActiveGroup("termines")}>Terminés <span>{summary.completed}</span></button>
              <button type="button" className={activeGroup === "annules" ? "active" : ""} onClick={() => setActiveGroup("annules")}>Annulés <span>{summary.cancelled}</span></button>
            </div>
            <label className="filter-button">Type de DAACT
              <select value={typeFilter} onChange={(event) => setTypeFilter(event.target.value as "all" | MissionKey)}>
                <option value="all">Tous les types</option>
                <option value="ppr">Sismique</option>
                <option value="re">RE2020</option>
                <option value="resp">RE simplifiée</option>
                <option value="rga">RGA</option>
              </select>
            </label>
          </div>

          {listPending ? (
            <div className="empty-group"><span><Icon name="folder" /></span><h2>Chargement des dossiers…</h2><p>Lecture du registre ENRGETIC.</p></div>
          ) : listError ? (
            <div className="empty-group"><span>!</span><h2>Liste momentanément indisponible</h2><p>{listError}</p><button className="wizard-secondary" type="button" onClick={() => { setListPending(true); void loadDossiers(); }}>Réessayer</button></div>
          ) : visibleDossiers.length ? (
            <div className="cases-table-wrap">
              <table className="cases-table">
                <thead><tr><th>Client et projet</th><th>DAACT</th><th>Avancement</th><th>Pièces</th><th>Règlements</th><th>Prochaine relance</th><th><span className="sr-only-admin">Actions</span></th></tr></thead>
                <tbody>
                  {visibleDossiers.map((row, index) => {
                    const info = missions[missionKeyFromCode(row.daactCode)];
                    const clientName = `${row.firstName} ${row.lastName}`.trim();
                    const detailLabel = row.projectDetail || row.projectType;
                    return (
                      <tr key={row.reference}>
                        <td><button className="client-cell client-row-link client-row-button" type="button" onClick={() => setActivityOpen(row)}><span className={`avatar avatar-${index % 4 + 1}`}>{initials(row.firstName, row.lastName)}</span><div><strong>{clientName}</strong><small>{row.city} · {detailLabel}{row.createdSurface ? ` · ${row.createdSurface} m²` : ""}</small></div></button></td>
                        <td><div className="mission-cell"><img src={info.icon} alt="" /><div><strong>{info.label}</strong><small>{info.code}</small></div></div></td>
                        <td><span className={`case-status status-${index % 4 + 1}`}>{row.status}</span><div className="table-progress"><span style={{ width: `${row.completeness}%` }} /></div></td>
                        <td><strong className="piece-count">{row.piecesReceived} / {row.piecesExpected}</strong><small className="cell-caption">pièces · {row.filesReceived} fichiers</small></td>
                        <td><div className="payment-lines"><span><i className={row.depositInvoiceStatus === "Payée" ? "paid" : row.depositInvoiceStatus ? "sent" : "empty"} />Acompte {row.depositInvoiceStatus || "—"}</span><span><i className={row.balanceInvoiceStatus === "Payée" ? "paid" : row.balanceInvoiceStatus ? "sent" : "empty"} />Solde {row.balanceInvoiceStatus || "—"}</span></div></td>
                        <td><span className="reminder-date"><Icon name="calendar" />{formatAdminDate(row.reminderDate)}</span></td>
                        <td><button className="more-button" type="button" onClick={() => setActivityOpen(row)} aria-label={`Voir le dossier de ${clientName}`}>+</button></td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          ) : (
            <div className="empty-group"><span><Icon name={activeGroup === "termines" ? "check" : "folder"} /></span><h2>Aucun dossier dans cette vue</h2><p>{search || typeFilter !== "all" ? "Modifiez la recherche ou le filtre." : "Ce groupe reste séparé : aucune relance ne peut partir depuis cet état."}</p></div>
          )}
        </section>

        <aside className="admin-note"><span>i</span><p><strong>Principe retenu :</strong> une ligne correspond à une DAACT. Un même client peut donc avoir plusieurs lignes, plusieurs liens et des calendriers d’avancement indépendants.</p></aside>
      </section>

      {wizardOpen && (
        <div className="wizard-backdrop" onMouseDown={resetWizard}>
          <section className="wizard-panel" role="dialog" aria-modal="true" aria-labelledby="wizard-title" onMouseDown={(event) => event.stopPropagation()}>
            <div className="wizard-header">
              <div><p className="admin-eyebrow">Nouveau suivi</p><h2 id="wizard-title">Créer un dossier DAACT</h2></div>
              <button type="button" onClick={resetWizard} aria-label="Fermer">×</button>
            </div>

            {!created ? (
              <>
                <div className="wizard-steps" aria-label="Étapes">
                  {[1, 2, 3].map((value) => <div key={value} className={step >= value ? "active" : ""}><span>{step > value ? "✓" : value}</span><small>{value === 1 ? "Client et projet" : value === 2 ? "Type de DAACT" : "Suivi et relances"}</small></div>)}
                </div>

                <div className="wizard-body">
                  {step === 1 && (
                    <div className="form-section">
                      <div className="form-heading"><h3>Identifier le chantier</h3><p>Ces informations nomment le dossier Drive et personnalisent l’espace client.</p></div>
                      <div className="form-grid two">
                        <label>Prénom<input value={firstName} onChange={(event) => setFirstName(event.target.value)} /></label>
                        <label>Nom<input value={lastName} onChange={(event) => setLastName(event.target.value)} /></label>
                        <label className="wide">E-mail client<input type="email" value={email} onChange={(event) => setEmail(event.target.value)} /></label>
                        <label>Ville du projet<input value={city} onChange={(event) => setCity(event.target.value)} /></label>
                        <label>Surface créée (m²)<input inputMode="decimal" value={surface} onChange={(event) => setSurface(event.target.value)} /></label>
                      </div>
                      <fieldset className="choice-field"><legend>Nature du projet</legend><div className="segmented">{(["Maison neuve", "Extension", "Autre"] as ProjectKey[]).map((type) => <button key={type} type="button" className={projectType === type ? "active" : ""} onClick={() => setProjectType(type)}>{type}</button>)}</div><small>{projectType === "Extension" ? "Comprend aussi un garage ou carport accolé." : projectType === "Autre" ? "Garage, carport ou autre annexe indépendante uniquement." : "Construction d’une maison individuelle neuve."}</small></fieldset>
                      <label className="detail-field">Précision projet<textarea value={detail} onChange={(event) => setDetail(event.target.value)} rows={3} /></label>
                    </div>
                  )}

                  {step === 2 && (
                    <div className="form-section">
                      <div className="form-heading"><h3>Choisir une seule mission</h3><p>Une mission crée une ligne Monday, un dossier Drive et un lien client dédiés.</p></div>
                      <div className="mission-choice-grid">
                        {(Object.keys(missions) as MissionKey[]).map((key) => {
                          const info = missions[key];
                          return <button key={key} type="button" className={mission === key ? "active" : ""} onClick={() => setMission(key)}><img src={info.icon} alt="" /><span><strong>{info.label}</strong><small>{info.description}</small></span><b>{info.code}</b></button>;
                        })}
                      </div>
                      <div className="checklist-preview">
                        <div><span className="preview-icon"><Icon name="document" /></span><p><strong>{missionData.documents}</strong><small>pièces documentaires</small></p></div>
                        <div><span className="preview-icon"><Icon name="folder" /></span><p><strong>{missionData.photos}</strong><small>catégories photo</small></p></div>
                        <p className="preview-note">Checklist issue du référentiel ENRGETIC V1 · Les éléments conditionnels seront adaptés au projet.</p>
                      </div>
                    </div>
                  )}

                  {step === 3 && (
                    <div className="form-section">
                      <div className="form-heading"><h3>Facturation et rythme des relances</h3><p>Les relances restent sous le contrôle de l’agent administratif : date choisie ou action manuelle.</p></div>
                      <div className="billing-grid">
                        <article><h4>Devis</h4><label>N° de devis<input value={quoteNumber} onChange={(event) => setQuoteNumber(event.target.value)} /></label><label>Statut<select value={quoteStatus} onChange={(event) => setQuoteStatus(event.target.value)}><option>Envoyé</option><option>Accepté</option></select></label></article>
                        <article><h4>Facture d’acompte</h4><label>N° de facture<input value={depositNumber} onChange={(event) => setDepositNumber(event.target.value)} /></label><label>Statut<select value={depositStatus} onChange={(event) => setDepositStatus(event.target.value)}><option>Envoyée</option><option>Payée</option></select></label></article>
                        <article><h4>Facture de solde</h4><label>N° de facture<input placeholder="À renseigner plus tard" value={balanceNumber} onChange={(event) => setBalanceNumber(event.target.value)} /></label><label>Statut<select value={balanceStatus} onChange={(event) => setBalanceStatus(event.target.value)}><option>Envoyée</option><option>Payée</option></select></label></article>
                      </div>
                      <div className="reminder-builder">
                        <span className="preview-icon"><Icon name="bell" /></span>
                        <div><strong>Première relance autorisée</strong><p>Aucun message avant cette date. L’agent administratif pourra aussi utiliser « Relancer maintenant ».</p></div>
                        <label>Objet<select value={reminderType} onChange={(event) => setReminderType(event.target.value)}><option>Pièces manquantes</option><option>Acompte non payé</option><option>Dossier complet — solde attendu</option></select></label>
                        <label>Date<input type="date" value={reminderDate} onChange={(event) => setReminderDate(event.target.value)} /></label>
                      </div>
                      <div className="generated-path"><span><Icon name="folder" /></span><div><small>Dossier créé dans DAACT PARTAGE / Dossiers en Cours</small><strong>La référence et le nom définitif seront générés à la validation.</strong></div></div>
                    </div>
                  )}
                </div>

                <footer className="wizard-footer">
                  <button type="button" className="wizard-secondary" onClick={step === 1 ? resetWizard : () => setStep(step - 1)}>{step === 1 ? "Annuler" : "Retour"}</button>
                  <button
                    type="button"
                    className="wizard-primary"
                    disabled={creationPending}
                    onClick={() => {
                      if (step < 3) setStep(step + 1);
                      else void handleCreateDossier();
                    }}
                  >
                    {step < 3 ? "Continuer" : creationPending ? "Création en cours…" : "Créer le dossier et le lien"}<span>→</span>
                  </button>
                </footer>
                {creationBlocked && (
                  <div className="settings-notice" role="status">
                    <span>i</span>
                    <p>{creationError || "La création n’a pas pu être finalisée. Aucun résultat incomplet n’est présenté comme réussi."}</p>
                    <button type="button" onClick={() => setCreationBlocked(false)} aria-label="Fermer">×</button>
                  </div>
                )}
              </>
            ) : (
              <div className="success-state">
                <span className="success-check"><Icon name="check" /></span>
                <p className="admin-eyebrow">Dossier prêt</p>
                <h3>{missionData.label} · {firstName} {lastName}</h3>
                <p>La checklist personnalisée est prête. Le lien reste accessible pendant toute la durée du chantier.</p>
                <div className="success-summary"><span><img src={missionData.icon} alt="" /></span><div><small>Dossier Drive créé</small><strong>{createdDossier?.driveFolderName ?? folderName}</strong><small>{projectType} · {surface} m² · {city}</small></div></div>
                <div className="link-box"><div><Icon name="link" /><span><small>Lien nominatif client</small><strong>{clientLink}</strong></span></div><button type="button" onClick={handleCopy}><Icon name="copy" />{copied ? "Copié" : "Copier"}</button></div>
                <div className="success-actions"><a className="wizard-secondary" href={createdDossier?.driveFolderUrl} target="_blank" rel="noreferrer">Ouvrir Drive</a><a className="wizard-secondary" href={createdDossier?.mondayItemUrl} target="_blank" rel="noreferrer">Ouvrir Monday</a></div>
                <div className="success-actions"><button className="wizard-secondary" type="button" onClick={resetWizard}>Fermer</button><button className="wizard-primary" type="button">Préparer l’e-mail client <span>→</span></button></div>
              </div>
            )}
          </section>
        </div>
      )}

      {activityOpen && (
        <div className="activity-backdrop" onMouseDown={() => setActivityOpen(null)}>
          <aside className="activity-panel" role="dialog" aria-modal="true" aria-labelledby="activity-title" onMouseDown={(event) => event.stopPropagation()}>
            <header>
              <div><p className="admin-eyebrow">Résumé du dossier</p><h2 id="activity-title">{activityOpen.firstName} {activityOpen.lastName}</h2><span>{activityOpen.reference} · {missions[missionKeyFromCode(activityOpen.daactCode)].label}</span></div>
              <button type="button" onClick={() => setActivityOpen(null)} aria-label="Fermer">×</button>
            </header>
            <div className="activity-sync"><span><Icon name="check" /></span><p><strong>Synchronisé avec Monday et Drive</strong><br />Dernière activité connue : {formatAdminDate(activityOpen.lastUpdate)}.</p></div>
            <div className="activity-timeline">
              <article className="activity-entry">
                <span className="activity-dot green" />
                <div className="activity-card">
                  <div className="activity-meta"><span className="activity-kind green">État réel</span><time>{formatAdminDate(activityOpen.lastUpdate)}</time></div>
                  <h3>{activityOpen.status}</h3>
                  <p>{activityOpen.piecesReceived} pièce(s) attendue(s) représentée(s) par {activityOpen.filesReceived} fichier(s), sur {activityOpen.piecesExpected} éléments de checklist.</p>
                  <div className="activity-files">
                    <span><Icon name="document" />Acompte : {activityOpen.depositInvoiceStatus || "non renseigné"}</span>
                    <span><Icon name="document" />Solde : {activityOpen.balanceInvoiceStatus || "non renseigné"}</span>
                    <span><Icon name="calendar" />Relance : {formatAdminDate(activityOpen.reminderDate)}{activityOpen.reminderObject ? ` · ${activityOpen.reminderObject}` : ""}</span>
                  </div>
                  <footer><span>Données du registre ENRGETIC</span>{activityOpen.mondayItemUrl && <a href={activityOpen.mondayItemUrl} target="_blank" rel="noreferrer">Voir dans Monday ↗</a>}</footer>
                </div>
              </article>
            </div>
            <div className="activity-rule"><strong>Accès rapides</strong><p>Le journal détaillé et daté reste dans les mises à jour Monday. Les dépôts multiples créent une seule entrée récapitulative.</p><div className="activity-links">{activityOpen.portalUrl && <a href={activityOpen.portalUrl} target="_blank" rel="noreferrer">Espace client</a>}{activityOpen.driveFolderUrl && <a href={activityOpen.driveFolderUrl} target="_blank" rel="noreferrer">Dossier Drive</a>}{activityOpen.mondayItemUrl && <a href={activityOpen.mondayItemUrl} target="_blank" rel="noreferrer">Ligne Monday</a>}<button type="button" onClick={() => void handleRegenerateLink()} disabled={linkRegenerationPending}>{linkRegenerationPending ? "Régénération…" : "Régénérer le lien client"}</button></div>{linkRegenerationError && <p className="activity-error">{linkRegenerationError}</p>}{activityOpen.lastError && <p className="activity-error">À vérifier : {activityOpen.lastError}</p>}</div>
          </aside>
        </div>
      )}
    </main>
  );
}
