import { useEffect, useMemo, useState } from "react";
import { useLocation } from "wouter";
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { trpc } from "@/lib/trpc";
import { toast } from "sonner";
import { Building2, Mail, Phone, Search, Smartphone, Users, ArrowLeft, BriefcaseBusiness, Pencil, Plus, Save, Trash2, X, Loader2 } from "lucide-react";

type DirectoryContact = {
  name: string;
  role: string;
  email?: string;
  phone?: string;
  mobile?: string;
  extension?: string;
};

type DirectoryService = {
  id: string;
  title: string;
  description: string;
  contacts: DirectoryContact[];
};

type DirectoryDivision = {
  id: string;
  title: string;
  description: string;
  accentClassName: string;
  services: DirectoryService[];
};

const ccdsInternalDirectory: DirectoryDivision[] = [
  {
    id: "cabinet",
    title: "Cabinet",
    description: "Présidence et accompagnement direct du pilotage institutionnel.",
    accentClassName: "border-l-4 border-l-emerald-500 bg-emerald-50/70",
    services: [
      {
        id: "presidence",
        title: "Présidence",
        description: "Contacts de représentation et de pilotage politique.",
        contacts: [
          {
            name: "Michael Rimane",
            role: "Président de la CCDS",
            email: "president@ccds-guyane.fr",
            phone: "05 94 32 81 60",
            mobile: "0694 38 38 80",
          },
        ],
      },
      {
        id: "cabinet-direction",
        title: "Cabinet",
        description: "Direction et coordination du cabinet.",
        contacts: [
          {
            name: "Aldo Neman",
            role: "Directeur / Collaborateur de cabinet",
            email: "aldo.neman@ccds-guyane.fr",
            phone: "05 94 32 81 70",
            mobile: "0694 31 21 52",
            extension: "68",
          },
        ],
      },
    ],
  },
  {
    id: "dgs",
    title: "Direction Générale des Services",
    description: "Accueil, secrétariat de direction et coordination générale des services.",
    accentClassName: "border-l-4 border-l-amber-500 bg-amber-50/70",
    services: [
      {
        id: "dgs-direction",
        title: "Direction Générale des Services",
        description: "Cellule de direction générale et accueil institutionnel.",
        contacts: [
          {
            name: "Tatiana Falgayrettes",
            role: "Directrice Générale des Services",
            email: "tatiana.falgayrettes@ccds-guyane.fr",
            phone: "05 94 22 19 17",
            mobile: "0694 38 38 17",
            extension: "28",
          },
          {
            name: "Jeanne Leite do Rosario",
            role: "Hôtesse d'accueil",
            email: "jeane.leitedorosario@ccds-guyane.fr",
            phone: "05 94 22 00 17",
            extension: "24",
          },
          {
            name: "Joelle Jersier",
            role: "Assistante de direction",
            email: "joelle.jersier@ccds-guyane.fr",
            phone: "05 94 22 19 79",
            mobile: "0694 40 33 77",
            extension: "26",
          },
          {
            name: "Valem Douka",
            role: "Assistante de direction",
            email: "valem.douka@ccds-guyane.fr",
            phone: "05 94 22 19 41",
            mobile: "0694 40 40 67",
            extension: "42",
          },
        ],
      },
      {
        id: "communication",
        title: "Service de communication",
        description: "Relations publiques, communication institutionnelle et santé territoriale.",
        contacts: [
          {
            name: "Maëlyss Amaranthe-Blaise",
            role: "Assistante relation publique",
            email: "maelyss.amaranthe@ccds-guyane.fr",
            phone: "05 94 22 43 49",
            extension: "74",
          },
          {
            name: "Christiane Pédie",
            role: "Chargée de mission Contrat local santé",
            email: "christiane.pedie@ccds-guyane.fr",
            phone: "05 94 22 19 73",
            mobile: "0694 42 06 76",
            extension: "23",
          },
          {
            name: "Stella Prudent",
            role: "Assistante santé",
            email: "stella.prudent@ccds-guyane.fr",
            phone: "05 94 22 26 66",
            extension: "63",
          },
          {
            name: "Salle de réunion",
            role: "Réservation / coordination",
            email: "room2_ccds@ccds-guyane.fr",
            phone: "05 94 22 19 19",
            extension: "30",
          },
          {
            name: "Rolando Chrétien",
            role: "Chargé de communication",
            email: "rolando.chretien@ccds-guyane.fr",
            phone: "05 94 22 19 20",
            mobile: "0694 08 30 12",
            extension: "40",
          },
          {
            name: "Claudia Berthier",
            role: "Chargée de communication",
            email: "claudia.berthier@ccds-guyane.fr",
            phone: "05 94 22 19 76",
            mobile: "0694 08 30 14",
            extension: "31",
          },
          {
            name: "Daven Majoko",
            role: "Assistante de communication",
            email: "daven.majoko@ccds-guyane.fr",
            phone: "05 94 22 19 54",
            mobile: "0694 24 05 75",
            extension: "50",
          },
          {
            name: "Marlissa Cordeiro",
            role: "Chargée de mission relations publiques",
            email: "marlissa.cordeiro@ccds-guyane.fr",
            phone: "05 94 32 81 70",
            mobile: "0694 24 17 16",
            extension: "65",
          },
        ],
      },
    ],
  },
  {
    id: "ingenierie",
    title: "Direction Ingénierie et Expertise aux Services",
    description: "Ressources, finances et moyens supports au fonctionnement de la CCDS.",
    accentClassName: "border-l-4 border-l-rose-500 bg-rose-50/70",
    services: [
      {
        id: "rh",
        title: "Service des ressources humaines",
        description: "Gestion RH, suivi administratif des agents et organisation interne.",
        contacts: [
          {
            name: "Lindsey Raisin",
            role: "Responsable RH",
            email: "lindsey.raisin@ccds-guyane.fr",
            phone: "05 94 22 43 47",
            extension: "59",
          },
          {
            name: "Mireille Asselos",
            role: "Gestionnaire RH",
            email: "mireille.asselos@ccds-guyane.fr",
            phone: "05 94 22 19 71",
            mobile: "06 94 21 04 33",
            extension: "55",
          },
          {
            name: "Carine Darcheville William",
            role: "Gestionnaire RH",
            email: "carine.darcheville@ccds-guyane.fr",
            phone: "05 94 32 81 65",
            extension: "62",
          },
        ],
      },
      {
        id: "finances",
        title: "Service finances et marchés publics",
        description: "Budgets, commandes, gestion financière et marchés.",
        contacts: [
          {
            name: "Louisa Basse-Brousse",
            role: "Responsable",
            email: "louisa.basse-brousse@ccds-guyane.fr",
            phone: "05 94 22 19 90",
            mobile: "0694 38 40 80",
            extension: "41",
          },
          {
            name: "Cindy Mourougandy",
            role: "Assistante de direction",
            email: "cindy.mourougandy@ccds-guyane.fr",
            phone: "05 94 22 19 70",
            extension: "20",
          },
          {
            name: "Cellia Ringuet",
            role: "Gestionnaire",
            email: "cellia.ringuet@ccds-guyane.fr",
            phone: "05 94 32 81 67",
            extension: "57",
          },
          {
            name: "Samina Hiram",
            role: "Coordinatrice comptable / budgétaire",
            email: "samina.hiram@ccds-guyane.fr",
            phone: "05 94 22 19 78",
            extension: "33",
          },
          {
            name: "Malina Joseph",
            role: "Gestionnaire",
            email: "malina.joseph@ccds-guyane.fr",
            phone: "05 94 32 75 75",
            extension: "53",
          },
          {
            name: "Francine Lafrontière",
            role: "Chargée de mission finances / marchés",
            email: "francine.lafrontiere@ccds-guyane.fr",
            phone: "05 94 32 75 72",
            extension: "45",
          },
          {
            name: "Leida Oger",
            role: "Gestionnaire des finances",
            email: "leida.oger@ccds-guyane.fr",
            phone: "05 94 22 75 70",
            extension: "44",
          },
        ],
      },
      {
        id: "moyens-generaux",
        title: "Services des moyens généraux",
        description: "Coordination des moyens supports et du fonctionnement interne.",
        contacts: [
          {
            name: "Richard Rimane",
            role: "Chargé de mission informatiques",
            email: "richard.rimane@ccds-guyane.fr",
            phone: "05 94 22 19 99",
            mobile: "0694 40 40 71",
            extension: "54",
          },
        ],
      },
      {
        id: "patrimoine",
        title: "Cellule patrimoine",
        description: "Suivi des bâtiments, patrimoine et moyens généraux.",
        contacts: [
          {
            name: "Christele Oliveira da Silva",
            role: "Coordinatrice moyens généraux",
            email: "christele.oliveiradasilva@ccds-guyane.fr",
            phone: "05 94 32 81 77",
            mobile: "0694 31 20 27",
            extension: "38",
          },
          {
            name: "Lucia Rapha",
            role: "Agent social polyvalent",
            email: "lucia.rapha@ccds-guyane.fr",
            mobile: "0694 90 67 44",
          },
          {
            name: "Maleva Pinas",
            role: "Agent administratif",
            email: "maleva.pinas@ccds-guyane.fr",
            phone: "05 94 22 64 59",
            extension: "72",
          },
          {
            name: "Yves-Hianska Minancée",
            role: "Assistante de direction",
            email: "yves-hianska.minancee@ccds-guyane.fr",
            phone: "05 94 22 19 76",
            extension: "31",
          },
        ],
      },
      {
        id: "informatique",
        title: "Cellule informatique",
        description: "Support informatique, administration et accompagnement numérique.",
        contacts: [
          {
            name: "Stéphane Golitin",
            role: "Agent technique polyvalent",
            email: "stephane.golitin@ccds-guyane.fr",
            phone: "05 94 22 19 72",
            mobile: "0694 40 93 73",
            extension: "22",
          },
          {
            name: "Clarence Amimiba",
            role: "Chargé de missions informatiques",
            email: "clarence.amimiba@ccds-guyane.fr",
            phone: "05 94 22 19 18",
            extension: "25",
          },
        ],
      },
      {
        id: "parc-auto",
        title: "Cellule parc automobile",
        description: "Véhicules, flotte et appui technique de mobilité.",
        contacts: [
          {
            name: "Frédéric Zephir",
            role: "Agent technique polyvalent",
            email: "frederic.zephir@ccds-guyane.fr",
            mobile: "0694 92 88 88",
          },
          {
            name: "Fabrice Marcellus",
            role: "Agent technique polyvalent",
            email: "fabrice.marcellus@ccds-guyane.fr",
            mobile: "0694 38 83 26",
          },
        ],
      },
    ],
  },
  {
    id: "amenagement",
    title: "Direction de l'Aménagement et Développement Durable",
    description: "Développement durable, déchets, eau, assainissement et économie territoriale.",
    accentClassName: "border-l-4 border-l-sky-500 bg-sky-50/70",
    services: [
      {
        id: "dadd-direction",
        title: "Direction de l'aménagement et du développement durable",
        description: "Pilotage de la direction, brigades et coordination territoriale.",
        contacts: [
          {
            name: "Pascal Gombauld",
            role: "Directeur de l'aménagement et du développement durable",
            email: "pascal.gombauld@ccds-guyane.fr",
            phone: "05 94 22 43 51",
            mobile: "0694 44 06 61",
            extension: "37",
          },
          {
            name: "Franciane Chocho",
            role: "Assistante de direction",
            email: "franciane.chocho@ccds-guyane.fr",
            phone: "05 94 22 43 63",
            mobile: "0694 21 03 29",
            extension: "36",
          },
          {
            name: "Leonne Sophie",
            role: "Brigade particulière",
            email: "leonne.sophie@ccds-guyane.fr",
            phone: "05 94 22 43 64",
            mobile: "0694 24 27 03",
            extension: "34",
          },
          {
            name: "Denis Berthier",
            role: "Brigade particulière",
            email: "denis.berthier@ccds-guyane.fr",
          },
          {
            name: "Yuali Aquila",
            role: "Brigade particulière",
            email: "yuali.aquila@ccds-guyane.fr",
            mobile: "06 94 24 26 97",
          },
          {
            name: "Estelle Payard-Lyonnet",
            role: "Chargée de mission CODOM",
            email: "estelle.lyonnet@ccds-guyane.fr",
          },
          {
            name: "Florence Lozanguiez",
            role: "Référente plan vélo",
            email: "florence.lozanguiez@ccds-guyane.fr",
            phone: "05 94 22 67 03",
            mobile: "06 94 38 41 04",
            extension: "21",
          },
          {
            name: "Salle de réunion",
            role: "Réservation / coordination",
            email: "room2_ccds@ccds-guyane.fr",
          },
        ],
      },
      {
        id: "dechets",
        title: "Service des déchets",
        description: "Exploitation, collecte, traitement et environnement.",
        contacts: [
          {
            name: "Mélina Venute",
            role: "Responsable de service",
            email: "melina.venute@ccds-guyane.fr",
            phone: "05 94 22 19 98",
            mobile: "0694 40 40 76",
            extension: "48",
          },
          {
            name: "José Arthémie",
            role: "Référent exploitation",
            email: "jose.arthemie@ccds-guyane.fr",
            phone: "05 94 22 19 92",
            mobile: "0694 40 42 47",
            extension: "43",
          },
          {
            name: "Franck Adélaïde",
            role: "Référent collecte et traitement",
            email: "franck.adelaide@ccds-guyane.fr",
            phone: "05 94 32 75 76",
            mobile: "0694 31 31 42",
            extension: "49",
          },
          {
            name: "Aimé-Claude Dechesne",
            role: "Gestionnaire environnement",
            email: "aime.claude.dechesne@ccds-guyane.fr",
            phone: "05 94 11 19 79",
          },
          {
            name: "Olivier Primerose",
            role: "Gestionnaire environnement",
            email: "olivier.primerose@ccds-guyane.fr",
            phone: "05 94 34 53 66",
          },
          {
            name: "Aline Petchy",
            role: "Gestionnaire environnement",
            email: "aline.petchy@ccds-guyane.fr",
            phone: "05 94 22 19 79",
          },
          {
            name: "Nicoletta Tourville",
            role: "Gestionnaire cellule prévention / déchets",
            email: "nicoletta.tourville@ccds-guyane.fr",
            phone: "05 94 34 53 56",
            mobile: "0694 40 30 56",
          },
          {
            name: "Paul-Dylan Lessales",
            role: "Agent technique polyvalent",
            email: "paul-dylan.lessales@ccds-guyane.fr",
            phone: "05 94 22 28 84",
            mobile: "0694 31 32 22",
          },
          {
            name: "Yannick Coumba",
            role: "Agent technique polyvalent",
            email: "yannick.coumba@ccds-guyane.fr",
            phone: "05 94 22 19 49",
            mobile: "05 94 23 06 49",
          },
          {
            name: "Myriam Riera",
            role: "Agent technique polyvalent",
            email: "myriam.riera@ccds-guyane.fr",
            phone: "05 94 20 98 56",
            mobile: "0694 20 98 56",
          },
          {
            name: "Alain Deron",
            role: "Agent technique polyvalent",
            email: "alain.deron@ccds-guyane.fr",
            phone: "05 94 43 99 81",
            mobile: "0694 43 99 81",
          },
          {
            name: "Boris Ngwete",
            role: "Pec déchèterie Kourou",
            email: "boris.ngwete@ccds-guyane.fr",
            phone: "05 94 45 55 53",
            mobile: "0694 45 55 53",
          },
          {
            name: "Dimitri Souza Da Costa",
            role: "Agent technique polyvalent",
            email: "dimitri.souzadacosta@ccds-guyane.fr",
            phone: "05 94 22 43 50",
            mobile: "0694 23 06 79",
            extension: "75",
          },
        ],
      },
      {
        id: "eau-assainissement",
        title: "Service eau et assainissement",
        description: "EAU, GEMAPI et interventions techniques associées.",
        contacts: [
          {
            name: "Christophe Bienaime",
            role: "Chargé de mission EAU",
            email: "christophe.bienaime@ccds-guyane.fr",
            phone: "05 94 32 81 68",
            mobile: "0694 22 77 17",
            extension: "64",
          },
          {
            name: "Julian Frederick",
            role: "Chargé de mission GEMAPI",
            email: "julian.frederick@ccds-guyane.fr",
            phone: "05 94 22 19 96",
            mobile: "0694 26 95 01",
            extension: "52",
          },
          {
            name: "Marcella Amarhante",
            role: "Agent technique polyvalent",
            email: "marcella.amarante@ccds-guyane.fr",
            phone: "05 94 34 69 29",
            mobile: "06 94 24 05 93",
          },
          {
            name: "Henry Galima",
            role: "Agent technique polyvalent",
            email: "henry.galima@ccds-guyane.fr",
          },
        ],
      },
      {
        id: "economie-fiscalite",
        title: "Service économie et fiscalité",
        description: "Suivi économique et fiscal du territoire, accueil du service et coordination économique.",
        contacts: [
          {
            name: "Matthieu Calatayud",
            role: "Animateur LEADER",
            email: "matthieu.calatayud@ccds-guyane.fr",
            phone: "05 94 22 67 03",
            mobile: "0694 40 30 31",
          },
          {
            name: "Paule Betian",
            role: "Agent d'accueil",
            email: "paule.betian@ccds-guyane.fr",
            phone: "05 94 22 67 03",
          },
          {
            name: "Rose Jacquet-Exavier",
            role: "Gal des Savanes",
            email: "rose.jacquet-exavier@ccds-guyane.fr",
            phone: "05 94 22 67 03",
          },
          {
            name: "Chantal Joseph",
            role: "Gestionnaire LEADER",
            email: "chantal.joseph@ccds-guyane.fr",
            phone: "05 94 22 67 03",
          },
          {
            name: "Priscilla Lama",
            role: "Gestionnaire LEADER",
            email: "priscilla.lama@ccds-guyane.fr",
            phone: "05 94 22 43 48",
          },
          {
            name: "Marie-France Anicet",
            role: "Coordinatrice projet économique",
            email: "marie-france.anicet@ccds-guyane.fr",
            mobile: "06 94 23 15 98",
            extension: "73",
          },
        ],
      },
    ],
  },
  {
    id: "usagers",
    title: "Direction des Services aux Usagers",
    description: "Maisons de services, jeunesse, sports, culture et accueil économique.",
    accentClassName: "border-l-4 border-l-violet-500 bg-violet-50/70",
    services: [
      {
        id: "mjs",
        title: "Maison de la Jeunesse des Savanes",
        description: "Direction, accueil, gestion administrative et service sports & culture.",
        contacts: [
          {
            name: "Juliana Rimane",
            role: "Directrice",
            email: "juliana.rimane@ccds-guyane.fr",
            phone: "05 94 21 64 46",
            mobile: "0694 31 31 76",
          },
          {
            name: "Maryvonne Amat",
            role: "Assistante de direction",
            email: "maryvonne.amat@ccds-guyane.fr",
            phone: "05 94 21 64 46",
          },
          {
            name: "Nadelle Lambert",
            role: "Agent d'accueil",
            email: "nadelle.lambert@ccds-guyane.fr",
            phone: "05 94 47 14 44",
          },
          {
            name: "Katucia Lambert",
            role: "Agent d'accueil",
            email: "katucia.lambert@ccds-guyane.fr",
          },
          {
            name: "Jean-Marie Balif",
            role: "Agent polyvalent",
            email: "jean-marie.balif@ccds-guyane.fr",
            phone: "05 94 24 05 93",
          },
          {
            name: "Montage DSU",
            role: "Pôle logistique / montage",
            email: "montage-dsu@ccds-guyane.fr",
          },
          {
            name: "Jean-Claude Maloudo",
            role: "Chargé de mission sport & culture",
            email: "jean-claude.maloudo@ccds-guyane.fr",
            phone: "05 94 22 64 49",
            mobile: "0694 43 13 56",
          },
          {
            name: "Lesly Malouda",
            role: "Agent technique polyvalent",
            email: "lesly.malouda@ccds-guyane.fr",
            phone: "05 94 22 80 71",
            mobile: "0694 38 83 29",
          },
          {
            name: "Smaely Pinguet",
            role: "Agent technique polyvalent",
            email: "smaely.pinguet@ccds-guyane.fr",
            mobile: "0694 40 29 47",
          },
        ],
      },
      {
        id: "hotel-entreprises",
        title: "Hôtel des entreprises de Sinnamary",
        description: "Accompagnement économique et suivi des entreprises.",
        contacts: [
          {
            name: "Patricia Lelima",
            role: "Responsable de service",
            email: "patricia.lelima@ccds-guyane.fr",
            phone: "05 94 32 75 73",
            mobile: "0694 21 01 46",
            extension: "46",
          },
          {
            name: "Leslie Madeline",
            role: "Agent administratif polyvalent",
            email: "leslie.madeline@ccds-guyane.fr",
            phone: "05 94 32 81 76",
            extension: "67",
          },
          {
            name: "Anita Dorilas",
            role: "Agent administratif polyvalent",
            email: "anita.dorilas@ccds-guyane.fr",
            phone: "05 94 32 75 74",
            extension: "47",
          },
          {
            name: "Nata Tovic",
            role: "Agent administratif polyvalent",
            email: "nata.tovic@ccds-guyane.fr",
            phone: "05 94 24 36 65",
            extension: "39",
          },
        ],
      },
    ],
  },
];

type CCDSInternalDirectoryProps = {
  backHref?: string;
  backLabel?: string;
  canEdit?: boolean;
};

function normalize(value: string) {
  return value
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .toLowerCase();
}

function tokenizeSearch(value: string) {
  const stopWords = new Set([
    "a",
    "au",
    "aux",
    "d",
    "de",
    "des",
    "du",
    "et",
    "l",
    "la",
    "le",
    "les",
    "moi",
    "ou",
    "pour",
    "qui",
    "un",
    "une",
  ]);

  return normalize(value)
    .split(/[\s,;:/()_-]+/)
    .map((token) => token.trim())
    .filter((token) => Boolean(token) && !stopWords.has(token));
}

function expandSearchTokens(tokens: string[]) {
  const synonyms: Record<string, string[]> = {
    directeur: ["directeur", "directrice", "directeurs", "directrices", "direction"],
    directrice: ["directeur", "directrice", "directeurs", "directrices", "direction"],
    directeurs: ["directeur", "directrice", "directeurs", "directrices", "direction"],
    directrices: ["directeur", "directrice", "directeurs", "directrices", "direction"],
    responsable: ["responsable", "responsables"],
    responsables: ["responsable", "responsables"],
    gestionnaire: ["gestionnaire", "gestionnaires"],
    gestionnaires: ["gestionnaire", "gestionnaires"],
    gestion: ["gestion", "gestionnaire", "gestionnaires", "administratif", "administrative", "administration"],
    administratif: ["gestion", "gestionnaire", "gestionnaires", "administratif", "administrative", "administration"],
    administrative: ["gestion", "gestionnaire", "gestionnaires", "administratif", "administrative", "administration"],
    administration: ["gestion", "gestionnaire", "gestionnaires", "administratif", "administrative", "administration"],
    charge: ["charge", "chargee", "charges", "chargees"],
    chargee: ["charge", "chargee", "charges", "chargees"],
    charges: ["charge", "chargee", "charges", "chargees"],
    chargees: ["charge", "chargee", "charges", "chargees"],
    assistant: ["assistant", "assistante", "assistants", "assistantes"],
    assistante: ["assistant", "assistante", "assistants", "assistantes"],
    assistants: ["assistant", "assistante", "assistants", "assistantes"],
    assistantes: ["assistant", "assistante", "assistants", "assistantes"],
    technique: ["technique", "techniques", "technicien", "techniciens", "technicienne", "techniciennes", "polyvalent", "polyvalente"],
    techniques: ["technique", "techniques", "technicien", "techniciens", "technicienne", "techniciennes", "polyvalent", "polyvalente"],
    technicien: ["technique", "techniques", "technicien", "techniciens", "technicienne", "techniciennes", "polyvalent", "polyvalente"],
    techniciens: ["technique", "techniques", "technicien", "techniciens", "technicienne", "techniciennes", "polyvalent", "polyvalente"],
    technicienne: ["technique", "techniques", "technicien", "techniciens", "technicienne", "techniciennes", "polyvalent", "polyvalente"],
    techniciennes: ["technique", "techniques", "technicien", "techniciens", "technicienne", "techniciennes", "polyvalent", "polyvalente"],
    polyvalent: ["technique", "techniques", "technicien", "techniciens", "technicienne", "techniciennes", "polyvalent", "polyvalente"],
    polyvalente: ["technique", "techniques", "technicien", "techniciens", "technicienne", "techniciennes", "polyvalent", "polyvalente"],
    communication: ["communication", "communicant", "communicante", "relations publiques", "charge de communication", "chargee de communication"],
    communicant: ["communication", "communicant", "communicante", "relations publiques", "charge de communication", "chargee de communication"],
    communicante: ["communication", "communicant", "communicante", "relations publiques", "charge de communication", "chargee de communication"],
    president: ["president", "presidente", "presidence", "cabinet", "elus", "pilotage", "direction"],
    presidente: ["president", "presidente", "presidence", "cabinet", "elus", "pilotage", "direction"],
    presidence: ["president", "presidente", "presidence", "cabinet", "elus", "pilotage", "direction"],
    cabinet: ["cabinet", "president", "presidence", "elus", "pilotage", "direction"],
    elus: ["cabinet", "president", "presidence", "elus", "pilotage", "direction"],
    pilotage: ["cabinet", "president", "presidence", "elus", "pilotage", "direction"],
    secretaire: ["secretaire", "secretariat", "assistante", "assistant"],
    secretariat: ["secretaire", "secretariat", "assistante", "assistant"],
    accueil: ["accueil", "hotesse", "agent d'accueil", "dgs", "secretariat", "coordination", "general", "jeunes", "jeunesse", "sport", "culture"],
    hotesse: ["accueil", "hotesse", "agent d'accueil", "dgs", "secretariat", "coordination", "general"],
    dgs: ["dgs", "accueil", "secretariat", "coordination", "general", "direction generale des services"],
    coordination: ["dgs", "coordination", "general", "accueil", "secretariat"],
    general: ["dgs", "coordination", "general", "accueil", "secretariat"],
    finances: ["finances", "finance", "comptable", "budget", "budgétaire", "marches", "ingenierie", "expertise", "moyens supports"],
    finance: ["finances", "finance", "comptable", "budget", "budgétaire", "marches", "ingenierie", "expertise", "moyens supports"],
    comptable: ["finances", "finance", "comptable", "budget", "budgétaire", "marches", "ingenierie", "expertise"],
    budget: ["finances", "finance", "comptable", "budget", "budgétaire", "marches", "ingenierie", "expertise"],
    budgetaire: ["finances", "finance", "comptable", "budget", "budgétaire", "marches", "ingenierie", "expertise"],
    marches: ["finances", "finance", "comptable", "budget", "budgétaire", "marches", "ingenierie", "expertise"],
    rh: ["rh", "ressources humaines", "humaines", "ingenierie", "expertise"],
    ressources: ["rh", "ressources humaines", "humaines", "ingenierie", "expertise"],
    humaines: ["rh", "ressources humaines", "humaines", "ingenierie", "expertise"],
    ingenierie: ["ingenierie", "expertise", "finances", "budget", "ressources humaines", "rh", "informatique", "moyens supports"],
    expertise: ["ingenierie", "expertise", "finances", "budget", "ressources humaines", "rh", "informatique", "moyens supports"],
    moyens: ["moyens generaux", "moyens supports", "patrimoine", "informatique", "parc automobile", "ingenierie", "expertise"],
    supports: ["moyens supports", "moyens generaux", "ingenierie", "expertise"],
    informatique: ["informatique", "numerique", "systeme", "systems", "missions informatiques", "ingenierie", "expertise", "moyens supports"],
    numerique: ["informatique", "numerique", "systeme", "systems", "missions informatiques", "ingenierie", "expertise"],
    systeme: ["informatique", "numerique", "systeme", "systems", "missions informatiques", "ingenierie", "expertise"],
    systems: ["informatique", "numerique", "systeme", "systems", "missions informatiques", "ingenierie", "expertise"],
    dechets: ["dechets", "poubelles", "environnement", "transition", "territoire", "amenagement"],
    poubelles: ["dechets", "poubelles", "environnement", "transition", "territoire", "amenagement"],
    eau: ["eau", "assainissement", "gemapi", "amenagement", "territoire"],
    assainissement: ["eau", "assainissement", "gemapi", "amenagement", "territoire"],
    environnement: ["dechets", "environnement", "transition", "amenagement", "territoire"],
    transition: ["dechets", "environnement", "transition", "amenagement", "territoire"],
    economie: ["economie", "fiscalite", "leader", "accueil economique", "territoire", "amenagement"],
    fiscalite: ["economie", "fiscalite", "leader", "accueil economique", "territoire", "amenagement"],
    territoire: ["amenagement", "territoire", "dechets", "eau", "assainissement", "economie", "fiscalite"],
    amenagement: ["amenagement", "territoire", "dechets", "poubelles", "eau", "assainissement", "environnement", "transition", "economie"],
    msap: ["msap", "maison de services", "services aux usagers", "usagers"],
    maison: ["maison de services", "maison de la jeunesse des savanes", "msap", "usagers"],
    jeunes: ["jeunes", "jeunesse", "sport", "culture", "association", "subvention", "services aux usagers"],
    jeunesse: ["jeunes", "jeunesse", "sport", "culture", "association", "subvention", "services aux usagers"],
    sport: ["sport", "culture", "jeunes", "jeunesse", "association", "subvention", "services aux usagers"],
    culture: ["sport", "culture", "jeunes", "jeunesse", "association", "subvention", "services aux usagers"],
    association: ["association", "subvention", "sport", "culture", "services aux usagers"],
    subvention: ["association", "subvention", "sport", "culture", "services aux usagers"],
    usagers: ["services aux usagers", "usagers", "msap", "maison de services", "jeunesse", "sport", "culture", "accueil economique"],
    proximite: ["services aux usagers", "usagers", "msap", "maison de services", "jeunesse", "sport", "culture", "accueil economique"],
  };

  return Array.from(
    new Set(
      tokens.flatMap((token) => {
        const direct = synonyms[token];
        if (direct) return direct;
        const singular = token.endsWith("s") ? token.slice(0, -1) : token;
        return synonyms[singular] || [token];
      })
    )
  );
}

function matchesSearchTerms(haystack: string, query: string) {
  const tokens = tokenizeSearch(query);
  if (tokens.length === 0) return true;
  const expandedTokens = expandSearchTokens(tokens);
  const normalizedHaystack = normalize(haystack);
  return expandedTokens.some((token) => normalizedHaystack.includes(token));
}

function formatContactRow(value: string | undefined) {
  return value?.trim() || "Non renseigné";
}

function createEmptyContact(): DirectoryContact {
  return {
    name: "",
    role: "",
    email: "",
    phone: "",
    mobile: "",
    extension: "",
  };
}

function createSlug(value: string) {
  return value
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/(^-|-$)/g, "")
    || "element";
}

function buildUniqueId(existingIds: string[], seed: string) {
  const baseId = createSlug(seed);
  let nextId = baseId;
  let index = 2;
  while (existingIds.includes(nextId)) {
    nextId = `${baseId}-${index}`;
    index += 1;
  }
  return nextId;
}

export default function CCDSInternalDirectory({ backHref, backLabel, canEdit = false }: CCDSInternalDirectoryProps) {
  const utils = trpc.useUtils();
  const [, setLocation] = useLocation();
  const [query, setQuery] = useState("");
  const [isEditMode, setIsEditMode] = useState(false);
  const { data: storedDirectory } = trpc.internalDirectory.get.useQuery();
  const saveDirectoryMutation = trpc.internalDirectory.set.useMutation({
    onSuccess: () => {
      toast.success("Annuaire interne mis à jour");
      utils.internalDirectory.get.invalidate();
      setIsEditMode(false);
    },
    onError: (error) => {
      toast.error(error.message || "Impossible d'enregistrer l'annuaire");
    },
  });
  const [draftDirectory, setDraftDirectory] = useState<DirectoryDivision[]>(ccdsInternalDirectory);

  const directoryData = useMemo(
    () => (storedDirectory && storedDirectory.length > 0 ? storedDirectory : ccdsInternalDirectory),
    [storedDirectory]
  );

  useEffect(() => {
    if (!isEditMode) {
      setDraftDirectory(directoryData);
    }
  }, [directoryData, isEditMode]);

  const dataSource = isEditMode ? draftDirectory : directoryData;

  const filteredSections = useMemo(() => {
    if (isEditMode) return dataSource;
    if (!query.trim()) return dataSource;

    return dataSource
      .map((division) => {
        const matchingServices = division.services
          .map((service) => {
            const matchesService = matchesSearchTerms(
              [service.title, service.description].join(" "),
              query
            );

            const matchingContacts = service.contacts.filter((contact) =>
              matchesSearchTerms(
                [
                  contact.name,
                  contact.role,
                  contact.email || "",
                  contact.phone || "",
                  contact.mobile || "",
                  contact.extension || "",
                  service.title,
                  division.title,
                ].join(" "),
                query
              )
            );

            if (matchesService) {
              return service;
            }

            if (matchingContacts.length > 0) {
              return {
                ...service,
                contacts: matchingContacts,
              };
            }

            return null;
          })
          .filter((service): service is DirectoryService => Boolean(service));

        const matchesDivision = matchesSearchTerms(
          [division.title, division.description].join(" "),
          query
        );

        if (matchesDivision) {
          return division;
        }

        if (matchingServices.length > 0) {
          return {
            ...division,
            services: matchingServices,
          };
        }

        return null;
      })
      .filter((division): division is DirectoryDivision => Boolean(division));
  }, [dataSource, isEditMode, query]);

  const totalServices = useMemo(
    () => filteredSections.reduce((sum, division) => sum + division.services.length, 0),
    [filteredSections]
  );
  const totalContacts = useMemo(
    () =>
      filteredSections.reduce(
        (sum, division) =>
          sum + division.services.reduce((serviceSum, service) => serviceSum + service.contacts.length, 0),
        0
      ),
    [filteredSections]
  );

  const updateDivisionField = (divisionId: string, field: "title" | "description", value: string) => {
    setDraftDirectory((prev) =>
      prev.map((division) =>
        division.id === divisionId ? { ...division, [field]: value } : division
      )
    );
  };

  const updateServiceField = (
    divisionId: string,
    serviceId: string,
    field: "title" | "description",
    value: string
  ) => {
    setDraftDirectory((prev) =>
      prev.map((division) =>
        division.id === divisionId
          ? {
              ...division,
              services: division.services.map((service) =>
                service.id === serviceId ? { ...service, [field]: value } : service
              ),
            }
          : division
      )
    );
  };

  const updateContactField = (
    divisionId: string,
    serviceId: string,
    contactIndex: number,
    field: keyof DirectoryContact,
    value: string
  ) => {
    setDraftDirectory((prev) =>
      prev.map((division) =>
        division.id === divisionId
          ? {
              ...division,
              services: division.services.map((service) =>
                service.id === serviceId
                  ? {
                      ...service,
                      contacts: service.contacts.map((contact, index) =>
                        index === contactIndex ? { ...contact, [field]: value } : contact
                      ),
                    }
                  : service
              ),
            }
          : division
      )
    );
  };

  const addContact = (divisionId: string, serviceId: string) => {
    setDraftDirectory((prev) =>
      prev.map((division) =>
        division.id === divisionId
          ? {
              ...division,
              services: division.services.map((service) =>
                service.id === serviceId
                  ? { ...service, contacts: [...service.contacts, createEmptyContact()] }
                  : service
              ),
            }
          : division
      )
    );
  };

  const removeContact = (divisionId: string, serviceId: string, contactIndex: number) => {
    setDraftDirectory((prev) =>
      prev.map((division) =>
        division.id === divisionId
          ? {
              ...division,
              services: division.services.map((service) =>
                service.id === serviceId
                  ? { ...service, contacts: service.contacts.filter((_, index) => index !== contactIndex) }
                  : service
              ),
            }
          : division
      )
    );
  };

  const addDivision = () => {
    setDraftDirectory((prev) => {
      const divisionIds = prev.map((division) => division.id);
      const nextDivisionId = buildUniqueId(divisionIds, "nouvelle-direction");
      return [
        ...prev,
        {
          id: nextDivisionId,
          title: "Nouvelle grande direction",
          description: "Description à compléter.",
          accentClassName: "border-l-4 border-l-slate-400 bg-slate-50/70",
          services: [],
        },
      ];
    });
  };

  const addService = (divisionId: string) => {
    setDraftDirectory((prev) =>
      prev.map((division) => {
        if (division.id !== divisionId) return division;
        const serviceIds = division.services.map((service) => service.id);
        const nextServiceId = buildUniqueId(serviceIds, "nouveau-service");
        return {
          ...division,
          services: [
            ...division.services,
            {
              id: nextServiceId,
              title: "Nouveau service",
              description: "Description du service à compléter.",
              contacts: [],
            },
          ],
        };
      })
    );
  };

  const handleStartEdit = () => {
    setQuery("");
    setDraftDirectory(directoryData);
    setIsEditMode(true);
  };

  const handleCancelEdit = () => {
    setDraftDirectory(directoryData);
    setIsEditMode(false);
  };

  const handleSave = () => {
    saveDirectoryMutation.mutate({ divisions: draftDirectory });
  };

  return (
    <div className="space-y-6">
      <Card className="border-primary/15 bg-gradient-to-br from-white via-white to-primary/5">
        <CardHeader className="gap-4">
          <div className="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
            <div className="space-y-3">
              <div className="flex items-center gap-3">
                <div className="rounded-xl bg-primary/10 p-3 text-primary">
                  <BriefcaseBusiness className="h-6 w-6" />
                </div>
                <div>
                  <CardTitle className="text-2xl">Annuaire interne CCDS</CardTitle>
                  <CardDescription className="text-sm">
                    Un point d’entrée rapide pour retrouver une direction, un service ou le contact d’une personne précise.
                  </CardDescription>
                </div>
              </div>
              <div className="flex flex-wrap gap-2">
                {filteredSections.map((division) => (
                  <Badge key={division.id} variant="outline" className="bg-white/80">
                    {division.title}
                  </Badge>
                ))}
              </div>
            </div>
            <div className="flex flex-wrap gap-2">
              {canEdit ? (
                isEditMode ? (
                  <>
                    <Button variant="outline" onClick={addDivision}>
                      <Plus className="mr-2 h-4 w-4" />
                      Ajouter une grande direction
                    </Button>
                    <Button variant="outline" onClick={handleCancelEdit}>
                      <X className="mr-2 h-4 w-4" />
                      Annuler
                    </Button>
                    <Button onClick={handleSave} disabled={saveDirectoryMutation.isPending}>
                      {saveDirectoryMutation.isPending ? (
                        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                      ) : (
                        <Save className="mr-2 h-4 w-4" />
                      )}
                      Enregistrer l'annuaire
                    </Button>
                  </>
                ) : (
                  <Button variant="outline" onClick={handleStartEdit}>
                    <Pencil className="mr-2 h-4 w-4" />
                    Mode édition
                  </Button>
                )
              ) : null}
              {backHref ? (
                <Button variant="outline" onClick={() => setLocation(backHref)}>
                  <ArrowLeft className="mr-2 h-4 w-4" />
                  {backLabel || "Retour"}
                </Button>
              ) : null}
            </div>
          </div>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="relative">
            <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
            <Input
              value={query}
              onChange={(event) => setQuery(event.target.value)}
              placeholder={
                isEditMode
                  ? "La recherche est suspendue pendant l'édition pour modifier chaque fiche en place"
                  : "Rechercher un nom, un service, une mission, un email ou un numéro"
              }
              className="pl-10"
              disabled={isEditMode}
            />
          </div>
          {isEditMode ? (
            <div className="rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900">
              Tu modifies ici les fiches existantes en place. Le bouton <span className="font-semibold">Ajouter un contact</span> sert uniquement à créer une nouvelle fiche.
            </div>
          ) : null}
          <div className="grid gap-3 md:grid-cols-3">
            <Card className="border-primary/10">
              <CardContent className="flex items-center gap-3 p-4">
                <Building2 className="h-5 w-5 text-primary" />
                <div>
                  <p className="text-xs text-muted-foreground">Grandes directions</p>
                  <p className="text-lg font-semibold">{filteredSections.length}</p>
                </div>
              </CardContent>
            </Card>
            <Card className="border-primary/10">
              <CardContent className="flex items-center gap-3 p-4">
                <Users className="h-5 w-5 text-primary" />
                <div>
                  <p className="text-xs text-muted-foreground">Services visibles</p>
                  <p className="text-lg font-semibold">{totalServices}</p>
                </div>
              </CardContent>
            </Card>
            <Card className="border-primary/10">
              <CardContent className="flex items-center gap-3 p-4">
                <Mail className="h-5 w-5 text-primary" />
                <div>
                  <p className="text-xs text-muted-foreground">Contacts indexés</p>
                  <p className="text-lg font-semibold">{totalContacts}</p>
                </div>
              </CardContent>
            </Card>
          </div>
        </CardContent>
      </Card>

      {filteredSections.length === 0 ? (
        <Card className="border-dashed">
          <CardContent className="py-12 text-center">
            <p className="text-lg font-medium">Aucun résultat</p>
            <p className="text-sm text-muted-foreground">
              Essaie avec un nom, un service, une mission ou une adresse email.
            </p>
          </CardContent>
        </Card>
      ) : (
        <Accordion
          type="multiple"
          defaultValue={filteredSections.map((section) => section.id)}
          className="space-y-4"
        >
          {filteredSections.map((division) => (
            <AccordionItem
              key={division.id}
              value={division.id}
              className={`overflow-hidden rounded-2xl border ${division.accentClassName}`}
            >
              <AccordionTrigger className="px-5 py-5 hover:no-underline">
                <div className="space-y-2">
                  <div className="flex flex-wrap items-center gap-2">
                    <span className="text-lg font-semibold">{division.title}</span>
                    <Badge variant="secondary">{division.services.length} service{division.services.length > 1 ? "s" : ""}</Badge>
                  </div>
                  {isEditMode ? (
                    <div className="space-y-2">
                      <Input
                        value={division.title}
                        onChange={(event) => updateDivisionField(division.id, "title", event.target.value)}
                        onClick={(event) => event.stopPropagation()}
                      />
                      <Textarea
                        value={division.description}
                        onChange={(event) => updateDivisionField(division.id, "description", event.target.value)}
                        onClick={(event) => event.stopPropagation()}
                        rows={2}
                      />
                    </div>
                  ) : (
                    <p className="text-sm text-muted-foreground">{division.description}</p>
                  )}
                </div>
              </AccordionTrigger>
              <AccordionContent className="px-5 pb-5">
                {isEditMode ? (
                  <div className="mb-4">
                    <Button type="button" variant="outline" onClick={() => addService(division.id)}>
                      <Plus className="mr-2 h-4 w-4" />
                      Ajouter un service
                    </Button>
                  </div>
                ) : null}
                <Accordion
                  type="multiple"
                  defaultValue={division.services.map((service) => service.id)}
                  className="space-y-3"
                >
                  {division.services.map((service) => (
                    <AccordionItem key={service.id} value={service.id} className="rounded-xl border bg-white/90 px-4">
                      <AccordionTrigger className="hover:no-underline">
                        <div className="space-y-1">
                          <div className="flex flex-wrap items-center gap-2">
                            <span className="font-medium">{service.title}</span>
                            <Badge variant="outline">
                              {service.contacts.length > 0 ? `${service.contacts.length} contact${service.contacts.length > 1 ? "s" : ""}` : "À compléter"}
                            </Badge>
                          </div>
                          {isEditMode ? (
                            <div className="space-y-2" onClick={(event) => event.stopPropagation()}>
                              <Input
                                value={service.title}
                                onChange={(event) => updateServiceField(division.id, service.id, "title", event.target.value)}
                              />
                              <Textarea
                                value={service.description}
                                onChange={(event) => updateServiceField(division.id, service.id, "description", event.target.value)}
                                rows={2}
                              />
                            </div>
                          ) : (
                            <p className="text-sm text-muted-foreground">{service.description}</p>
                          )}
                        </div>
                      </AccordionTrigger>
                      <AccordionContent>
                        {service.contacts.length > 0 ? (
                          <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3">
                            {service.contacts.map((contact, contactIndex) => (
                              <Card key={`${division.id}-${service.id}-${contactIndex}`} className="h-full border-primary/10 shadow-sm">
                                <CardContent className="space-y-3 p-4">
                                  {isEditMode ? (
                                    <div className="space-y-3">
                                      <div className="flex items-center justify-between gap-2">
                                        <p className="font-medium">Contact {contactIndex + 1}</p>
                                        <Button
                                          type="button"
                                          variant="ghost"
                                          size="icon"
                                          onClick={() => removeContact(division.id, service.id, contactIndex)}
                                        >
                                          <Trash2 className="h-4 w-4" />
                                        </Button>
                                      </div>
                                      <Input
                                        value={contact.name}
                                        onChange={(event) => updateContactField(division.id, service.id, contactIndex, "name", event.target.value)}
                                        placeholder="Nom"
                                      />
                                      <Input
                                        value={contact.role}
                                        onChange={(event) => updateContactField(division.id, service.id, contactIndex, "role", event.target.value)}
                                        placeholder="Fonction"
                                      />
                                      <Input
                                        value={contact.email || ""}
                                        onChange={(event) => updateContactField(division.id, service.id, contactIndex, "email", event.target.value)}
                                        placeholder="Email"
                                      />
                                      <Input
                                        value={contact.phone || ""}
                                        onChange={(event) => updateContactField(division.id, service.id, contactIndex, "phone", event.target.value)}
                                        placeholder="Téléphone fixe"
                                      />
                                      <Input
                                        value={contact.mobile || ""}
                                        onChange={(event) => updateContactField(division.id, service.id, contactIndex, "mobile", event.target.value)}
                                        placeholder="Portable"
                                      />
                                      <Input
                                        value={contact.extension || ""}
                                        onChange={(event) => updateContactField(division.id, service.id, contactIndex, "extension", event.target.value)}
                                        placeholder="Poste"
                                      />
                                    </div>
                                  ) : (
                                    <>
                                      <div>
                                        <p className="font-semibold">{contact.name}</p>
                                        <p className="text-sm text-muted-foreground">{contact.role}</p>
                                      </div>
                                      <div className="space-y-2 text-sm">
                                        <div className="flex items-start gap-2">
                                          <Mail className="mt-0.5 h-4 w-4 text-muted-foreground" />
                                          {contact.email ? (
                                            <a href={`mailto:${contact.email}`} className="break-all text-primary hover:underline">
                                              {contact.email}
                                            </a>
                                          ) : (
                                            <span className="text-muted-foreground">Non renseigné</span>
                                          )}
                                        </div>
                                        <div className="flex items-start gap-2">
                                          <Phone className="mt-0.5 h-4 w-4 text-muted-foreground" />
                                          <span>{formatContactRow(contact.phone)}</span>
                                        </div>
                                        <div className="flex items-start gap-2">
                                          <Smartphone className="mt-0.5 h-4 w-4 text-muted-foreground" />
                                          <span>{formatContactRow(contact.mobile)}</span>
                                        </div>
                                        {contact.extension ? (
                                          <div className="flex items-start gap-2">
                                            <Users className="mt-0.5 h-4 w-4 text-muted-foreground" />
                                            <span>Poste {contact.extension}</span>
                                          </div>
                                        ) : null}
                                      </div>
                                    </>
                                  )}
                                </CardContent>
                              </Card>
                            ))}
                          </div>
                        ) : (
                          <Card className="border-dashed">
                            <CardContent className="p-5 text-sm text-muted-foreground">
                              Ce service est déjà visible dans l’annuaire pour garder la bonne structure CCDS. Les contacts détaillés peuvent être complétés ensuite.
                            </CardContent>
                          </Card>
                        )}
                        {isEditMode ? (
                          <div className="mt-3">
                            <Button type="button" variant="outline" onClick={() => addContact(division.id, service.id)}>
                              <Plus className="mr-2 h-4 w-4" />
                              Ajouter un nouveau contact
                            </Button>
                          </div>
                        ) : null}
                      </AccordionContent>
                    </AccordionItem>
                  ))}
                </Accordion>
              </AccordionContent>
            </AccordionItem>
          ))}
        </Accordion>
      )}
    </div>
  );
}
