"use client";

import { type FormEvent, useEffect, useState } from "react";
import { useRouter, useParams } from "next/navigation";
import { Salarie, Alerte, User, Contrat } from "@/types/type";
import EtatCivil from "@/components/employes/EtatCivil";
import Link from "next/link";
import Contrats from "@/components/employes/Contrats";
import AbsencePanel from "@/components/employes/AbsencesPanel";
import AbsencesTab from "@/components/employes/AbsencesTab";
import { Absence } from "@/types/type";
import AlertesTab from "@/components/employes/AlertesTab";
import { useSearchParams } from "next/navigation";
import Image from "next/image";
import VisitesMedicalesTab from "@/components/employes/VisitesMedicalesTab";
import DisciplinairesTab from "@/components/employes/DisciplinairesTab";
import FichesPaieTab from "@/components/employes/FichesPaieTab";
import AutresTab from "@/components/employes/AutresTab";
import { formatDate } from "@/utils/formatter";

type NouveauSalarieForm = {
  TIT: "Monsieur" | "Madame";
  NSA: string;
  PRE: string;
};

const NOUVEAU_SALARIE_INITIAL: NouveauSalarieForm = {
  TIT: "Monsieur",
  NSA: "",
  PRE: "",
};

type TabId =
  | "etat-civil"
  | "contrats"
  | "absences"
  | "alertes"
  | "visites-medicales"
  | "sanctions"
  | "fiches-paie"
  | "autres";

type PermissionKey =
  | "alertes"
  | "etat_civil"
  | "contrats"
  | "absences"
  | "visites_medicales"
  | "sanctions"
  | "fiches_paie"
  | "impressions"
  | "autres";

type EmployeePageUser = User & {
  access?: {
    permissions?: Partial<
      Record<PermissionKey, { canRead: boolean; canWrite: boolean }>
    >;
  };
};

const TAB_PERMISSIONS: Record<TabId, PermissionKey> = {
  alertes: "alertes",
  "etat-civil": "etat_civil",
  contrats: "contrats",
  absences: "absences",
  "visites-medicales": "visites_medicales",
  sanctions: "sanctions",
  "fiches-paie": "fiches_paie",
  autres: "autres",
};

export default function EmployeDetailsPage() {
  const router = useRouter();
  const [user, setUser] = useState<EmployeePageUser | null>(null);
  const [salaries, setSalaries] = useState<Salarie[]>([]);
  const [salarie, setSalarie] = useState<Salarie | null>(null);
  const [search, setSearch] = useState("");
  const [activeTab, setActiveTab] = useState<TabId>("etat-civil");
  const [absences, setAbsences] = useState<Absence[]>([]);
  const [selectedAbsence, setSelectedAbsence] = useState<Absence | null>(null);
  const [isAbsenceOpen, setIsAbsenceOpen] = useState(false);
  const [nouveauSalarieOpen, setNouveauSalarieOpen] = useState(false);
  const [nouveauSalarie, setNouveauSalarie] = useState<NouveauSalarieForm>(
    NOUVEAU_SALARIE_INITIAL,
  );
  const [creationEnCours, setCreationEnCours] = useState(false);
  const [suppressionEnCours, setSuppressionEnCours] = useState(false);
  const [actionError, setActionError] = useState<string | null>(null);
  const [contratActif, setContratActif] = useState<Contrat | null>(null);
  const [contratsRevision, setContratsRevision] = useState(0);
  const params = useParams();
  const cos = params.id;
  const cosAlerte = Array.isArray(params.id) ? params.id[0] : (params.id ?? "");
  const nombreSalaries = salaries?.length ?? 0;
  const searchParams = useSearchParams();
  const tabParam = searchParams.get("tab");

  const tabs: { id: TabId; label: string }[] = [
    { id: "alertes", label: "Alertes" },
    { id: "etat-civil", label: "État Civil" },
    { id: "contrats", label: "Contrats" },
    { id: "absences", label: "Absences" },
    { id: "visites-medicales", label: "Visites médicales" },
    { id: "sanctions", label: "Sanctions" },
    { id: "fiches-paie", label: "Fiches de paie" },
    { id: "autres", label: "Autres" },
  ];

  const visibleTabs = tabs.filter(
    (tab) =>
      user?.role === "super_admin" ||
      user?.access?.permissions?.[TAB_PERMISSIONS[tab.id]]?.canRead === true,
  );
  const canWriteEtatCivil =
    user?.role === "super_admin" ||
    user?.access?.permissions?.etat_civil?.canWrite === true;
  const canReadImpressions =
    user?.role === "super_admin" ||
    user?.access?.permissions?.impressions?.canRead === true;
  const canWriteAutres =
    user?.role === "super_admin" ||
    user?.access?.permissions?.autres?.canWrite === true;

  console.log("SALARIE DETAIL =", salarie);

  useEffect(() => {
    const allowedTabs: TabId[] = [
      "etat-civil",
      "contrats",
      "absences",
      "alertes",
      "visites-medicales",
      "sanctions",
      "fiches-paie",
      "autres",
    ];

    if (
      tabParam &&
      allowedTabs.includes(tabParam as TabId) &&
      visibleTabs.some((tab) => tab.id === tabParam)
    ) {
      setActiveTab(tabParam as TabId);
    }
  }, [tabParam, user]);

  useEffect(() => {
    if (!user || visibleTabs.length === 0) return;
    if (!visibleTabs.some((tab) => tab.id === activeTab)) {
      setActiveTab(visibleTabs[0].id);
    }
  }, [user, activeTab]);

  function handleUnauthorized(response: Response) {
    if (response.status === 401) {
      localStorage.removeItem("token");
      localStorage.removeItem("user");
      router.push("/login");
      return true;
    }

    return false;
  }

  const nbSalariesEnCours = salaries.filter((s) => s.Actif === true).length;

  useEffect(() => {
    async function fetchSalarie() {
      const token = localStorage.getItem("token");

      const response = await fetch(
        `${process.env.NEXT_PUBLIC_API_URL}/api/employes/${cos}`,
        {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        },
      );

      if (handleUnauthorized(response)) return;

      const data = await response.json();
      setSalarie(data.employe ?? null);
    }

    fetchSalarie();
  }, [cos]);

  useEffect(() => {
    async function fetchContratActif() {
      if (!cosAlerte) {
        setContratActif(null);
        return;
      }

      const token = localStorage.getItem("token");
      const response = await fetch(
        `${process.env.NEXT_PUBLIC_API_URL}/api/employes/${cosAlerte}/contrats`,
        {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        },
      );

      if (handleUnauthorized(response)) return;

      if (!response.ok) {
        setContratActif(null);
        return;
      }

      const data = await response.json();
      const contratsEmploye: Contrat[] = Array.isArray(data.items)
        ? data.items
        : [];

      const today = new Date();
      today.setHours(0, 0, 0, 0);

      const hasStarted = (contrat: Contrat) => {
        if (!contrat.DAE) return true;

        const dateEmbauche = new Date(contrat.DAE);

        if (Number.isNaN(dateEmbauche.getTime())) return false;

        dateEmbauche.setHours(0, 0, 0, 0);
        return dateEmbauche <= today;
      };

      const contratsCommences = contratsEmploye
        .filter(hasStarted)
        .sort((left, right) => {
          const leftDate = left.DAE ? new Date(left.DAE).getTime() : 0;
          const rightDate = right.DAE ? new Date(right.DAE).getTime() : 0;

          return rightDate - leftDate || right.id - left.id;
        });

      const dernierContratCommence =
        contratsCommences[0] ?? contratsEmploye[0] ?? null;

      setContratActif(dernierContratCommence);

      const cosNumber = Number(cosAlerte);
      const etablissement =
        dernierContratCommence?.ETB?.trim().toLocaleUpperCase("fr") ?? "";
      const hasActiveContrat =
        dernierContratCommence != null &&
        dernierContratCommence.DSR == null &&
        ["LESQUIN", "ENVIE LESQUIN"].includes(etablissement);

      setSalaries((current) =>
        current.map((item) =>
          Number(item.COS) === cosNumber
            ? { ...item, Actif: hasActiveContrat }
            : item,
        ),
      );
    }

    void fetchContratActif();
  }, [cosAlerte, contratsRevision]);

  useEffect(() => {
    async function fetchSalaries() {
      const token = localStorage.getItem("token");

      const response = await fetch(
        `${process.env.NEXT_PUBLIC_API_URL}/api/employes`,
        {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        },
      );

      if (handleUnauthorized(response)) return;

      const data = await response.json();
      setSalaries(data.items ?? []);
    }

    fetchSalaries();
  }, []);

  const salariesUniques = Array.from(
    salaries
      .reduce((parCos, current) => {
        const cosKey = String(current.COS);
        const existing = parCos.get(cosKey);

        if (!existing || (existing.Actif !== true && current.Actif === true)) {
          parCos.set(cosKey, current);
        }

        return parCos;
      }, new Map<string, Salarie>())
      .values(),
  );

  const filteredSalaries = salariesUniques.filter((salarie) => {
    const fullName = `${salarie.NSA ?? ""} ${salarie.PRE ?? ""}`.toLowerCase();
    return fullName.includes(search.toLowerCase());
  });

  async function handleCreateSalarie(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setActionError(null);

    const nom = nouveauSalarie.NSA.trim();
    const prenom = nouveauSalarie.PRE.trim();

    if (!nom || !prenom) {
      setActionError("Le nom et le prénom sont obligatoires.");
      return;
    }

    setCreationEnCours(true);

    try {
      const token = localStorage.getItem("token");

      const response = await fetch(
        `${process.env.NEXT_PUBLIC_API_URL}/api/employes`,
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${token}`,
          },
          body: JSON.stringify({
            TIT: nouveauSalarie.TIT,
            NSA: nom.toLocaleUpperCase("fr"),
            PRE: prenom.toLocaleUpperCase("fr"),
          }),
        },
      );

      if (handleUnauthorized(response)) return;

      const data = await response.json().catch(() => null);

      if (!response.ok) {
        throw new Error(data?.message ?? "Impossible de créer le salarié.");
      }

      const employeCree = data?.employe as Salarie | undefined;

      if (!employeCree?.COS) {
        throw new Error(
          "Le salarié a été créé, mais la réponse de l'API est incomplète.",
        );
      }

      setSalaries((current) =>
        [...current, employeCree].sort((left, right) => {
          const nomCompare = (left.NSA ?? "").localeCompare(
            right.NSA ?? "",
            "fr",
          );

          return (
            nomCompare || (left.PRE ?? "").localeCompare(right.PRE ?? "", "fr")
          );
        }),
      );
      setNouveauSalarieOpen(false);
      setNouveauSalarie(NOUVEAU_SALARIE_INITIAL);
      router.push(`/employes/${employeCree.COS}`);
    } catch (error) {
      setActionError(
        error instanceof Error
          ? error.message
          : "Une erreur inattendue est survenue.",
      );
    } finally {
      setCreationEnCours(false);
    }
  }

  async function handleDeleteSalarie() {
    if (!salarie || suppressionEnCours) return;

    const nomComplet =
      [salarie.PRE, salarie.NSA].filter(Boolean).join(" ") ||
      `COS ${salarie.COS}`;

    const confirmed = window.confirm(
      `Supprimer définitivement le dossier de ${nomComplet} ?\n\n` +
      "La suppression sera refusée si des contrats ou d'autres données RH sont liés à ce salarié.",
    );

    if (!confirmed) return;

    setSuppressionEnCours(true);
    setActionError(null);

    try {
      const token = localStorage.getItem("token");

      const response = await fetch(
        `${process.env.NEXT_PUBLIC_API_URL}/api/employes/${salarie.COS}`,
        {
          method: "DELETE",
          headers: {
            Authorization: `Bearer ${token}`,
          },
        },
      );

      if (handleUnauthorized(response)) return;

      const data = await response.json().catch(() => null);

      if (!response.ok) {
        if (response.status === 409) {
          throw new Error(
            "Ce salarié possède déjà un contrat ou des données RH liées. " +
            "Il doit être déclaré sorti/inactif plutôt que supprimé.",
          );
        }

        throw new Error(data?.message ?? "Impossible de supprimer le salarié.");
      }

      const remainingSalaries = salaries.filter(
        (item) => item.COS !== salarie.COS,
      );

      setSalaries(remainingSalaries);
      setSalarie(null);

      const nextSalarie =
        remainingSalaries.find((item) => item.Actif === true) ??
        remainingSalaries[0];

      router.push(
        nextSalarie?.COS ? `/employes/${nextSalarie.COS}` : "/dashboard",
      );
    } catch (error) {
      setActionError(
        error instanceof Error
          ? error.message
          : "Une erreur inattendue est survenue.",
      );
    } finally {
      setSuppressionEnCours(false);
    }
  }

  useEffect(() => {
    const token = localStorage.getItem("token");

    if (!token) {
      router.push("/login");
      return;
    }

    fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/auth/me`, {
      headers: { Authorization: `Bearer ${token}` },
      cache: "no-store",
    })
      .then(async (response) => {
        if (!response.ok) throw new Error("Session invalide");
        return response.json();
      })
      .then((data) => {
        setUser(data.user);
        localStorage.setItem("user", JSON.stringify(data.user));
      })
      .catch(() => {
        localStorage.removeItem("token");
        localStorage.removeItem("user");
        router.push("/login");
      });
  }, [router]);

  const handleLogout = () => {
    localStorage.removeItem("token");
    localStorage.removeItem("user");

    window.location.href = "/login";
  };

  return (
    <main className="h-screen overflow-hidden bg-slate-100 p-2">
      <header className="mb-2 flex items-center justify-between border border-sky-300 bg-sky-100 px-3 py-1 text-xs text-slate-800">
        <div className="flex items-center gap-3">
          <Image
            src="/RHconnect.png"
            alt="Logo Envie"
            width={45}
            height={45}
            priority
          />

          <h1 className="text-xl font-bold uppercase tracking-wide text-slate-700">
            {[salarie?.PRE, salarie?.NSA].filter(Boolean).join(" ")}
          </h1>
        </div>

        <div className="flex items-center gap-8">
          <div className="text-right">
            <p>
              <span className="font-semibold">Contrat :</span>{" "}
              {contratActif?.TCS ?? "-"}
            </p>
            <p>
              <span className="font-semibold">Équipe :</span>{" "}
              {contratActif?.Secteur ?? "-"}
            </p>
          </div>

          <div className="text-right">
            <p>
              <span className="font-semibold">Date Emb. :</span>{" "}
              {formatDate(contratActif?.DAE)}
            </p>
            <p>
              <span className="font-semibold">Date Sortie Prev. :</span>{" "}
              {formatDate(contratActif?.DSP)}
            </p>
          </div>

          {canReadImpressions && (
            <div className="flex items-center gap-2">
              <button
                type="button"
                onClick={() =>
                  router.push(
                    `/impressions/documents-automatiques?cos=${encodeURIComponent(cosAlerte)}`,
                  )
                }
                title="Générer un document automatique pour ce salarié"
                className="rounded border border-blue-500 bg-white px-4 py-2 font-semibold text-blue-600 shadow-sm transition hover:bg-blue-50"
              >
                Documents
              </button>
              <button
                type="button"
                onClick={() => router.push("/impressions/salaries-en-cours")}
                title="Afficher la liste imprimable des salariés en cours"
                className="rounded border bg-white px-4 py-1 text-center shadow-sm transition hover:bg-sky-50 hover:ring-2 hover:ring-sky-300"
              >
                <p className="text-[11px] text-slate-600">Salariés en cours</p>
                <p className="font-bold text-black">{nbSalariesEnCours}</p>
              </button>
            </div>
          )}

          <button
            type="button"
            onClick={() => router.push("/dashboard")}
            className="rounded border border-blue-500 bg-white px-4 py-2 font-semibold text-blue-600 shadow transition hover:bg-blue-50"
          >
            Tableau de bord
          </button>

          <button
            type="button"
            onClick={handleLogout} className="rounded bg-blue-500 px-5 py-2 font-semibold text-white shadow hover:bg-blue-600">
            Quitter
          </button>
        </div>
      </header>

      <div className="grid h-[calc(100vh-80px)] grid-cols-[260px_1fr] gap-2 overflow-hidden">
        {/* Liste salariés */}
        <section className="grid min-h-0 grid-rows-[auto_minmax(0,1fr)_auto] rounded bg-white p-2 shadow">
          <input
            type="text"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="mb-2 w-full border border-slate-400 px-2 py-1 text-sm text-black"
          />

          <ul className="min-h-0 overflow-y-auto text-sm">
            {filteredSalaries.map((salarie) => (
              <li key={salarie.COS}>
                <Link
                  href={`/employes/${salarie.COS}`}
                  className="group relative grid grid-cols-[110px_1fr] overflow-visible px-1 py-0.5 text-black hover:bg-black hover:text-white"
                >
                  <span className="relative z-0 whitespace-nowrap">
                    {salarie.NSA}
                  </span>

                  <span className="relative z-10 whitespace-nowrap bg-white pl-2 group-hover:bg-black">
                    {salarie.PRE}
                  </span>
                </Link>
              </li>
            ))}
          </ul>

          {canWriteEtatCivil && (
            <div className="mt-2 grid grid-cols-2 gap-1">
              <button
                type="button"
                onClick={() => {
                  setActionError(null);
                  setNouveauSalarie(NOUVEAU_SALARIE_INITIAL);
                  setNouveauSalarieOpen(true);
                }}
                className="rounded bg-blue-500 px-2 py-1 text-xs font-semibold text-white hover:bg-blue-600"
              >
                Nouveau salarié
              </button>
              <button
                type="button"
                onClick={() => void handleDeleteSalarie()}
                disabled={!salarie || suppressionEnCours}
                className="rounded bg-red-600 px-2 py-1 text-xs font-semibold text-white hover:bg-red-700 disabled:cursor-not-allowed disabled:bg-red-300"
              >
                {suppressionEnCours ? "Suppression..." : "Supprimer salarié"}
              </button>
            </div>
          )}

          {actionError && !nouveauSalarieOpen && (
            <p
              role="alert"
              className="mt-2 rounded border border-red-300 bg-red-50 p-2 text-xs text-red-700"
            >
              {actionError}
            </p>
          )}
        </section>

        {/* Contenu fiche salarié */}
        <section className="grid min-h-0 grid-cols-[130px_1fr] gap-4 overflow-hidden rounded bg-white p-4 shadow">
          <nav className="flex flex-col gap-2">
            {visibleTabs.map((tab) => (
              <button
                key={tab.id}
                type="button"
                onClick={() => setActiveTab(tab.id)}
                className={`rounded px-3 py-3 text-sm font-semibold text-white transition-colors ${activeTab === tab.id
                    ? "bg-sky-700"
                    : "bg-sky-500 hover:bg-sky-600"
                  }`}
              >
                {tab.label}
              </button>
            ))}
          </nav>

          <div className="min-h-0 overflow-hidden">
            {visibleTabs.length === 0 && (
              <p className="rounded bg-amber-50 p-4 text-amber-800">
                Aucun onglet n’est autorisé pour ce compte.
              </p>
            )}
            {activeTab === "etat-civil" && <EtatCivil salarie={salarie} />}
            {activeTab === "contrats" && (
              <Contrats
                salarie={salarie}
                onContratsChange={() =>
                  setContratsRevision((current) => current + 1)
                }
              />
            )}
            {activeTab === "absences" && <AbsencesTab salarie={salarie} />}
            {activeTab === "alertes" && <AlertesTab cos={cosAlerte} />}
            {activeTab === "visites-medicales" && (
              <VisitesMedicalesTab salarie={salarie} />
            )}
            {activeTab === "sanctions" && (
              <DisciplinairesTab salarie={salarie} />
            )}
            {activeTab === "fiches-paie" && (
              <FichesPaieTab
                salarie={salarie}
                defaultEstablishment={contratActif?.ETB}
              />
            )}
            {activeTab === "autres" && (
              <AutresTab
                salarie={salarie}
                currentUsername={user?.username ?? ""}
                canWrite={canWriteAutres}
              />
            )}
          </div>
        </section>
      </div>

      {nouveauSalarieOpen && (
        <div
          className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4"
          role="dialog"
          aria-modal="true"
          aria-labelledby="nouveau-salarie-title"
        >
          <form
            onSubmit={handleCreateSalarie}
            className="w-full max-w-md rounded-lg bg-white p-5 text-sm text-slate-900 shadow-xl"
          >
            <h2
              id="nouveau-salarie-title"
              className="text-lg font-bold text-blue-700"
            >
              Créer un nouveau salarié
            </h2>

            <p className="mt-1 text-xs text-slate-500">
              Les autres informations pourront être renseignées dans
              l&apos;onglet État Civil après la création.
            </p>

            <div className="mt-4 space-y-3">
              <label className="block">
                <span className="mb-1 block font-semibold">Civilité</span>
                <select
                  value={nouveauSalarie.TIT}
                  onChange={(event) =>
                    setNouveauSalarie((current) => ({
                      ...current,
                      TIT: event.target.value as "Monsieur" | "Madame",
                    }))
                  }
                  className="w-full rounded border border-slate-300 bg-white px-3 py-2 text-black"
                >
                  <option value="Monsieur">Monsieur</option>
                  <option value="Madame">Madame</option>
                </select>
              </label>

              <label className="block">
                <span className="mb-1 block font-semibold">Nom *</span>
                <input
                  type="text"
                  maxLength={150}
                  required
                  autoFocus
                  value={nouveauSalarie.NSA}
                  onChange={(event) =>
                    setNouveauSalarie((current) => ({
                      ...current,
                      NSA: event.target.value,
                    }))
                  }
                  className="w-full rounded border border-slate-300 px-3 py-2 text-black"
                />
              </label>

              <label className="block">
                <span className="mb-1 block font-semibold">Prénom *</span>
                <input
                  type="text"
                  maxLength={150}
                  required
                  value={nouveauSalarie.PRE}
                  onChange={(event) =>
                    setNouveauSalarie((current) => ({
                      ...current,
                      PRE: event.target.value,
                    }))
                  }
                  className="w-full rounded border border-slate-300 px-3 py-2 text-black"
                />
              </label>
            </div>

            {actionError && (
              <p
                role="alert"
                className="mt-3 rounded border border-red-300 bg-red-50 p-2 text-xs text-red-700"
              >
                {actionError}
              </p>
            )}

            <div className="mt-5 flex justify-end gap-2">
              <button
                type="button"
                onClick={() => {
                  setNouveauSalarieOpen(false);
                  setNouveauSalarie(NOUVEAU_SALARIE_INITIAL);
                  setActionError(null);
                }}
                disabled={creationEnCours}
                className="rounded border border-slate-300 bg-white px-4 py-2 font-semibold hover:bg-slate-50 disabled:cursor-wait"
              >
                Annuler
              </button>

              <button
                type="submit"
                disabled={creationEnCours}
                className="rounded bg-blue-600 px-4 py-2 font-semibold text-white hover:bg-blue-700 disabled:cursor-wait disabled:bg-blue-300"
              >
                {creationEnCours ? "Création..." : "Créer le salarié"}
              </button>
            </div>
          </form>
        </div>
      )}
    </main>
  );
}
