"use client";

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

type GroupeAlerte =
    | "cisp"
    | "direction"
    | "adm"
    | "logistique"
    | "atelier";

type MessageAlerte = {
    id: number;
    message: string;
    urgent: boolean;
};

type SectionAlerte = {
    category: string;
    order: number;
    messages: MessageAlerte[];
};

type StatistiquesApercu = {
    sourceMessages: number;
    matchedMessages: number;
    includedMessages: number;
    includedSections: number;
    unmatchedCategories: string[];
    invalidRecipientCount: number;
};

type ApercuMailAlertes = {
    subject: string;
    group: GroupeAlerte;
    groupLabel: string;
    recipients: string[];
    sections: SectionAlerte[];
    html: string;
    canSend: boolean;
    generatedAt: string;
    source: string;
    stats: StatistiquesApercu;
    warnings: string[];
};

type ReponseApercu = {
    item?: ApercuMailAlertes;
    message?: string;
};

type ReponseEnvoiTest = {
    message?: string;
    item?: {
        messageId: string;
        recipient: string;
        subject: string;
        sentAt: string;
        anonymized: true;
    };
};

const GROUPES: Array<{ value: GroupeAlerte; label: string }> = [
    { value: "cisp", label: "CISP" },
    { value: "direction", label: "Direction" },
    { value: "adm", label: "Administratif" },
    { value: "logistique", label: "Logistique" },
    { value: "atelier", label: "Atelier" },
];

function formatDateHeure(value: string) {
    const date = new Date(value);

    if (Number.isNaN(date.getTime())) {
        return "-";
    }

    return new Intl.DateTimeFormat("fr-FR", {
        dateStyle: "short",
        timeStyle: "medium",
    }).format(date);
}

function formatDateCourte(value: string) {
    const [annee, mois, jour] = value.split("-");

    if (!annee || !mois || !jour) {
        return "-";
    }

    return `${jour}/${mois}/${annee}`;
}

function getDateParis() {
    const parts = new Intl.DateTimeFormat("fr-CA", {
        timeZone: "Europe/Paris",
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
    }).formatToParts(new Date());

    const getPart = (type: "year" | "month" | "day") =>
        parts.find((part) => part.type === type)?.value ?? "";

    return `${getPart("year")}-${getPart("month")}-${getPart("day")}`;
}

export default function AlertesMailsPage() {
    const [groupe, setGroupe] = useState<GroupeAlerte>("cisp");
    const [dateSaisie, setDateSaisie] = useState("");
    const [dateSimulation, setDateSimulation] = useState("");
    const [dateInitialisee, setDateInitialisee] = useState(false);
    const [apercu, setApercu] = useState<ApercuMailAlertes | null>(null);
    const [chargement, setChargement] = useState(true);
    const [erreur, setErreur] = useState<string | null>(null);
    const [envoiTestEnCours, setEnvoiTestEnCours] = useState(false);
    const [messageEnvoiTest, setMessageEnvoiTest] = useState<string | null>(
        null
    );
    const [erreurEnvoiTest, setErreurEnvoiTest] = useState<string | null>(null);

    useEffect(() => {
        const dateUrl = new URLSearchParams(window.location.search).get("date");
        const dateInitiale = dateUrl || getDateParis();

        setDateSaisie(dateInitiale);
        setDateSimulation(dateInitiale);
        setDateInitialisee(true);
    }, []);

    const chargerApercu = useCallback(async () => {
        if (!dateInitialisee) {
            return;
        }

        setChargement(true);
        setErreur(null);

        try {
            const token = localStorage.getItem("token");
            const apiUrl = process.env.NEXT_PUBLIC_API_URL;

            if (!token) {
                throw new Error(
                    "Session introuvable. Reconnecte-toi avant de charger l'aperçu."
                );
            }

            if (!apiUrl) {
                throw new Error(
                    "La variable NEXT_PUBLIC_API_URL n'est pas configurée."
                );
            }

            const queryParams = new URLSearchParams({
                groupe,
                date: dateSimulation,
            });

            const response = await fetch(
                `${apiUrl}/api/alertes-mails/preview?${queryParams.toString()}`,
                {
                    headers: {
                        Authorization: `Bearer ${token}`,
                    },
                    cache: "no-store",
                }
            );

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

            if (!response.ok) {
                if (response.status === 401) {
                    throw new Error(
                        "Ta session a expiré. Reconnecte-toi puis réessaie."
                    );
                }

                throw new Error(
                    data?.message ??
                        `Impossible de charger l'aperçu (erreur ${response.status}).`
                );
            }

            if (!data?.item) {
                throw new Error("La réponse de l'API ne contient aucun aperçu.");
            }

            setApercu(data.item);
        } catch (error) {
            setApercu(null);
            setErreur(
                error instanceof Error
                    ? error.message
                    : "Une erreur inattendue est survenue."
            );
        } finally {
            setChargement(false);
        }
    }, [dateInitialisee, dateSimulation, groupe]);

    useEffect(() => {
        void chargerApercu();
    }, [chargerApercu]);

    function appliquerDateSimulation(date: string) {
        if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
            setErreur("Choisis une date de simulation valide.");
            return;
        }

        const url = new URL(window.location.href);
        url.searchParams.set("date", date);
        window.history.replaceState(null, "", url.toString());

        setDateSaisie(date);
        setDateSimulation(date);
    }

    async function envoyerMailTest() {
        const confirmation = window.confirm(
            "Envoyer un mail de test anonymisé via Microsoft Graph aux adresses définies dans ALERT_MAIL_GRAPH_TEST_RECIPIENTS ?"
        );

        if (!confirmation) {
            return;
        }

        setEnvoiTestEnCours(true);
        setMessageEnvoiTest(null);
        setErreurEnvoiTest(null);

        try {
            const token = localStorage.getItem("token");
            const apiUrl = process.env.NEXT_PUBLIC_API_URL;

            if (!token) {
                throw new Error(
                    "Session introuvable. Reconnecte-toi avant l'envoi."
                );
            }

            if (!apiUrl) {
                throw new Error(
                    "La variable NEXT_PUBLIC_API_URL n'est pas configurée."
                );
            }

            const response = await fetch(
                `${apiUrl}/api/alertes-mails/test`,
                {
                    method: "POST",
                    headers: {
                        Authorization: `Bearer ${token}`,
                        "Content-Type": "application/json",
                    },
                    body: JSON.stringify({
                        groupe,
                        confirmation: "ENVOYER_TEST",
                    }),
                }
            );

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

            if (!response.ok) {
                throw new Error(
                    data?.message ??
                        `Impossible d'envoyer le mail de test (erreur ${response.status}).`
                );
            }

            setMessageEnvoiTest(
                data?.message ??
                    "Le mail de test anonymisé a été envoyé via Microsoft Graph."
            );
        } catch (error) {
            setErreurEnvoiTest(
                error instanceof Error
                    ? error.message
                    : "Une erreur inattendue est survenue pendant l'envoi."
            );
        } finally {
            setEnvoiTestEnCours(false);
        }
    }

    const nombreUrgent = useMemo(
        () =>
            apercu?.sections.reduce(
                (total, section) =>
                    total +
                    section.messages.filter((message) => message.urgent).length,
                0
            ) ?? 0,
        [apercu]
    );

    return (
        <main className="min-h-screen bg-slate-100 p-4 text-slate-900 sm:p-6">
            <div className="mx-auto flex max-w-[1600px] flex-col gap-4">
                <header className="flex flex-col gap-3 rounded-lg bg-white p-4 shadow sm:flex-row sm:items-center sm:justify-between">
                    <div>
                        <div className="flex flex-wrap items-center gap-2">
                            <h1 className="text-2xl font-bold text-blue-700">
                                Prévisualisation des mails d&apos;alertes
                            </h1>
                            <span className="rounded-full bg-amber-100 px-3 py-1 text-xs font-semibold text-amber-800">
                                Mode test — aucun envoi RH réel
                            </span>
                        </div>
                        <p className="mt-1 text-sm text-slate-500">
                            Vérifie les destinataires et le contenu qui seront
                            utilisés lors du futur envoi automatique.
                        </p>
                    </div>

                    <div className="flex flex-wrap gap-2">
                        <Link
                            href="/parametres"
                            className="w-fit rounded border border-blue-500 bg-white px-4 py-2 text-sm font-semibold text-blue-600 hover:bg-blue-50"
                        >
                            Retour aux paramètres
                        </Link>
                        <Link
                            href="/dashboard"
                            className="w-fit rounded border border-slate-300 bg-white px-4 py-2 text-sm font-semibold text-slate-700 hover:bg-slate-50"
                        >
                            Retour au tableau de bord
                        </Link>
                    </div>
                </header>

                <section className="rounded-lg bg-white p-4 shadow">
                    <div className="flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-end">
                        <label className="flex min-w-64 flex-col gap-1 text-sm font-semibold text-slate-700">
                            Groupe destinataire
                            <select
                                value={groupe}
                                onChange={(event) =>
                                    setGroupe(
                                        event.target.value as GroupeAlerte
                                    )
                                }
                                disabled={chargement}
                                className="rounded border border-slate-300 bg-white px-3 py-2 font-normal text-black disabled:cursor-wait disabled:bg-slate-100"
                            >
                                {GROUPES.map((option) => (
                                    <option
                                        key={option.value}
                                        value={option.value}
                                    >
                                        {option.label}
                                    </option>
                                ))}
                            </select>
                        </label>

                        <label className="flex flex-col gap-1 text-sm font-semibold text-slate-700">
                            Date de simulation
                            <input
                                type="date"
                                value={dateSaisie}
                                onChange={(event) =>
                                    setDateSaisie(event.target.value)
                                }
                                disabled={!dateInitialisee || chargement}
                                className="rounded border border-slate-300 bg-white px-3 py-2 font-normal text-black disabled:cursor-wait disabled:bg-slate-100"
                            />
                        </label>

                        <button
                            type="button"
                            onClick={() =>
                                appliquerDateSimulation(dateSaisie)
                            }
                            disabled={
                                !dateInitialisee ||
                                chargement ||
                                !dateSaisie ||
                                dateSaisie === dateSimulation
                            }
                            className="rounded bg-sky-600 px-5 py-2 font-semibold text-white shadow hover:bg-sky-700 disabled:cursor-not-allowed disabled:bg-sky-300"
                        >
                            Simuler cette date
                        </button>

                        <button
                            type="button"
                            onClick={() => appliquerDateSimulation(getDateParis())}
                            disabled={!dateInitialisee || chargement}
                            className="rounded border border-slate-300 bg-white px-4 py-2 font-semibold text-slate-700 hover:bg-slate-50 disabled:cursor-wait disabled:bg-slate-100"
                        >
                            Revenir à aujourd&apos;hui
                        </button>

                        <button
                            type="button"
                            onClick={() => void chargerApercu()}
                            disabled={chargement}
                            className="rounded bg-blue-600 px-5 py-2 font-semibold text-white shadow hover:bg-blue-700 disabled:cursor-wait disabled:bg-blue-300"
                        >
                            {chargement
                                ? "Chargement..."
                                : "Actualiser l'aperçu"}
                        </button>

                        <button
                            type="button"
                            onClick={() => void envoyerMailTest()}
                            disabled={chargement || envoiTestEnCours}
                            className="rounded bg-emerald-600 px-5 py-2 font-semibold text-white shadow hover:bg-emerald-700 disabled:cursor-wait disabled:bg-emerald-300"
                        >
                            {envoiTestEnCours
                                ? "Envoi en cours..."
                                : "Envoyer un mail de test"}
                        </button>
                    </div>

                    <p className="mt-3 text-xs text-slate-500">
                        Le mail de test contient uniquement des données
                        fictives et part vers l&apos;adresse verrouillée dans la
                        configuration du backend.
                    </p>
                </section>

                {messageEnvoiTest && (
                    <section
                        role="status"
                        className="rounded-lg border border-emerald-300 bg-emerald-50 p-4 text-sm text-emerald-800 shadow"
                    >
                        <p className="font-bold">Envoi réussi</p>
                        <p className="mt-1">{messageEnvoiTest}</p>
                    </section>
                )}

                {erreurEnvoiTest && (
                    <section
                        role="alert"
                        className="rounded-lg border border-red-300 bg-red-50 p-4 text-sm text-red-800 shadow"
                    >
                        <p className="font-bold">Échec de l&apos;envoi de test</p>
                        <p className="mt-1">{erreurEnvoiTest}</p>
                    </section>
                )}

                {erreur && (
                    <section
                        role="alert"
                        className="rounded-lg border border-red-300 bg-red-50 p-4 text-sm text-red-800 shadow"
                    >
                        <p className="font-bold">Aperçu indisponible</p>
                        <p className="mt-1">{erreur}</p>
                    </section>
                )}

                {chargement && !apercu && (
                    <section className="rounded-lg bg-white p-8 text-center text-slate-500 shadow">
                        Construction de l&apos;aperçu en cours…
                    </section>
                )}

                {apercu && (
                    <>
                        <section className="grid gap-3 sm:grid-cols-2 xl:grid-cols-5">
                            <article className="rounded-lg bg-white p-4 shadow">
                                <p className="text-xs font-semibold uppercase text-slate-500">
                                    Messages inclus
                                </p>
                                <p className="mt-1 text-2xl font-bold text-blue-700">
                                    {apercu.stats.includedMessages}
                                </p>
                                <p className="text-xs text-slate-500">
                                    sur {apercu.stats.sourceMessages} en base
                                </p>
                            </article>

                            <article className="rounded-lg bg-white p-4 shadow">
                                <p className="text-xs font-semibold uppercase text-slate-500">
                                    Catégories
                                </p>
                                <p className="mt-1 text-2xl font-bold text-blue-700">
                                    {apercu.stats.includedSections}
                                </p>
                                <p className="text-xs text-slate-500">
                                    sections dans le mail
                                </p>
                            </article>

                            <article className="rounded-lg bg-white p-4 shadow">
                                <p className="text-xs font-semibold uppercase text-slate-500">
                                    Alertes urgentes
                                </p>
                                <p className="mt-1 text-2xl font-bold text-red-600">
                                    {nombreUrgent}
                                </p>
                                <p className="text-xs text-slate-500">
                                    signalées dans l&apos;aperçu
                                </p>
                            </article>

                            <article className="rounded-lg bg-white p-4 shadow">
                                <p className="text-xs font-semibold uppercase text-slate-500">
                                    Destinataires
                                </p>
                                <p className="mt-1 text-2xl font-bold text-blue-700">
                                    {apercu.recipients.length}
                                </p>
                                <p className="text-xs text-slate-500">
                                    adresse(s) valide(s)
                                </p>
                            </article>

                            <article className="rounded-lg bg-white p-4 shadow">
                                <p className="text-xs font-semibold uppercase text-slate-500">
                                    Envoi autorisé
                                </p>
                                <p className="mt-1 text-2xl font-bold text-amber-600">
                                    {apercu.canSend ? "Oui" : "Non"}
                                </p>
                                <p className="text-xs text-slate-500">
                                    sécurité du mode aperçu
                                </p>
                            </article>
                        </section>

                        <section className="grid gap-4 xl:grid-cols-[minmax(0,2fr)_minmax(320px,1fr)]">
                            <article className="rounded-lg bg-white p-4 shadow">
                                <h2 className="font-bold text-slate-800">
                                    Informations du mail
                                </h2>
                                <dl className="mt-3 grid gap-3 text-sm sm:grid-cols-2">
                                    <div>
                                        <dt className="font-semibold text-slate-500">
                                            Objet
                                        </dt>
                                        <dd className="break-words">
                                            {apercu.subject}
                                        </dd>
                                    </div>
                                    <div>
                                        <dt className="font-semibold text-slate-500">
                                            Groupe
                                        </dt>
                                        <dd>{apercu.groupLabel}</dd>
                                    </div>
                                    <div>
                                        <dt className="font-semibold text-slate-500">
                                            Généré le
                                        </dt>
                                        <dd>
                                            {formatDateHeure(
                                                apercu.generatedAt
                                            )}
                                        </dd>
                                    </div>
                                    <div>
                                        <dt className="font-semibold text-slate-500">
                                            Date de simulation
                                        </dt>
                                        <dd>
                                            {formatDateCourte(dateSimulation)}
                                        </dd>
                                    </div>
                                    <div>
                                        <dt className="font-semibold text-slate-500">
                                            Source
                                        </dt>
                                        <dd>{apercu.source}</dd>
                                    </div>
                                </dl>
                            </article>

                            <article className="rounded-lg bg-white p-4 shadow">
                                <h2 className="font-bold text-slate-800">
                                    Destinataires
                                </h2>
                                {apercu.recipients.length > 0 ? (
                                    <ul className="mt-3 space-y-2">
                                        {apercu.recipients.map((recipient) => (
                                            <li
                                                key={recipient}
                                                className="break-all rounded bg-sky-50 px-3 py-2 text-sm text-blue-900"
                                            >
                                                {recipient}
                                            </li>
                                        ))}
                                    </ul>
                                ) : (
                                    <p className="mt-3 text-sm font-semibold text-red-700">
                                        Aucun destinataire configuré.
                                    </p>
                                )}
                            </article>
                        </section>

                        {(apercu.warnings.length > 0 ||
                            apercu.stats.unmatchedCategories.length > 0 ||
                            apercu.stats.invalidRecipientCount > 0) && (
                            <section className="rounded-lg border border-amber-300 bg-amber-50 p-4 text-sm text-amber-900 shadow">
                                <h2 className="font-bold">
                                    Points à vérifier
                                </h2>
                                <ul className="mt-2 list-disc space-y-1 pl-5">
                                    {apercu.warnings.map((warning, index) => (
                                        <li key={`${warning}-${index}`}>
                                            {warning}
                                        </li>
                                    ))}
                                    {apercu.stats.unmatchedCategories.length >
                                        0 && (
                                        <li>
                                            Catégories non reconnues :{" "}
                                            {apercu.stats.unmatchedCategories.join(
                                                ", "
                                            )}
                                        </li>
                                    )}
                                    {apercu.stats.invalidRecipientCount > 0 && (
                                        <li>
                                            {
                                                apercu.stats
                                                    .invalidRecipientCount
                                            }{" "}
                                            adresse(s) mail invalide(s).
                                        </li>
                                    )}
                                </ul>
                            </section>
                        )}

                        <section className="overflow-hidden rounded-lg bg-white shadow">
                            <div className="flex flex-col gap-1 border-b border-slate-200 px-4 py-3 sm:flex-row sm:items-center sm:justify-between">
                                <h2 className="font-bold text-slate-800">
                                    Rendu final du mail
                                </h2>
                                <p className="text-xs text-slate-500">
                                    Aperçu isolé et non interactif
                                </p>
                            </div>

                            <iframe
                                key={`${apercu.group}-${apercu.generatedAt}`}
                                title={`Aperçu du mail d'alertes ${apercu.groupLabel}`}
                                srcDoc={apercu.html}
                                sandbox=""
                                className="h-[720px] w-full bg-white"
                            />
                        </section>
                    </>
                )}
            </div>
        </main>
    );
}
