"use client";

import { FormEvent, useEffect, useState } from "react";

type AuthUser = { displayName: string; email: string; fullName: string | null };
type PortalProfile = {
  id: number;
  lotReference: string;
  firstName: string;
  lastName: string;
  email: string;
  phone: string;
  avenue: string;
  addressNumber: string;
  role: "resident" | "bureau";
  accessStatus: "pending" | "invited" | "active" | "suspended";
  notes: string;
  createdAt: string;
  updatedAt: string;
};

type DueRecord = {
  id: number; memberId: number; year: number; amountCents: number; paidAmountCents: number;
  dueDate: string; status: "pending" | "partial" | "paid" | "overdue" | "cancelled";
  paymentMethod: string | null; paymentReference: string | null; paidAt: string | null; notes: string;
  lotReference: string; firstName: string; lastName: string; avenue: string; email: string;
};

type ReminderRuleRecord = {
  id: number; label: string; enabled: boolean; triggerType: "before_due" | "after_due";
  daysOffset: number; channel: "in_app" | "email"; audience: "unpaid" | "overdue";
};

type PortalProps = {
  authUser: AuthUser | null;
  initialProfile: PortalProfile | null;
  databaseReady: boolean;
  signInPath: string;
  signOutPath: string;
};

type IconName =
  | "home"
  | "news"
  | "wallet"
  | "calendar"
  | "shield"
  | "folder"
  | "users"
  | "bell"
  | "chevron"
  | "arrow"
  | "menu"
  | "plus"
  | "clock"
  | "check"
  | "map"
  | "leaf"
  | "download"
  | "mail"
  | "search"
  | "send"
  | "eye"
  | "upload"
  | "credit"
  | "settings"
  | "more"
  | "close";

function Icon({ name, size = 20 }: { name: IconName; size?: number }) {
  const paths: Record<IconName, React.ReactNode> = {
    home: <><path d="M3 10.7 12 3l9 7.7"/><path d="M5.5 9.5V21h13V9.5M9.5 21v-7h5v7"/></>,
    news: <><path d="M5 4h14v16H5z"/><path d="M8 8h8M8 12h8M8 16h5"/></>,
    wallet: <><path d="M4 6.5h14a2 2 0 0 1 2 2v10H4a2 2 0 0 1-2-2v-12a2 2 0 0 1 2-2h12"/><path d="M15 11h7v4h-7a2 2 0 0 1 0-4Z"/></>,
    calendar: <><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M8 3v4M16 3v4M3 10h18"/><path d="M8 14h.01M12 14h.01M16 14h.01M8 18h.01M12 18h.01"/></>,
    shield: <><path d="M12 22s8-3.5 8-10V5l-8-3-8 3v7c0 6.5 8 10 8 10Z"/><path d="m9 12 2 2 4-5"/></>,
    folder: <><path d="M3 5h7l2 2h9v12H3z"/></>,
    users: <><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"/></>,
    bell: <><path d="M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9"/><path d="M10 21h4"/></>,
    chevron: <path d="m9 18 6-6-6-6"/>,
    arrow: <><path d="M5 12h14"/><path d="m14 7 5 5-5 5"/></>,
    menu: <><path d="M4 7h16M4 12h16M4 17h16"/></>,
    plus: <><path d="M12 5v14M5 12h14"/></>,
    clock: <><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></>,
    check: <path d="m5 12 4 4L19 6"/>,
    map: <><path d="m3 6 6-3 6 3 6-3v15l-6 3-6-3-6 3z"/><path d="M9 3v15M15 6v15"/></>,
    leaf: <><path d="M20 4c-7 0-13 3-14 9-.6 3.5 2.5 6 5.5 4.7C17 15.3 19.5 9.3 20 4Z"/><path d="M4 21c2-5 6-8 11-10"/></>,
    download: <><path d="M12 3v12"/><path d="m7 10 5 5 5-5M5 21h14"/></>,
    mail: <><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3 7 9 6 9-6"/></>,
    search: <><circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/></>,
    send: <><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></>,
    eye: <><path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6S2 12 2 12Z"/><circle cx="12" cy="12" r="2.5"/></>,
    upload: <><path d="M12 21V9"/><path d="m7 14 5-5 5 5M5 3h14"/></>,
    credit: <><rect x="2" y="5" width="20" height="14" rx="2"/><path d="M2 10h20M6 15h4"/></>,
    settings: <><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .34 1.87l.06.06-2.83 2.83-.06-.06A1.7 1.7 0 0 0 15 19.4a1.7 1.7 0 0 0-1 .6 1.7 1.7 0 0 0-.4 1.1V21h-4v-.1A1.7 1.7 0 0 0 8.6 19.4a1.7 1.7 0 0 0-1.87.34l-.06.06-2.83-2.83.06-.06A1.7 1.7 0 0 0 4.6 15a1.7 1.7 0 0 0-.6-1 1.7 1.7 0 0 0-1.1-.4H3v-4h.1A1.7 1.7 0 0 0 4.6 8.6a1.7 1.7 0 0 0-.34-1.87l-.06-.06 2.83-2.83.06.06A1.7 1.7 0 0 0 9 4.6a1.7 1.7 0 0 0 1-.6 1.7 1.7 0 0 0 .4-1.1V3h4v.1A1.7 1.7 0 0 0 15.4 4.6a1.7 1.7 0 0 0 1.87-.34l.06-.06 2.83 2.83-.06.06A1.7 1.7 0 0 0 19.4 9c.14.38.36.72.66 1 .3.28.68.43 1.1.4h.1v4h-.1c-.42-.03-.8.12-1.1.4-.3.28-.52.62-.66 1Z"/></>,
    more: <><circle cx="5" cy="12" r="1"/><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/></>,
    close: <><path d="m6 6 12 12M18 6 6 18"/></>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      {paths[name]}
    </svg>
  );
}

const navigation = [
  { id: "home", label: "Accueil", icon: "home" as IconName },
  { id: "actualites", label: "Actualités", icon: "news" as IconName },
  { id: "cotisations", label: "Mes cotisations", icon: "wallet" as IconName },
  { id: "ag", label: "AG & documents", icon: "calendar" as IconName },
  { id: "voisinage", label: "Alertes voisinage", icon: "shield" as IconName },
  { id: "profil", label: "Ma fiche coloti", icon: "users" as IconName },
  { id: "annuaire", label: "Vie du lotissement", icon: "users" as IconName },
];

const bureauNavigation = [
  { id: "overview", label: "Vue d’ensemble", icon: "home" as IconName },
  { id: "dues", label: "Suivi des cotisations", icon: "wallet" as IconName },
  { id: "publications", label: "Informations", icon: "news" as IconName },
  { id: "documents", label: "Documents & AG", icon: "folder" as IconName },
  { id: "alerts", label: "Signalements", icon: "shield" as IconName },
  { id: "residents", label: "Gestion des colotis", icon: "users" as IconName },
];

const notices = [
  {
    tag: "Entretien",
    title: "Débroussaillage : rappel avant le 15 septembre",
    text: "Pensez à maintenir vos accès et abords dégagés conformément aux consignes communales.",
    date: "9 août 2026",
    color: "sage",
  },
  {
    tag: "Travaux",
    title: "Intervention sur l’éclairage des Mimosas",
    text: "Une vérification des candélabres est programmée jeudi matin entre 8 h et 11 h.",
    date: "7 août 2026",
    color: "gold",
  },
];

type Notify = (message: string) => void;

function SectionHeading({ eyebrow, title, text, action }: { eyebrow: string; title: string; text: string; action?: React.ReactNode }) {
  return (
    <section className="section-heading">
      <div><div className="page-kicker"><span /><p>{eyebrow}</p></div><h1>{title}</h1><p>{text}</p></div>
      {action}
    </section>
  );
}

function NewsView({ notify }: { notify: Notify }) {
  const cards = [
    { tag: "Entretien", date: "9 août 2026", title: "Débroussaillage : rappel avant le 15 septembre", text: "Chaque propriétaire est invité à vérifier les abords de sa parcelle et la végétation le long des accès.", icon: "leaf" as IconName, tone: "green" },
    { tag: "Travaux", date: "7 août 2026", title: "Éclairage de l’avenue des Mimosas", text: "Le diagnostic des candélabres aura lieu jeudi matin. Quelques coupures ponctuelles sont possibles.", icon: "settings" as IconName, tone: "gold" },
    { tag: "Vie du lotissement", date: "4 août 2026", title: "Bienvenue aux nouveaux propriétaires", text: "Le bureau souhaite la bienvenue aux familles récemment installées avenue des Oliviers.", icon: "users" as IconName, tone: "green" },
    { tag: "Sécurité", date: "2 août 2026", title: "Bonnes pratiques pendant les départs en vacances", text: "Pensez à prévenir un voisin de confiance et à ne pas laisser de courrier visible dans votre boîte.", icon: "shield" as IconName, tone: "terracotta" },
  ];
  return (
    <>
      <SectionHeading eyebrow="Fil d’information" title="Actualités du lotissement" text="Les communications officielles du bureau, classées et faciles à retrouver." />
      <div className="filter-row"><button className="active">Toutes</button><button>Entretien</button><button>Travaux</button><button>Sécurité</button><label><Icon name="search" size={16}/><input aria-label="Rechercher une information" placeholder="Rechercher…" /></label></div>
      <article className="featured-news">
        <div className="featured-visual"><span>À retenir</span><Icon name="leaf" size={42}/><i/><i/><i/></div>
        <div><span className="news-tag">Information prioritaire · 9 août 2026</span><h2>Prévention incendie et obligations de débroussaillage</h2><p>Le bureau rappelle l’importance de dégager les accès, les toitures et les limites de propriété. Une fiche pratique est disponible dans les documents du lotissement.</p><button onClick={() => notify("La fiche pratique est prête à être consultée dans la rubrique Documents.")}>Lire l’information <Icon name="arrow" size={17}/></button></div>
      </article>
      <div className="news-grid">
        {cards.map((card) => <article key={card.title} className="news-card"><div className={`news-card-icon ${card.tone}`}><Icon name={card.icon} size={24}/></div><div className="news-card-meta"><span>{card.tag}</span><time>{card.date}</time></div><h3>{card.title}</h3><p>{card.text}</p><button onClick={() => notify(`Ouverture de l’information « ${card.title} »`)}>Lire la suite <Icon name="arrow" size={15}/></button></article>)}
      </div>
    </>
  );
}

function DuesView({ notify, openPayment, liveData, profile }: { notify: Notify; openPayment: () => void; liveData: boolean; profile: PortalProfile }) {
  const [records, setRecords] = useState<Array<Partial<DueRecord> & { year: number; amountCents: number; paidAmountCents: number; status: DueRecord["status"] }>>([
    { year: 2026, amountCents: 32000, paidAmountCents: 0, status: "pending", dueDate: "2026-09-30" },
    { year: 2025, amountCents: 30000, paidAmountCents: 30000, status: "paid", paidAt: "2025-09-18" },
    { year: 2024, amountCents: 29000, paidAmountCents: 29000, status: "paid", paidAt: "2024-09-22" },
  ]);
  useEffect(() => {
    if (!liveData) return;
    fetch("/api/dues").then((response) => response.json()).then((data) => { if (Array.isArray(data.dues)) setRecords(data.dues); }).catch(() => {});
  }, [liveData]);
  const current = records.find((record) => record.year === 2026) ?? records[0];
  const history = records.filter((record) => record.year < 2026);
  const amount = current?.amountCents ?? 0;
  const paid = current?.paidAmountCents ?? 0;
  const progress = amount ? Math.min(100, Math.round(paid / amount * 100)) : 0;
  const isPaid = current?.status === "paid";
  const euros = (cents: number) => new Intl.NumberFormat("fr-FR", { style: "currency", currency: "EUR", maximumFractionDigits: 0 }).format(cents / 100);
  return (
    <>
      <SectionHeading eyebrow="Espace financier" title="Mes cotisations" text="Suivez vos échéances, réglez en ligne et retrouvez vos justificatifs." />
      <section className="dues-hero">
        <div className="dues-main"><span className={`status ${isPaid ? "success" : "warning"}`}>{isPaid ? "Réglée" : current?.status === "partial" ? "Paiement partiel" : "Échéance en cours"}</span><p>Cotisation annuelle · Exercice {current?.year ?? 2026}</p><div className="dues-amount"><strong>{euros(amount)}</strong><span>{isPaid ? "Réglée le" : "À régler avant"}<br/><b>{isPaid && current?.paidAt ? new Date(current.paidAt).toLocaleDateString("fr-FR") : "le 30 septembre 2026"}</b></span></div><div className="dues-progress"><i style={{width:`${isPaid ? 100 : Math.max(progress, 5)}%`}}/><span>{isPaid ? "Cotisation soldée" : `${euros(Math.max(0, amount - paid))} restant`}</span></div><div className="dues-actions">{!isPaid && <button onClick={openPayment}><Icon name="credit" size={18}/> Régler maintenant</button>}<button onClick={() => notify(`L’avis de cotisation ${current?.year ?? 2026} est prêt à être téléchargé.`)}><Icon name="download" size={17}/> {isPaid ? "Télécharger la quittance" : "Télécharger l’avis"}</button></div></div>
        <div className="dues-side"><div className="receipt-mark"><Icon name="check" size={26}/></div><span>Situation du compte</span><h3>{isPaid ? "Cotisation à jour" : current?.status === "partial" ? "Règlement partiel enregistré" : "Échéance ouverte"}</h3><p>{isPaid ? "Votre règlement a été pointé par le bureau." : "Le bureau actualise ici votre situation après chaque règlement."}</p><div><small>Référence du lot</small><strong>{profile.lotReference}</strong></div></div>
      </section>
      <div className="two-col-layout">
        <section className="standard-panel">
          <div className="standard-panel-head"><div><span>Historique</span><h2>Mes derniers règlements</h2></div><button onClick={() => notify("L’historique complet est prêt à être exporté.")}><Icon name="download" size={16}/> Exporter</button></div>
          <div className="payment-history">{history.length ? history.map((record) => <div key={record.year}><span className="year-pill">{record.year}</span><p><strong>Cotisation annuelle</strong><small>{record.paidAt ? `Réglée le ${new Date(record.paidAt).toLocaleDateString("fr-FR")}` : "Historique enregistré"}</small></p><b>{euros(record.amountCents)}</b><span className="paid-badge"><Icon name="check" size={13}/> {record.status === "paid" ? "Payée" : "Archivée"}</span><button aria-label={`Télécharger le reçu ${record.year}`} onClick={() => notify(`Reçu ${record.year} prêt à être téléchargé`)}><Icon name="download" size={17}/></button></div>) : <p className="empty-history">Aucun exercice antérieur n’est encore enregistré.</p>}</div>
        </section>
        <aside className="standard-panel preferences-panel"><div className="standard-panel-head"><div><span>Rappels</span><h2>Mes notifications</h2></div></div><p>Choisissez comment recevoir les échéances importantes.</p><label><span><Icon name="mail" size={17}/><b>Rappel par e-mail</b></span><input type="checkbox" defaultChecked /></label><label><span><Icon name="bell" size={17}/><b>Notification dans l’espace</b></span><input type="checkbox" defaultChecked /></label><button onClick={() => notify("Vos préférences de notification sont enregistrées.")}>Enregistrer mes préférences</button></aside>
      </div>
    </>
  );
}

function MeetingsView({ notify, openDocument }: { notify: Notify; openDocument: (title: string) => void }) {
  const docs = [
    ["Procès-verbal de l’AG 2025", "PV d’assemblée générale", "PDF · 1,8 Mo", "4 août 2026"],
    ["Comptes annuels 2025", "Comptabilité", "PDF · 920 Ko", "4 août 2026"],
    ["Budget prévisionnel 2026", "Comptabilité", "PDF · 610 Ko", "4 août 2026"],
    ["Règlement du lotissement", "Document permanent", "PDF · 2,4 Mo", "12 janvier 2026"],
    ["Statuts de l’ASL", "Document permanent", "PDF · 1,1 Mo", "12 janvier 2026"],
  ];
  return (
    <>
      <SectionHeading eyebrow="Assemblées & archives" title="AG et documents" text="Préparez les prochaines assemblées et consultez les archives officielles de l’ASL." />
      <section className="meeting-hero">
        <div className="meeting-date"><span>OCT</span><strong>10</strong><small>2026</small></div><div className="meeting-copy"><span>Prochaine assemblée générale ordinaire</span><h2>Votre rendez-vous annuel</h2><p><Icon name="clock" size={15}/> Samedi 10 octobre à 18 h 30 · Salle La Coupole, La Gaude</p><div><button onClick={() => notify("Votre présence à l’AG a bien été enregistrée.")}><Icon name="check" size={16}/> Je serai présent</button><button onClick={() => notify("Le formulaire de pouvoir a été préparé.")}>Donner pouvoir</button></div></div><aside><span>Votre réponse</span><strong>En attente</strong><small>Répondre avant le 3 octobre</small></aside>
      </section>
      <div className="meeting-layout">
        <section className="standard-panel agenda-detail"><div className="standard-panel-head"><div><span>Ordre du jour</span><h2>AG du 10 octobre 2026</h2></div><button onClick={() => openDocument("Convocation à l’AG 2026")}><Icon name="eye" size={16}/> Voir la convocation</button></div>{["Approbation du procès-verbal 2025", "Rapport moral et rapport financier", "Vote du budget prévisionnel 2027", "Travaux d’éclairage et entretien des voies", "Questions diverses des colotis"].map((item, i) => <div className="agenda-item" key={item}><span>{String(i+1).padStart(2,"0")}</span><p>{item}</p>{i < 3 && <small>Vote</small>}</div>)}</section>
        <aside className="standard-panel ask-panel"><div className="ask-icon"><Icon name="mail" size={22}/></div><span>Une question pour l’AG ?</span><h3>Proposez un point à l’ordre du jour</h3><p>Envoyez votre demande au bureau avant le 20 septembre.</p><button onClick={() => notify("Le formulaire de question à l’AG est ouvert.")}>Poser ma question <Icon name="arrow" size={15}/></button></aside>
      </div>
      <section className="standard-panel document-library"><div className="standard-panel-head"><div><span>Bibliothèque</span><h2>Documents de l’ASL</h2></div><div className="doc-filters"><button className="active">Tous</button><button>2026</button><button>2025</button></div></div><div className="document-list">{docs.map(([title,type,size,date]) => <article key={title}><span className="pdf-icon">PDF</span><p><strong>{title}</strong><small>{type} · Ajouté le {date}</small></p><span>{size}</span><button onClick={() => openDocument(title)}><Icon name="eye" size={16}/> Consulter</button><button aria-label={`Télécharger ${title}`} onClick={() => notify(`Le document « ${title} » est prêt à être téléchargé.`)}><Icon name="download" size={17}/></button></article>)}</div></section>
    </>
  );
}

function AlertsView({ notify, openAlert }: { notify: Notify; openAlert: () => void }) {
  return (
    <>
      <SectionHeading eyebrow="Vigilance collective" title="Alertes de voisinage" text="Un canal responsable pour signaler rapidement les faits inhabituels au bureau." action={<button className="primary-action inline-action" onClick={openAlert}><Icon name="plus" size={18}/> Nouveau signalement</button>} />
      <section className="safety-rule"><div><Icon name="shield" size={25}/></div><p><strong>En cas de danger immédiat, appelez le 17.</strong><span>Ce portail ne remplace jamais les services d’urgence. Évitez les noms, visages et plaques d’immatriculation dans les messages publics.</span></p><button onClick={() => notify("Les règles de bon usage sont ouvertes.")}>Règles de bon usage</button></section>
      <div className="alerts-layout">
        <section className="standard-panel alert-feed"><div className="standard-panel-head"><div><span>En cours</span><h2>Dernières informations de vigilance</h2></div><span className="live-pill"><i/> 2 actives</span></div>
          <article className="alert-card important"><div className="alert-card-top"><span><Icon name="shield" size={18}/> Vigilance renforcée</span><time>Hier · 22 h 15</time></div><h3>Véhicule inhabituel avenue des Lauriers</h3><p>Deux signalements concordants ont été transmis au bureau. Les vérifications sont en cours.</p><div><span>Avenue des Lauriers</span><b>Suivi par le bureau</b></div></article>
          <article className="alert-card resolved"><div className="alert-card-top"><span><Icon name="check" size={18}/> Information vérifiée</span><time>8 août · 10 h 40</time></div><h3>Intervention technique avenue des Mimosas</h3><p>Le véhicule signalé appartenait à l’entreprise missionnée pour le contrôle de l’éclairage.</p><div><span>Avenue des Mimosas</span><b>Clôturé</b></div></article>
        </section>
        <aside className="avenue-status"><span>Le lotissement aujourd’hui</span><h2>Activité par avenue</h2>{[["Mimosas","Aucun incident","36 lots"],["Lauriers","Vigilance en cours","41 lots"],["Oliviers","Aucun incident","36 lots"]].map(([name,status,count],i)=><div key={name}><i className={i===1?"warn":"ok"}/><p><strong>Avenue des {name}</strong><small>{status}</small></p><span>{count}</span></div>)}<button onClick={() => notify("Le récapitulatif de vigilance a été actualisé.")}><Icon name="bell" size={16}/> Gérer mes alertes</button></aside>
      </div>
      <section className="good-practices"><div><span>01</span><p><strong>Observez sans intervenir</strong><small>Gardez vos distances et relevez uniquement les faits utiles.</small></p></div><div><span>02</span><p><strong>Prévenez les bons interlocuteurs</strong><small>Police ou gendarmerie d’abord si la situation est urgente.</small></p></div><div><span>03</span><p><strong>Informez avec mesure</strong><small>Un message factuel évite les rumeurs et protège chacun.</small></p></div></section>
    </>
  );
}

function CommunityView({ notify }: { notify: Notify }) {
  function submitContact(event: FormEvent<HTMLFormElement>) { event.preventDefault(); notify("Votre message a été transmis au bureau de l’ASL."); (event.currentTarget as HTMLFormElement).reset(); }
  return (
    <>
      <SectionHeading eyebrow="Contacts & cadre de vie" title="Vie du lotissement" text="Retrouvez le bureau, les trois avenues et les contacts utiles du quotidien." />
      <section className="community-hero"><div><span>ASL Le Plan du Bois</span><h2>Un lotissement à taille humaine au cœur de La Gaude</h2><p>113 colotis réunis autour de trois avenues arborées et d’un cadre de vie partagé.</p></div><div className="roads-visual"><i/><i/><i/><span>113<small>lots</small></span></div></section>
      <div className="community-grid">
        <section className="standard-panel bureau-team"><div className="standard-panel-head"><div><span>Votre association</span><h2>Le bureau de l’ASL</h2></div></div>{[["PR","Présidence","Coordination générale"],["TR","Trésorerie","Cotisations et comptes"],["SE","Secrétariat","AG et documents"]].map(([initials,role,desc])=><div key={role}><span>{initials}</span><p><strong>{role}</strong><small>{desc}</small></p><button onClick={() => notify(`Votre message sera adressé à la ${role.toLowerCase()}.`)}><Icon name="mail" size={16}/></button></div>)}<p className="privacy-note">Les coordonnées nominatives seront visibles uniquement par les colotis connectés après la mise en service.</p></section>
        <section className="standard-panel contact-panel"><div className="standard-panel-head"><div><span>Nous écrire</span><h2>Contacter le bureau</h2></div></div><form onSubmit={submitContact}><div className="field-row"><label>Objet<select><option>Question générale</option><option>Cotisation</option><option>Voirie et entretien</option><option>Assemblée générale</option></select></label><label>Avenue<select><option>Les Oliviers</option><option>Les Mimosas</option><option>Les Lauriers</option></select></label></div><label>Votre message<textarea required placeholder="Écrivez votre demande…"/></label><button type="submit">Envoyer mon message <Icon name="send" size={16}/></button></form></section>
      </div>
      <section className="avenue-cards">{[["Mimosas","36","#d7aa3d"],["Lauriers","41","#457d64"],["Oliviers","36","#7c8d4f"]].map(([name,count,color])=><article key={name} style={{"--avenue-color":color} as React.CSSProperties}><div className="avenue-symbol"><i/><i/><i/></div><span>Avenue des</span><h3>{name}</h3><p><strong>{count}</strong> lots</p></article>)}</section>
      <section className="useful-contacts"><div><span>Contacts utiles</span><h2>À garder sous la main</h2></div><button onClick={() => notify("Composez le 17 en cas d’urgence immédiate.")}><b>17</b><span>Police secours</span></button><button onClick={() => notify("Composez le 18 en cas d’incendie ou de secours.")}><b>18</b><span>Sapeurs-pompiers</span></button><button onClick={() => notify("La fiche de contact de la mairie est ouverte.")}><Icon name="home" size={20}/><span>Mairie de La Gaude</span></button></section>
    </>
  );
}

function LoginScreen({ signInPath, onDemo }: { signInPath: string; onDemo: (role: "resident" | "bureau") => void }) {
  return (
    <main className="login-screen">
      <section className="login-brand-panel">
        <div className="login-brand"><div className="brand-mark"><span>LPB</span><i /></div><div><strong>ASL Le Plan du Bois</strong><small>La Gaude · 113 colotis</small></div></div>
        <div className="login-message"><span>Espace privé du lotissement</span><h1>Tout Le Plan du Bois,<br/>dans un seul espace.</h1><p>Cotisations, assemblées générales, documents, informations du bureau et alertes de voisinage.</p></div>
        <div className="login-avenues"><span>Mimosas</span><span>Lauriers</span><span>Oliviers</span></div>
        <div className="login-roads" aria-hidden="true"><i/><i/><i/></div>
      </section>
      <section className="login-form-panel">
        <div className="login-box">
          <span className="login-kicker">Accès sécurisé</span><h2>Bienvenue dans votre lotissement</h2><p>Connectez-vous avec l’adresse e-mail enregistrée sur votre fiche coloti.</p>
          <a className="login-main-button" href={signInPath}><Icon name="shield" size={19}/> Se connecter à mon espace <Icon name="arrow" size={17}/></a>
          <div className="login-separator"><span>Tester avant l’ouverture</span></div>
          <div className="demo-buttons"><button onClick={() => onDemo("resident")}><Icon name="users" size={18}/><span><strong>Démo coloti</strong><small>Consulter mon espace</small></span></button><button onClick={() => onDemo("bureau")}><Icon name="settings" size={18}/><span><strong>Démo bureau</strong><small>Gérer l’association</small></span></button></div>
          <div className="login-help"><Icon name="mail" size={17}/><p><strong>Première connexion ?</strong><span>Le bureau doit d’abord créer votre fiche avec votre adresse e-mail.</span></p></div>
        </div>
        <p className="login-privacy"><Icon name="shield" size={14}/> Accès nominatif · Données réservées à l’ASL</p>
      </section>
    </main>
  );
}

function PendingAccessScreen({ user, signOutPath }: { user: AuthUser; signOutPath: string }) {
  return <main className="pending-screen"><div className="pending-card"><div className="brand-mark"><span>LPB</span><i/></div><span>Compte identifié</span><h1>Votre fiche doit être rattachée</h1><p>L’adresse <strong>{user.email}</strong> n’est pas encore associée à un lot du Plan du Bois. Demandez au bureau de créer ou d’activer votre fiche coloti.</p><a href={signOutPath}>Utiliser une autre adresse</a></div></main>;
}

function ProfileView({ profile, notify }: { profile: PortalProfile; notify: Notify }) {
  const label = profile.role === "bureau" ? "Membre du bureau" : "Coloti";
  return <><SectionHeading eyebrow="Compte personnel" title="Ma fiche coloti" text="Les informations qui permettent au bureau d’identifier votre lot et de vous adresser les communications utiles."/><section className="profile-hero"><div className="profile-large-avatar">{profile.firstName.slice(0,1)}{profile.lastName.slice(0,1)}</div><div><span>{label} · Compte {profile.accessStatus === "active" ? "actif" : profile.accessStatus}</span><h2>{profile.firstName} {profile.lastName}</h2><p>{profile.addressNumber ? `${profile.addressNumber} ` : ""}{profile.avenue}</p></div><b>{profile.lotReference}</b></section><div className="profile-layout"><section className="standard-panel profile-details"><div className="standard-panel-head"><div><span>Coordonnées</span><h2>Informations de la fiche</h2></div><button onClick={() => notify("La demande de modification a été transmise au bureau.")}><Icon name="mail" size={15}/> Demander une modification</button></div><dl><div><dt>Adresse e-mail de connexion</dt><dd>{profile.email}</dd></div><div><dt>Téléphone</dt><dd>{profile.phone || "À compléter"}</dd></div><div><dt>Référence du lot</dt><dd>{profile.lotReference}</dd></div><div><dt>Avenue</dt><dd>{profile.avenue}</dd></div><div><dt>Numéro dans l’avenue</dt><dd>{profile.addressNumber || "À compléter"}</dd></div><div><dt>Niveau d’accès</dt><dd>{label}</dd></div></dl></section><aside className="standard-panel profile-security"><div className="standard-panel-head"><div><span>Sécurité</span><h2>Accès au portail</h2></div></div><div className="security-check"><Icon name="check" size={22}/><p><strong>Adresse vérifiée</strong><small>Connexion nominative activée</small></p></div><div className="security-check"><Icon name="shield" size={22}/><p><strong>Données protégées</strong><small>Accès limité selon votre rôle</small></p></div><button onClick={() => notify("L’historique des connexions sera disponible à la mise en service.")}>Voir l’activité du compte</button></aside></div></>;
}

function ResidentSection({ section, notify, openAlert, openPayment, openDocument, profile, liveData }: { section: string; notify: Notify; openAlert: () => void; openPayment: () => void; openDocument: (title: string) => void; profile: PortalProfile; liveData: boolean }) {
  if (section === "actualites") return <NewsView notify={notify}/>;
  if (section === "cotisations") return <DuesView notify={notify} openPayment={openPayment} liveData={liveData} profile={profile}/>;
  if (section === "ag") return <MeetingsView notify={notify} openDocument={openDocument}/>;
  if (section === "voisinage") return <AlertsView notify={notify} openAlert={openAlert}/>;
  if (section === "profil") return <ProfileView profile={profile} notify={notify}/>;
  return <CommunityView notify={notify}/>;
}

function BureauView({ section, notify, openCompose, openDocument, liveData }: { section: string; notify: Notify; openCompose: () => void; openDocument: (title: string) => void; liveData: boolean }) {
  const heading: Record<string,[string,string]> = {
    overview: ["Pilotage du lotissement", "Suivez les cotisations, publications, documents et signalements en un coup d’œil."],
    dues: ["Suivi des cotisations", "Visualisez l’avancement des règlements et relancez les comptes en attente."],
    publications: ["Informations du bureau", "Rédigez et planifiez les communications destinées aux colotis."],
    documents: ["Documents et assemblées", "Centralisez les convocations, procès-verbaux, comptes et règlements."],
    alerts: ["Gestion des signalements", "Qualifiez les alertes reçues et informez les avenues concernées."],
    residents: ["Gestion des colotis", "Suivez les accès et la répartition des 113 lots par avenue."],
  };
  const [title,text] = heading[section] ?? heading.overview;
  return (
    <>
      <SectionHeading eyebrow="Espace réservé au bureau" title={title} text={text} action={<button className="primary-action inline-action" onClick={section === "documents" ? () => notify("Le sélecteur de document est prêt pour la publication.") : openCompose}><Icon name={section === "documents" ? "upload" : "plus"} size={18}/> {section === "documents" ? "Publier un document" : "Nouvelle information"}</button>} />
      {section === "overview" && <BureauOverview notify={notify} openCompose={openCompose}/>} 
      {section === "dues" && <BureauDues notify={notify} liveData={liveData}/>} 
      {section === "publications" && <BureauPublications notify={notify} openCompose={openCompose}/>} 
      {section === "documents" && <BureauDocuments notify={notify} openDocument={openDocument}/>} 
      {section === "alerts" && <BureauAlerts notify={notify}/>} 
      {section === "residents" && <BureauResidents notify={notify} liveData={liveData}/>} 
    </>
  );
}

function BureauOverview({ notify, openCompose }: { notify: Notify; openCompose: () => void }) {
  return <><section className="admin-stats"><article><span className="soft-icon"><Icon name="users" size={21}/></span><div><small>Lots enregistrés</small><strong>113</strong><p>100 % des lots</p></div></article><article><span className="soft-icon"><Icon name="wallet" size={21}/></span><div><small>Cotisations réglées</small><strong>94</strong><p className="positive">+12 cette semaine</p></div></article><article><span className="soft-icon"><Icon name="clock" size={21}/></span><div><small>En attente</small><strong>12</strong><p>Avant le 30 septembre</p></div></article><article><span className="soft-icon alert"><Icon name="shield" size={21}/></span><div><small>Retards antérieurs</small><strong>7</strong><p className="negative">Relance conseillée</p></div></article></section><div className="admin-grid"><section className="standard-panel collection-panel"><div className="standard-panel-head"><div><span>Cotisations 2026</span><h2>État des règlements</h2></div><b>83 % collectés</b></div><div className="collection-body"><div className="donut"><div><strong>94</strong><span>réglées</span></div></div><div className="collection-legend"><p><i className="paid"/><span>Réglées</span><b>94</b></p><p><i className="pending"/><span>En attente</span><b>12</b></p><p><i className="late"/><span>En retard</span><b>7</b></p></div></div><button onClick={() => notify("Le suivi détaillé des cotisations est ouvert.")}>Voir le suivi complet <Icon name="arrow" size={16}/></button></section><section className="standard-panel admin-actions"><div className="standard-panel-head"><div><span>Actions rapides</span><h2>Gérer l’ASL</h2></div></div><button onClick={openCompose}><span><Icon name="news" size={18}/></span><p><strong>Publier une information</strong><small>Informer tous les colotis ou une avenue</small></p><Icon name="chevron" size={17}/></button><button onClick={() => notify("Le rappel groupé est prêt à être configuré.")}><span><Icon name="bell" size={18}/></span><p><strong>Envoyer un rappel</strong><small>Cotisations, AG ou entretien</small></p><Icon name="chevron" size={17}/></button><button onClick={() => notify("L’espace de publication des documents est ouvert.")}><span><Icon name="upload" size={18}/></span><p><strong>Ajouter un document</strong><small>PV, comptes, convocation ou règlement</small></p><Icon name="chevron" size={17}/></button></section></div><section className="standard-panel recent-admin"><div className="standard-panel-head"><div><span>Derniers mouvements</span><h2>Activité récente</h2></div><button>Tout voir</button></div>{[["check","Cotisation enregistrée","Lot OLI-027 · 320 €","Il y a 12 min"],["shield","Nouveau signalement","Avenue des Lauriers","Il y a 1 h"],["folder","Document publié","Comptes annuels 2025","Hier, 16 h 42"],["news","Information envoyée","113 destinataires","Hier, 10 h 15"]].map(([icon,title,sub,time])=><div key={title+sub}><span><Icon name={icon as IconName} size={17}/></span><p><strong>{title}</strong><small>{sub}</small></p><time>{time}</time></div>)}</section></>;
}

function BureauDues({ notify, liveData }: { notify: Notify; liveData: boolean }) {
  const demoRows: DueRecord[] = [
    { id: 1, memberId: 18, year: 2026, amountCents: 32000, paidAmountCents: 0, dueDate: "2026-09-30", status: "pending", paymentMethod: null, paymentReference: null, paidAt: null, notes: "", lotReference: "LAU-018", firstName: "Élodie", lastName: "Martin", avenue: "Avenue des Lauriers", email: "e.martin@exemple.fr" },
    { id: 2, memberId: 6, year: 2026, amountCents: 32000, paidAmountCents: 32000, dueDate: "2026-09-30", status: "paid", paymentMethod: "Virement", paymentReference: "VIR-0808", paidAt: "2026-08-08", notes: "", lotReference: "MIM-006", firstName: "Laurent", lastName: "Bernard", avenue: "Avenue des Mimosas", email: "l.bernard@exemple.fr" },
    { id: 3, memberId: 31, year: 2026, amountCents: 32000, paidAmountCents: 15000, dueDate: "2026-09-30", status: "partial", paymentMethod: "Chèque", paymentReference: "CHQ-1842", paidAt: "2026-08-02", notes: "Solde à percevoir", lotReference: "OLI-031", firstName: "Sophie", lastName: "Roux", avenue: "Avenue des Oliviers", email: "s.roux@exemple.fr" },
    { id: 4, memberId: 39, year: 2026, amountCents: 32000, paidAmountCents: 0, dueDate: "2026-09-30", status: "pending", paymentMethod: null, paymentReference: null, paidAt: null, notes: "", lotReference: "LAU-039", firstName: "Marc", lastName: "Petit", avenue: "Avenue des Lauriers", email: "m.petit@exemple.fr" },
  ];
  const defaultRules: ReminderRuleRecord[] = [
    { id: 1, label: "Rappel 30 jours avant", enabled: true, triggerType: "before_due", daysOffset: 30, channel: "in_app", audience: "unpaid" },
    { id: 2, label: "Rappel 7 jours avant", enabled: true, triggerType: "before_due", daysOffset: 7, channel: "in_app", audience: "unpaid" },
    { id: 3, label: "Relance 7 jours après", enabled: true, triggerType: "after_due", daysOffset: 7, channel: "in_app", audience: "overdue" },
    { id: 4, label: "Relance e-mail après échéance", enabled: false, triggerType: "after_due", daysOffset: 7, channel: "email", audience: "overdue" },
  ];
  const [rows, setRows] = useState<DueRecord[]>(demoRows);
  const [rules, setRules] = useState<ReminderRuleRecord[]>(defaultRules);
  const [selectedDue, setSelectedDue] = useState<DueRecord | null>(null);
  const [search, setSearch] = useState("");
  const [loading, setLoading] = useState(liveData);

  useEffect(() => {
    if (!liveData) return;
    Promise.all([fetch("/api/dues").then((r) => r.json()), fetch("/api/reminders").then((r) => r.json())])
      .then(([dueData, reminderData]) => {
        if (Array.isArray(dueData.dues)) setRows(dueData.dues);
        if (Array.isArray(reminderData.rules)) setRules(reminderData.rules);
      })
      .catch(() => {})
      .finally(() => setLoading(false));
  }, [liveData]);

  const total = rows.reduce((sum, row) => sum + row.amountCents, 0);
  const collected = rows.reduce((sum, row) => sum + row.paidAmountCents, 0);
  const remaining = Math.max(0, total - collected);
  const filtered = rows.filter((row) => `${row.lotReference} ${row.firstName} ${row.lastName} ${row.avenue}`.toLowerCase().includes(search.toLowerCase()));
  const euros = (cents: number) => new Intl.NumberFormat("fr-FR", { style: "currency", currency: "EUR", maximumFractionDigits: 0 }).format(cents / 100);
  const statusLabel = (status: DueRecord["status"]) => status === "paid" ? "Réglée" : status === "partial" ? "Partielle" : status === "overdue" ? "En retard" : "En attente";

  async function recordPayment(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!selectedDue) return;
    const form = new FormData(event.currentTarget);
    const payload = { id: selectedDue.id, paidAmountCents: Math.round(Number(form.get("amount")) * 100), paymentMethod: String(form.get("method") ?? ""), paymentReference: String(form.get("reference") ?? ""), paidAt: String(form.get("date") ?? ""), notes: String(form.get("notes") ?? "") };
    try {
      if (liveData) {
        const response = await fetch("/api/dues", { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) });
        const data = await response.json();
        if (!response.ok) throw new Error(data.error || "Erreur de pointage");
        setRows((current) => current.map((row) => row.id === selectedDue.id ? { ...row, ...data.due } : row));
      } else {
        const status = payload.paidAmountCents >= selectedDue.amountCents ? "paid" : payload.paidAmountCents > 0 ? "partial" : "pending";
        setRows((current) => current.map((row) => row.id === selectedDue.id ? { ...row, ...payload, status, paymentReference: payload.paymentReference, paymentMethod: payload.paymentMethod, paidAt: payload.paidAt } as DueRecord : row));
      }
      setSelectedDue(null);
      notify(`Le règlement du lot ${selectedDue.lotReference} a été pointé.`);
    } catch (error) {
      notify(error instanceof Error ? error.message : "Impossible d’enregistrer ce règlement.");
    }
  }

  async function toggleRule(rule: ReminderRuleRecord) {
    const enabled = !rule.enabled;
    if (rule.channel === "email" && enabled && !liveData) {
      notify("L’envoi e-mail sera activé après le choix du service d’expédition.");
      return;
    }
    try {
      if (liveData) {
        const response = await fetch("/api/reminders", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "toggle", id: rule.id, enabled }) });
        const data = await response.json();
        if (!response.ok) throw new Error(data.error || "Erreur de configuration");
      }
      setRules((current) => current.map((item) => item.id === rule.id ? { ...item, enabled } : item));
      notify(`La règle « ${rule.label} » est ${enabled ? "activée" : "désactivée"}.`);
    } catch (error) { notify(error instanceof Error ? error.message : "Impossible de modifier cette règle."); }
  }

  async function runReminders() {
    try {
      if (liveData) {
        const response = await fetch("/api/reminders", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "run" }) });
        const data = await response.json();
        if (!response.ok) throw new Error(data.error || "Erreur de relance");
        notify(`${data.generated} nouvelle(s) relance(s) ont été générée(s).`);
      } else notify("Simulation terminée : 2 rappels dans l’espace coloti et 1 relance à préparer.");
    } catch (error) { notify(error instanceof Error ? error.message : "Impossible de lancer les relances."); }
  }

  return <>
    <section className="admin-stats compact"><article><span className="soft-icon"><Icon name="wallet" size={21}/></span><div><small>Montant appelé</small><strong>{euros(total)}</strong><p>Exercice 2026</p></div></article><article><span className="soft-icon"><Icon name="check" size={21}/></span><div><small>Déjà encaissé</small><strong>{euros(collected)}</strong><p className="positive">{total ? Math.round(collected / total * 100) : 0} % collectés</p></div></article><article><span className="soft-icon alert"><Icon name="clock" size={21}/></span><div><small>Reste à percevoir</small><strong>{euros(remaining)}</strong><p>{rows.filter((row) => row.status !== "paid").length} compte(s)</p></div></article></section>
    <section className="standard-panel admin-table-panel"><div className="standard-panel-head"><div><span>Registre financier</span><h2>Pointage des règlements</h2></div><div className="table-actions"><label><Icon name="search" size={15}/><input value={search} onChange={(e) => setSearch(e.target.value)} placeholder="Lot ou coloti…"/></label><button onClick={runReminders}><Icon name="bell" size={15}/> Générer les relances</button></div></div><div className="admin-table dues-admin-table"><div className="admin-table-row header"><span>Lot / coloti</span><span>Montant</span><span>Réglé</span><span>Mode</span><span>Statut</span><span>Action</span></div>{loading ? <div className="table-loading">Chargement de la base…</div> : filtered.map((row)=><div className="admin-table-row" key={row.id}><span><b>{row.lotReference}</b><small>{row.firstName} {row.lastName}</small></span><span>{euros(row.amountCents)}</span><span>{euros(row.paidAmountCents)}</span><span>{row.paymentMethod || "—"}</span><span className={`table-status ${row.status === "paid" ? "paid" : row.status === "partial" ? "partial" : row.status === "overdue" ? "late" : "pending"}`}>{statusLabel(row.status)}</span><button className="record-button" onClick={() => setSelectedDue(row)}>{row.status === "paid" ? "Modifier" : "Pointer"}</button></div>)}</div></section>
    <section className="standard-panel reminder-config"><div className="standard-panel-head"><div><span>Automatisation</span><h2>Scénario de relance des cotisations</h2></div><b>{rules.filter((rule) => rule.enabled).length} règle(s) active(s)</b></div><div className="reminder-rule-grid">{rules.map((rule) => <article key={rule.id}><span className={`reminder-channel ${rule.channel}`}><Icon name={rule.channel === "email" ? "mail" : "bell"} size={18}/></span><p><strong>{rule.label}</strong><small>{rule.channel === "email" ? "E-mail automatique" : "Notification dans le portail"}</small></p>{rule.channel === "email" && <em>Service d’envoi à raccorder</em>}<button className={rule.enabled ? "toggle active" : "toggle"} aria-label={`${rule.enabled ? "Désactiver" : "Activer"} ${rule.label}`} onClick={() => toggleRule(rule)}><i/></button></article>)}</div><p className="reminder-note"><Icon name="settings" size={15}/> Les notifications internes sont générées automatiquement selon l’échéance. Pour les e-mails, il faudra choisir et raccorder un service d’expédition.</p></section>
    {selectedDue && <div className="modal-backdrop" role="presentation" onMouseDown={(e) => { if (e.target === e.currentTarget) setSelectedDue(null); }}><section className="modal record-payment-modal" role="dialog" aria-modal="true" aria-labelledby="record-payment-title"><button className="modal-close" aria-label="Fermer" onClick={() => setSelectedDue(null)}><Icon name="close" size={20}/></button><div className="modal-icon green"><Icon name="wallet" size={24}/></div><span className="modal-kicker green">Lot {selectedDue.lotReference}</span><h2 id="record-payment-title">Pointer un règlement</h2><p>{selectedDue.firstName} {selectedDue.lastName} · Cotisation {selectedDue.year} de {euros(selectedDue.amountCents)}</p><form onSubmit={recordPayment}><div className="field-row"><label>Montant reçu (€)<input name="amount" type="number" min="0" step="0.01" required defaultValue={(selectedDue.paidAmountCents / 100).toFixed(2)}/></label><label>Mode de règlement<select name="method" required defaultValue={selectedDue.paymentMethod || "Virement"}><option>Virement</option><option>Chèque</option><option>Carte bancaire</option><option>Espèces</option><option>Prélèvement</option><option>Autre</option></select></label></div><div className="field-row"><label>Date de réception<input name="date" type="date" required defaultValue={selectedDue.paidAt?.slice(0,10) || new Date().toISOString().slice(0,10)}/></label><label>Référence<input name="reference" placeholder="N° de chèque ou référence" defaultValue={selectedDue.paymentReference || ""}/></label></div><label>Note interne<textarea name="notes" placeholder="Observation facultative…" defaultValue={selectedDue.notes}/></label><div className="modal-actions"><button type="button" onClick={() => setSelectedDue(null)}>Annuler</button><button type="submit">Enregistrer le règlement <Icon name="check" size={17}/></button></div></form></section></div>}
  </>;
}

function BureauPublications({ notify, openCompose }: { notify: Notify; openCompose: () => void }) {
  const rows=[["Débroussaillage : rappel avant le 15 septembre","Entretien","113 destinataires","Publié · 9 août"],["Intervention sur l’éclairage des Mimosas","Travaux","36 destinataires","Publié · 7 août"],["Convocation à l’assemblée générale 2026","Assemblée générale","113 destinataires","Planifié · 20 août"],["Bienvenue aux nouveaux propriétaires","Vie du lotissement","113 destinataires","Publié · 4 août"]];
  return <><section className="publication-toolbar"><div><button className="active">Toutes <span>12</span></button><button>Publiées <span>9</span></button><button>Planifiées <span>2</span></button><button>Brouillons <span>1</span></button></div><button onClick={openCompose}><Icon name="plus" size={16}/> Rédiger une information</button></section><section className="standard-panel publication-list">{rows.map(([title,type,audience,status],i)=><article key={title}><span className={`publication-type p${i}`}><Icon name={i===0?"leaf":i===1?"settings":i===2?"calendar":"users"} size={20}/></span><p><strong>{title}</strong><small>{type} · {audience}</small></p><b className={status.startsWith("Planifié")?"planned":"published"}>{status}</b><button onClick={() => notify(`Les statistiques de lecture de « ${title} » sont ouvertes.`)}><Icon name="eye" size={16}/></button><button><Icon name="more" size={17}/></button></article>)}</section></>;
}

function BureauDocuments({ notify, openDocument }: { notify: Notify; openDocument: (title:string)=>void }) {
  const docs=[["Procès-verbal de l’AG 2025","PV d’AG","2025","Consulté 87 fois"],["Comptes annuels 2025","Comptabilité","2025","Consulté 62 fois"],["Budget prévisionnel 2026","Comptabilité","2026","Consulté 54 fois"],["Convocation AG 2026","Convocation","2026","Publication planifiée"],["Règlement du lotissement","Permanent","—","Consulté 103 fois"]];
  return <><section className="document-admin-summary"><div><Icon name="folder" size={25}/><p><strong>24 documents</strong><span>dans la bibliothèque</span></p></div><div><Icon name="eye" size={25}/><p><strong>412 consultations</strong><span>depuis janvier</span></p></div><div><Icon name="calendar" size={25}/><p><strong>1 document</strong><span>planifié</span></p></div></section><section className="standard-panel document-library admin-docs"><div className="standard-panel-head"><div><span>Bibliothèque officielle</span><h2>Documents publiés</h2></div><div className="doc-filters"><button className="active">Tous</button><button>AG</button><button>Comptes</button><button>Statuts</button></div></div><div className="document-list">{docs.map(([title,type,year,views])=><article key={title}><span className="pdf-icon">PDF</span><p><strong>{title}</strong><small>{type} · Exercice {year}</small></p><span>{views}</span><button onClick={()=>openDocument(title)}><Icon name="eye" size={16}/> Consulter</button><button aria-label={`Options ${title}`} onClick={()=>notify(`Les options du document « ${title} » sont ouvertes.`)}><Icon name="more" size={17}/></button></article>)}</div></section></>;
}

function BureauAlerts({ notify }: { notify: Notify }) {
  return <><section className="alert-admin-summary"><article className="current"><span>2</span><p><strong>À examiner</strong><small>Signalements récents</small></p></article><article><span>1</span><p><strong>En cours de suivi</strong><small>Information transmise</small></p></article><article><span>18</span><p><strong>Clôturés</strong><small>Depuis janvier 2026</small></p></article></section><section className="standard-panel admin-alert-list"><div className="standard-panel-head"><div><span>File de traitement</span><h2>Signalements reçus</h2></div><button>Historique</button></div>{[["Véhicule inhabituel","Avenue des Lauriers · Hier 22 h 15","2 signalements liés","Nouveau"],["Éclairage défectueux","Avenue des Mimosas · Hier 19 h 40","Candélabre n° 6","En cours"],["Branche sur la chaussée","Avenue des Oliviers · 8 août 9 h 20","Intervention terminée","Clôturé"]].map(([title,meta,detail,status],i)=><article key={title}><span className={`alert-priority a${i}`}><Icon name={i===2?"check":"shield"} size={20}/></span><p><strong>{title}</strong><small>{meta}</small></p><span>{detail}</span><b className={`alert-status s${i}`}>{status}</b><button onClick={()=>notify(`Le signalement « ${title} » est ouvert pour traitement.`)}>Traiter <Icon name="chevron" size={15}/></button></article>)}</section></>;
}

function BureauResidents({ notify, liveData }: { notify: Notify; liveData: boolean }) {
  const samples: PortalProfile[] = [
    demoBureau,
    demoResident,
    { ...demoResident, id: 16, lotReference: "MIM-016", firstName: "Claire", lastName: "Dubois", email: "c.dubois@exemple.fr", avenue: "Avenue des Mimosas", addressNumber: "16" },
    { ...demoResident, id: 33, lotReference: "LAU-033", firstName: "Julien", lastName: "Morel", email: "j.morel@exemple.fr", avenue: "Avenue des Lauriers", addressNumber: "33", accessStatus: "invited" },
    { ...demoResident, id: 8, lotReference: "OLI-008", firstName: "Nathalie", lastName: "Garnier", email: "n.garnier@exemple.fr", avenue: "Avenue des Oliviers", addressNumber: "8" },
  ];
  const [memberRows, setMemberRows] = useState<PortalProfile[]>(samples);
  const [createOpen, setCreateOpen] = useState(false);
  const [selected, setSelected] = useState<PortalProfile | null>(null);
  const [search, setSearch] = useState("");
  const [loading, setLoading] = useState(liveData);

  useEffect(() => {
    if (!liveData) return;
    fetch("/api/members").then((response) => response.json()).then((data) => {
      if (Array.isArray(data.members)) setMemberRows(data.members);
    }).catch(() => {}).finally(() => setLoading(false));
  }, [liveData]);

  const residentsOnly = memberRows.filter((member) => member.role === "resident");
  const avenueCounts = liveData ? [
    ["Mimosas", residentsOnly.filter((member) => member.avenue.includes("Mimosas")).length, "#cba048"],
    ["Lauriers", residentsOnly.filter((member) => member.avenue.includes("Lauriers")).length, "#3f7763"],
    ["Oliviers", residentsOnly.filter((member) => member.avenue.includes("Oliviers")).length, "#809253"],
  ] : [["Mimosas",36,"#cba048"],["Lauriers",41,"#3f7763"],["Oliviers",36,"#809253"]];
  const filtered = memberRows.filter((member) => `${member.lotReference} ${member.firstName} ${member.lastName} ${member.avenue}`.toLowerCase().includes(search.toLowerCase()));

  async function createMember(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const form = new FormData(event.currentTarget);
    const payload = {
      lotReference: String(form.get("lotReference") ?? ""), firstName: String(form.get("firstName") ?? ""), lastName: String(form.get("lastName") ?? ""), email: String(form.get("email") ?? ""), phone: String(form.get("phone") ?? ""), avenue: String(form.get("avenue") ?? ""), addressNumber: String(form.get("addressNumber") ?? ""), role: String(form.get("role") ?? "resident"), accessStatus: String(form.get("accessStatus") ?? "invited"), amountCents: Math.round(Number(form.get("amount")) * 100), notes: String(form.get("notes") ?? ""),
    };
    try {
      let member: PortalProfile;
      if (liveData) {
        const response = await fetch("/api/members", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) });
        const data = await response.json();
        if (!response.ok) throw new Error(data.error || "Impossible de créer la fiche");
        member = data.member;
      } else {
        member = { id: Date.now(), lotReference: payload.lotReference.toUpperCase(), firstName: payload.firstName, lastName: payload.lastName, email: payload.email, phone: payload.phone, avenue: payload.avenue, addressNumber: payload.addressNumber, role: payload.role === "bureau" ? "bureau" : "resident", accessStatus: payload.accessStatus === "active" ? "active" : "invited", notes: payload.notes, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() };
      }
      setMemberRows((current) => [...current, member]);
      setCreateOpen(false);
      notify(`La fiche ${member.lotReference} a été créée${member.accessStatus === "invited" ? " et l’invitation est prête" : ""}.`);
    } catch (error) { notify(error instanceof Error ? error.message : "Impossible de créer cette fiche."); }
  }

  async function changeAccess(member: PortalProfile, status: "active" | "suspended") {
    try {
      if (liveData) {
        const response = await fetch("/api/members", { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: member.id, accessStatus: status }) });
        const data = await response.json();
        if (!response.ok) throw new Error(data.error || "Impossible de modifier l’accès");
      }
      const updated = { ...member, accessStatus: status };
      setMemberRows((current) => current.map((item) => item.id === member.id ? updated : item));
      setSelected(updated);
      notify(`L’accès du lot ${member.lotReference} est maintenant ${status === "active" ? "actif" : "suspendu"}.`);
    } catch (error) { notify(error instanceof Error ? error.message : "Impossible de modifier cet accès."); }
  }

  return <>
    <section className="resident-distribution"><div className="distribution-copy"><span>Base des colotis</span><h2>{liveData ? `${residentsOnly.length} / 113 fiches créées` : "113 lots à enregistrer"}</h2><p>Une fiche nominative et un niveau d’accès pour chaque lot.</p></div>{avenueCounts.map(([name,count,color])=><div className="distribution-item" key={name as string}><span style={{background:color as string}}/><p><strong>Avenue des {name}</strong><small>{count as number} fiche(s)</small></p><b>{liveData ? `${count}` : `${Math.round(Number(count)/113*100)} %`}</b></div>)}</section>
    <section className="standard-panel admin-table-panel"><div className="standard-panel-head"><div><span>Répertoire sécurisé</span><h2>Fiches et accès des colotis</h2></div><div className="table-actions"><label><Icon name="search" size={15}/><input value={search} onChange={(e) => setSearch(e.target.value)} placeholder="Lot, nom ou avenue…"/></label><button onClick={() => setCreateOpen(true)}><Icon name="plus" size={15}/> Créer une fiche</button></div></div><div className="admin-table resident-table"><div className="admin-table-row header"><span>Référence</span><span>Coloti</span><span>Avenue</span><span>Accès</span><span>Rôle</span><span/></div>{loading ? <div className="table-loading">Chargement des fiches…</div> : filtered.map((member)=><div className="admin-table-row" key={member.id}><span>{member.lotReference}</span><span><b>{member.firstName} {member.lastName}</b><small>{member.email}</small></span><span>{member.avenue}</span><span className={`access-state ${member.accessStatus}`}>{member.accessStatus === "active" ? "Actif" : member.accessStatus === "invited" ? "Invité" : member.accessStatus === "suspended" ? "Suspendu" : "En attente"}</span><span>{member.role === "bureau" ? "Bureau" : "Coloti"}</span><button aria-label={`Ouvrir la fiche ${member.lotReference}`} onClick={() => setSelected(member)}><Icon name="chevron" size={16}/></button></div>)}</div></section>
    {createOpen && <div className="modal-backdrop" role="presentation" onMouseDown={(e) => { if (e.target === e.currentTarget) setCreateOpen(false); }}><section className="modal member-modal" role="dialog" aria-modal="true" aria-labelledby="create-member-title"><button className="modal-close" aria-label="Fermer" onClick={() => setCreateOpen(false)}><Icon name="close" size={20}/></button><div className="modal-icon green"><Icon name="users" size={24}/></div><span className="modal-kicker green">Base des 113 colotis</span><h2 id="create-member-title">Créer une fiche coloti</h2><p>L’adresse e-mail servira à reconnaître le coloti lors de sa connexion.</p><form onSubmit={createMember}><div className="field-row"><label>Prénom<input name="firstName" required/></label><label>Nom<input name="lastName" required/></label></div><div className="field-row"><label>Référence du lot<input name="lotReference" required placeholder="Ex. OLI-042"/></label><label>Numéro dans l’avenue<input name="addressNumber" placeholder="Ex. 42"/></label></div><label>Avenue<select name="avenue" required><option>Avenue des Mimosas</option><option>Avenue des Lauriers</option><option>Avenue des Oliviers</option><option>Bureau ASL</option></select></label><div className="field-row"><label>Adresse e-mail<input name="email" type="email" required/></label><label>Téléphone<input name="phone" type="tel"/></label></div><div className="field-row"><label>Niveau d’accès<select name="role"><option value="resident">Coloti</option><option value="bureau">Membre du bureau</option></select></label><label>Activation<select name="accessStatus"><option value="invited">Invitation à envoyer</option><option value="active">Activer immédiatement</option></select></label></div><div className="field-row"><label>Cotisation 2026 (€)<input name="amount" type="number" min="0" step="0.01" defaultValue="320.00"/></label><label>Note interne<input name="notes" placeholder="Facultatif"/></label></div><div className="modal-actions"><button type="button" onClick={() => setCreateOpen(false)}>Annuler</button><button type="submit">Créer la fiche <Icon name="check" size={17}/></button></div></form></section></div>}
    {selected && <div className="modal-backdrop" role="presentation" onMouseDown={(e) => { if (e.target === e.currentTarget) setSelected(null); }}><section className="modal member-detail-modal" role="dialog" aria-modal="true" aria-labelledby="member-detail-title"><button className="modal-close" aria-label="Fermer" onClick={() => setSelected(null)}><Icon name="close" size={20}/></button><div className="member-detail-head"><span>{selected.firstName.slice(0,1)}{selected.lastName.slice(0,1)}</span><div><small>{selected.lotReference}</small><h2 id="member-detail-title">{selected.firstName} {selected.lastName}</h2><p>{selected.addressNumber} {selected.avenue}</p></div></div><dl className="member-detail-list"><div><dt>E-mail de connexion</dt><dd>{selected.email}</dd></div><div><dt>Téléphone</dt><dd>{selected.phone || "Non renseigné"}</dd></div><div><dt>Rôle</dt><dd>{selected.role === "bureau" ? "Membre du bureau" : "Coloti"}</dd></div><div><dt>État de l’accès</dt><dd>{selected.accessStatus}</dd></div><div><dt>Note interne</dt><dd>{selected.notes || "Aucune note"}</dd></div></dl><div className="member-detail-actions"><button onClick={() => notify(`Une invitation de connexion est prête pour ${selected.email}.`)}><Icon name="mail" size={16}/> Renvoyer l’invitation</button><button onClick={() => changeAccess(selected, selected.accessStatus === "suspended" ? "active" : "suspended")}><Icon name="shield" size={16}/> {selected.accessStatus === "suspended" ? "Réactiver" : "Suspendre l’accès"}</button></div></section></div>}
  </>;
}

const demoResident: PortalProfile = { id: 42, lotReference: "OLI-042", firstName: "Christophe", lastName: "Nazarian", email: "demo.coloti@leplandubois.fr", phone: "06 •• •• •• ••", avenue: "Avenue des Oliviers", addressNumber: "42", role: "resident", accessStatus: "active", notes: "", createdAt: "2026-08-11", updatedAt: "2026-08-11" };
const demoBureau: PortalProfile = { ...demoResident, id: 1, lotReference: "BUREAU-001", email: "demo.bureau@leplandubois.fr", avenue: "Bureau ASL", addressNumber: "", role: "bureau" };

export default function Portal({ authUser, initialProfile, databaseReady, signInPath, signOutPath }: PortalProps) {
  const [demoRole, setDemoRole] = useState<"resident" | "bureau" | null>(null);
  const [active, setActive] = useState("home");
  const [role, setRole] = useState<"resident" | "bureau">(initialProfile?.role === "bureau" ? "bureau" : "resident");
  const [bureauSection, setBureauSection] = useState("overview");
  const [menuOpen, setMenuOpen] = useState(false);
  const [notificationsOpen, setNotificationsOpen] = useState(false);
  const [profileOpen, setProfileOpen] = useState(false);
  const [alertOpen, setAlertOpen] = useState(false);
  const [paymentOpen, setPaymentOpen] = useState(false);
  const [composeOpen, setComposeOpen] = useState(false);
  const [documentOpen, setDocumentOpen] = useState<string | null>(null);
  const [toast, setToast] = useState("");

  if (!authUser && !demoRole) {
    return <LoginScreen signInPath={signInPath} onDemo={(nextRole) => { setDemoRole(nextRole); setRole(nextRole); }} />;
  }
  if (authUser && databaseReady && !initialProfile) {
    return <PendingAccessScreen user={authUser} signOutPath={signOutPath}/>;
  }
  const profile = initialProfile ?? (demoRole === "bureau" ? demoBureau : demoResident);
  const canAccessBureau = profile.role === "bureau" || !authUser;
  const displayName = `${profile.firstName} ${profile.lastName}`.trim();
  const initials = `${profile.firstName.slice(0,1)}${profile.lastName.slice(0,1)}`.toUpperCase();

  const activeLabel = role === "bureau" ? (bureauNavigation.find((item) => item.id === bureauSection)?.label ?? "Espace bureau") : (navigation.find((item) => item.id === active)?.label ?? "Accueil");

  function notify(message: string) {
    setToast(message);
    window.setTimeout(() => setToast(""), 3000);
  }

  function navigate(id: string) {
    setActive(id);
    setMenuOpen(false);
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  function navigateBureau(id: string) {
    setBureauSection(id);
    setMenuOpen(false);
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  function toggleRole() {
    if (!canAccessBureau) return;
    setRole(role === "resident" ? "bureau" : "resident");
    setMenuOpen(false);
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  function submitAlert(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setAlertOpen(false);
    notify("Votre signalement a été transmis au bureau.");
  }

  return (
    <div className="app-shell">
      <aside className={`sidebar ${menuOpen ? "is-open" : ""}`}>
        <div className="brand">
          <div className="brand-mark"><span>LPB</span><i /></div>
          <div><strong>Le Plan du Bois</strong><small>Association syndicale libre</small></div>
        </div>

        <div className="residence-chip">
          <span className="chip-icon"><Icon name="map" size={18} /></span>
          <div><strong>113 colotis</strong><small>La Gaude · 06610</small></div>
        </div>

        {role === "resident" ? (
          <nav className="main-nav" aria-label="Navigation principale">
            <span className="nav-eyebrow">Mon espace</span>
            {navigation.map((item) => (
              <button key={item.id} className={active === item.id ? "active" : ""} onClick={() => navigate(item.id)}>
                <span className="nav-icon"><Icon name={item.icon} size={19} /></span>
                <span>{item.label}</span>
                {item.id === "voisinage" && <b className="nav-badge">2</b>}
              </button>
            ))}
          </nav>
        ) : (
          <nav className="main-nav bureau-nav" aria-label="Navigation du bureau">
            <span className="nav-eyebrow">Gestion de l’ASL</span>
            {bureauNavigation.map((item) => (
              <button key={item.id} className={bureauSection === item.id ? "active" : ""} onClick={() => navigateBureau(item.id)}>
                <span className="nav-icon"><Icon name={item.icon} size={19} /></span>
                <span>{item.label}</span>
                {item.id === "alerts" && <b className="nav-badge">2</b>}
              </button>
            ))}
          </nav>
        )}

        <div className="avenues-card">
          <div className="avenues-art" aria-hidden="true"><i /><i /><i /></div>
          <p><strong>Nos trois avenues</strong><br />Mimosas · Lauriers · Oliviers</p>
        </div>

        {canAccessBureau && <button className="bureau-link" onClick={toggleRole}>
          <span><Icon name={role === "resident" ? "shield" : "home"} size={17} /> {role === "resident" ? "Accès bureau" : "Retour espace coloti"}</span><Icon name="chevron" size={16} />
        </button>}
      </aside>

      {menuOpen && <button className="menu-scrim" aria-label="Fermer le menu" onClick={() => setMenuOpen(false)} />}

      <main className="main-panel">
        <header className="topbar">
          <button className="mobile-menu" aria-label="Ouvrir le menu" onClick={() => setMenuOpen(true)}><Icon name="menu" size={23} /></button>
          <div className="mobile-brand"><div className="mini-mark">LPB</div><span>{activeLabel}</span></div>
          <div className="topbar-actions">
            <button className="notification-button" aria-label="Notifications" onClick={() => setNotificationsOpen(!notificationsOpen)}>
              <Icon name="bell" size={20} /><i />
            </button>
            <button className="profile-button" aria-expanded={profileOpen} onClick={() => setProfileOpen(!profileOpen)}>
              <span className="avatar">{initials}</span>
              <span className="profile-copy"><strong>{displayName}</strong><small>{role === "bureau" ? "Membre du bureau" : profile.avenue}</small></span>
              <span className="profile-chevron">⌄</span>
            </button>
          </div>
          {notificationsOpen && (
            <div className="notifications-popover">
              <div className="popover-head"><strong>Notifications</strong><span>2 nouvelles</span></div>
              <button><i className="dot orange"/><span><strong>Cotisation 2026</strong><small>Échéance dans 50 jours</small></span></button>
              <button><i className="dot green"/><span><strong>Nouvelle information</strong><small>Débroussaillage avant le 15 septembre</small></span></button>
            </div>
          )}
          {profileOpen && <div className="account-popover"><div className="account-head"><span className="avatar">{initials}</span><p><strong>{displayName}</strong><small>{profile.email}</small></p></div><div className="account-meta"><span>Lot <b>{profile.lotReference}</b></span><span>Accès <b>{profile.role === "bureau" ? "Bureau" : "Coloti"}</b></span></div>{authUser ? <a href={signOutPath}>Se déconnecter</a> : <button onClick={() => { setDemoRole(null); setProfileOpen(false); }}>Quitter la démonstration</button>}</div>}
        </header>

        <div className="content-wrap">
          {role === "bureau" ? (
            <BureauView section={bureauSection} notify={notify} openCompose={() => setComposeOpen(true)} openDocument={setDocumentOpen} liveData={Boolean(authUser && initialProfile && databaseReady)} />
          ) : active === "home" ? (
          <>
          <section className="welcome-row">
            <div>
              <div className="page-kicker"><span /><p>Mardi 11 août 2026</p></div>
              <h1>Bonjour {profile.firstName},</h1>
              <p>Voici l’essentiel de la vie du lotissement aujourd’hui.</p>
            </div>
            <button className="primary-action" onClick={() => setAlertOpen(true)}><Icon name="shield" size={19} /> Signaler un fait urgent</button>
          </section>

          <section className="urgent-banner">
            <div className="urgent-icon"><Icon name="shield" size={22} /></div>
            <div><span>Information sécurité</span><strong>Vigilance renforcée après plusieurs signalements</strong><p>Deux véhicules suspects ont été aperçus hier soir avenue des Lauriers.</p></div>
            <button onClick={() => navigate("voisinage")}>Voir les détails <Icon name="arrow" size={17} /></button>
          </section>

          <section className="summary-grid">
            <article className="summary-card cotisation-card">
              <div className="card-heading"><span className="soft-icon"><Icon name="wallet" size={21} /></span><span className="status warning">À régler</span></div>
              <small>Cotisation annuelle 2026</small>
              <div className="amount-row"><strong>320 €</strong><span>avant le 30 sept.</span></div>
              <div className="progress-track"><i /></div>
              <button onClick={() => navigate("cotisations")}>Voir ma cotisation <Icon name="chevron" size={15}/></button>
            </article>

            <article className="summary-card meeting-card">
              <div className="card-heading"><span className="soft-icon"><Icon name="calendar" size={21} /></span><span className="status neutral">À venir</span></div>
              <small>Prochaine assemblée générale</small>
              <div className="date-lockup"><strong>10</strong><span><b>Octobre 2026</b><small>18 h 30 · Salle La Coupole</small></span></div>
              <button onClick={() => navigate("ag")}>Préparer l’AG <Icon name="chevron" size={15}/></button>
            </article>

            <article className="summary-card docs-card">
              <div className="card-heading"><span className="soft-icon"><Icon name="folder" size={21} /></span><span className="status success">6 nouveaux</span></div>
              <small>Documents récents</small>
              <div className="doc-stack"><i/><i/><i/><span><strong>Procès-verbaux & comptes</strong><small>Mis à jour le 4 août</small></span></div>
              <button onClick={() => navigate("ag")}>Consulter les documents <Icon name="chevron" size={15}/></button>
            </article>
          </section>

          <section className="dashboard-grid">
            <div className="panel info-panel">
              <div className="panel-title"><div><span>À la une</span><h2>Informations du bureau</h2></div><button onClick={() => navigate("actualites")}>Tout voir <Icon name="arrow" size={16}/></button></div>
              <div className="notice-list">
                {notices.map((notice) => (
                  <article key={notice.title}>
                    <div className={`notice-thumb ${notice.color}`}><Icon name={notice.color === "sage" ? "leaf" : "clock"} size={24}/></div>
                    <div><div className="notice-meta"><span>{notice.tag}</span><time>{notice.date}</time></div><h3>{notice.title}</h3><p>{notice.text}</p></div>
                    <button aria-label={`Lire ${notice.title}`}><Icon name="chevron" size={18}/></button>
                  </article>
                ))}
              </div>
            </div>

            <div className="panel agenda-panel">
              <div className="panel-title"><div><span>Calendrier</span><h2>Prochains rendez-vous</h2></div><button aria-label="Voir le calendrier"><Icon name="calendar" size={19}/></button></div>
              <div className="timeline">
                <div><time><b>15</b>SEP</time><i/><p><strong>Fin de la campagne de débroussaillage</strong><small>Tout le lotissement</small></p></div>
                <div><time><b>30</b>SEP</time><i/><p><strong>Échéance cotisation 2026</strong><small>Règlement annuel</small></p></div>
                <div><time><b>10</b>OCT</time><i/><p><strong>Assemblée générale</strong><small>18 h 30 · Salle La Coupole</small></p></div>
              </div>
            </div>
          </section>

          <section className="quick-actions">
            <div><span>Accès rapide</span><h2>Que souhaitez-vous faire ?</h2></div>
            <button onClick={() => navigate("cotisations")}><span><Icon name="wallet" size={20}/></span><p><strong>Régler ma cotisation</strong><small>Paiement et justificatifs</small></p><Icon name="chevron" size={18}/></button>
            <button onClick={() => navigate("ag")}><span><Icon name="folder" size={20}/></span><p><strong>Trouver un document</strong><small>PV, budgets et règlements</small></p><Icon name="chevron" size={18}/></button>
            <button onClick={() => navigate("annuaire")}><span><Icon name="users" size={20}/></span><p><strong>Contacter le bureau</strong><small>Écrire à l’association</small></p><Icon name="chevron" size={18}/></button>
          </section>
          </>
          ) : (
            <ResidentSection section={active} notify={notify} openAlert={() => setAlertOpen(true)} openPayment={() => setPaymentOpen(true)} openDocument={setDocumentOpen} profile={profile} liveData={Boolean(authUser && initialProfile && databaseReady)} />
          )}
        </div>

        {role === "resident" && <nav className="mobile-bottom-nav" aria-label="Navigation mobile">
          {navigation.slice(0, 4).map((item) => <button key={item.id} className={active === item.id ? "active" : ""} onClick={() => navigate(item.id)}><Icon name={item.icon} size={20}/><span>{item.id === "cotisations" ? "Cotisation" : item.id === "ag" ? "Documents" : item.label}</span></button>)}
          <button onClick={() => setMenuOpen(true)}><Icon name="menu" size={20}/><span>Plus</span></button>
        </nav>}
      </main>

      {alertOpen && (
        <div className="modal-backdrop" role="presentation" onMouseDown={(e) => { if (e.target === e.currentTarget) setAlertOpen(false); }}>
          <section className="modal" role="dialog" aria-modal="true" aria-labelledby="alert-title">
            <button className="modal-close" aria-label="Fermer" onClick={() => setAlertOpen(false)}><Icon name="close" size={20}/></button>
            <div className="modal-icon"><Icon name="shield" size={24}/></div>
            <span className="modal-kicker">Alerte voisinage</span>
            <h2 id="alert-title">Signaler un fait urgent</h2>
            <p>Votre message sera transmis immédiatement aux membres du bureau. En cas de danger immédiat, appelez le 17.</p>
            <form onSubmit={submitAlert}>
              <label>Type de signalement<select required defaultValue=""><option value="" disabled>Choisir une catégorie</option><option>Vol ou tentative de vol</option><option>Véhicule ou comportement suspect</option><option>Dégradation</option><option>Incident sur la voirie</option><option>Autre urgence</option></select></label>
              <div className="field-row"><label>Avenue<select required><option>Les Mimosas</option><option>Les Lauriers</option><option>Les Oliviers</option></select></label><label>Heure approximative<input type="time" /></label></div>
              <label>Que s’est-il passé ?<textarea required placeholder="Décrivez brièvement les faits, sans communiquer de données sensibles…" /></label>
              <label className="consent"><input type="checkbox" required /><span>Je confirme l’exactitude de ce signalement.</span></label>
              <div className="modal-actions"><button type="button" onClick={() => setAlertOpen(false)}>Annuler</button><button type="submit">Transmettre au bureau <Icon name="arrow" size={17}/></button></div>
            </form>
          </section>
        </div>
      )}

      {paymentOpen && (
        <div className="modal-backdrop" role="presentation" onMouseDown={(e) => { if (e.target === e.currentTarget) setPaymentOpen(false); }}>
          <section className="modal payment-modal" role="dialog" aria-modal="true" aria-labelledby="payment-title">
            <button className="modal-close" aria-label="Fermer" onClick={() => setPaymentOpen(false)}><Icon name="close" size={20}/></button>
            <div className="modal-icon green"><Icon name="credit" size={24}/></div><span className="modal-kicker green">Cotisation 2026</span><h2 id="payment-title">Préparer mon règlement</h2><p>Vérifiez le montant et choisissez votre mode de paiement. Aucun paiement réel n’est effectué dans cette version de démonstration.</p>
            <div className="payment-summary"><span>Lot {profile.lotReference}</span><p><small>Cotisation annuelle</small><strong>320,00 €</strong></p><b>À régler avant le 30 septembre 2026</b></div>
            <form onSubmit={(e) => { e.preventDefault(); setPaymentOpen(false); notify("Le module de paiement sécurisé sera raccordé lors de la mise en service."); }}><label className="payment-choice"><input type="radio" name="method" defaultChecked/><span><Icon name="credit" size={19}/><b>Carte bancaire</b><small>Confirmation immédiate</small></span></label><label className="payment-choice"><input type="radio" name="method"/><span><Icon name="wallet" size={19}/><b>Virement bancaire</b><small>Coordonnées et référence de paiement</small></span></label><div className="modal-actions"><button type="button" onClick={() => setPaymentOpen(false)}>Annuler</button><button type="submit">Continuer en toute sécurité <Icon name="arrow" size={17}/></button></div></form>
          </section>
        </div>
      )}

      {composeOpen && (
        <div className="modal-backdrop" role="presentation" onMouseDown={(e) => { if (e.target === e.currentTarget) setComposeOpen(false); }}>
          <section className="modal compose-modal" role="dialog" aria-modal="true" aria-labelledby="compose-title">
            <button className="modal-close" aria-label="Fermer" onClick={() => setComposeOpen(false)}><Icon name="close" size={20}/></button>
            <div className="modal-icon green"><Icon name="news" size={24}/></div><span className="modal-kicker green">Publication du bureau</span><h2 id="compose-title">Nouvelle information</h2><p>Rédigez une communication, choisissez ses destinataires et programmez sa notification.</p>
            <form onSubmit={(e) => { e.preventDefault(); setComposeOpen(false); notify("L’information a été enregistrée et la notification est prête à être envoyée."); }}><div className="field-row"><label>Catégorie<select><option>Information générale</option><option>Entretien</option><option>Travaux</option><option>Sécurité</option><option>Assemblée générale</option></select></label><label>Destinataires<select><option>Les 113 colotis</option><option>Avenue des Mimosas</option><option>Avenue des Lauriers</option><option>Avenue des Oliviers</option></select></label></div><label>Titre<input required placeholder="Titre de l’information"/></label><label>Message<textarea required placeholder="Rédigez une information claire et concise…"/></label><div className="field-row"><label>Publication<select><option>Immédiate</option><option>Planifier une date</option><option>Enregistrer en brouillon</option></select></label><label>Notifications<select><option>E-mail + espace coloti</option><option>Espace coloti uniquement</option><option>Sans notification</option></select></label></div><div className="modal-actions"><button type="button" onClick={() => setComposeOpen(false)}>Enregistrer plus tard</button><button type="submit">Publier l’information <Icon name="send" size={17}/></button></div></form>
          </section>
        </div>
      )}

      {documentOpen && (
        <div className="modal-backdrop" role="presentation" onMouseDown={(e) => { if (e.target === e.currentTarget) setDocumentOpen(null); }}>
          <section className="modal document-modal" role="dialog" aria-modal="true" aria-labelledby="document-title">
            <button className="modal-close" aria-label="Fermer" onClick={() => setDocumentOpen(null)}><Icon name="close" size={20}/></button>
            <div className="document-preview-head"><span className="pdf-icon">PDF</span><div><span>Document officiel de l’ASL</span><h2 id="document-title">{documentOpen}</h2></div></div>
            <div className="document-sheet"><div className="sheet-brand"><div className="mini-mark">LPB</div><p><strong>ASL Le Plan du Bois</strong><small>La Gaude · Alpes-Maritimes</small></p></div><h3>{documentOpen}</h3><p className="sheet-date">Document présenté dans l’espace sécurisé des colotis</p><div className="sheet-lines"><i/><i/><i/><i/><i/><i/></div><p className="sheet-note">Cet aperçu illustre la consultation intégrée. Les documents définitifs seront ajoutés et validés par le bureau avant l’ouverture du portail aux 113 colotis.</p></div>
            <div className="modal-actions"><button type="button" onClick={() => setDocumentOpen(null)}>Fermer</button><button type="button" onClick={() => notify(`Le document « ${documentOpen} » est prêt à être téléchargé.`)}><Icon name="download" size={17}/> Télécharger le PDF</button></div>
          </section>
        </div>
      )}

      {toast && <div className="toast"><span><Icon name="check" size={17}/></span>{toast}</div>}
    </div>
  );
}
