'use client';

import { useEffect, useState } from 'react';
import { AlertCircle, Building2, Clock3 } from 'lucide-react';

import {
  extractApiErrorMessage,
  fetchTableauDeBord,
  type TableauDeBord,
} from '@/lib/api';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Skeleton } from '@/components/ui/skeleton';
import { libelleRole } from '@/lib/utilisateurs';

import { DashboardUtiF } from './dashboard-uti-f';
import { DashboardUtiG } from './dashboard-uti-g';
import { DashboardUtiS } from './dashboard-uti-s';
import { formatDateHeure } from './dashboard-ui';

function initiales(nom: string, prenom: string | null): string {
  const lettres = [prenom, nom]
    .map((partie) => partie?.trim()?.[0] ?? '')
    .filter(Boolean)
    .join('');

  return (lettres || '?').toUpperCase();
}

function Hero({ donnees }: { donnees: TableauDeBord }) {
  const { nom, prenom } = donnees.utilisateur;
  const nomComplet = [prenom, nom].filter(Boolean).join(' ') || nom;

  return (
    <section className="sidebar-gradient relative mb-6 overflow-hidden rounded-2xl px-6 py-6 text-white shadow-brand">
      <div aria-hidden className="pointer-events-none absolute inset-0">
        <div className="brand-dots absolute inset-0 opacity-[0.14]" />
        <div className="absolute -right-16 -top-24 h-64 w-64 rounded-full bg-brand-500/30 blur-3xl" />
      </div>

      <div className="relative flex flex-wrap items-center justify-between gap-5">
        <div className="flex items-center gap-4">
          <span className="brand-gradient flex h-12 w-12 shrink-0 items-center justify-center rounded-xl text-base font-bold shadow-brand">
            {initiales(nom, prenom)}
          </span>

          <div className="min-w-0">
            <h1 className="truncate text-xl font-bold tracking-tight">
              Bonjour {prenom?.trim() || nomComplet}
            </h1>
            <div className="mt-1.5 flex flex-wrap items-center gap-2 text-xs text-white/60">
              <span className="rounded-md bg-white/10 px-2 py-0.5 font-semibold text-white/85">
                {donnees.role}
              </span>
              <span>{libelleRole(donnees.role)}</span>
              {donnees.organisation.nom ? (
                <>
                  <span aria-hidden>·</span>
                  <span className="inline-flex items-center gap-1.5">
                    <Building2 className="h-3.5 w-3.5" />
                    {donnees.organisation.nom}
                  </span>
                </>
              ) : null}
            </div>
          </div>
        </div>

        <p className="inline-flex items-center gap-2 rounded-lg border border-white/10 bg-white/[0.06] px-3 py-1.5 text-xs text-white/70">
          <Clock3 className="h-3.5 w-3.5" />
          Données arrêtées au {formatDateHeure(donnees.genere_le)}
        </p>
      </div>
    </section>
  );
}

function DashboardSkeleton() {
  return (
    <div className="space-y-6">
      <Skeleton className="h-[108px] w-full rounded-2xl" />
      <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
        {[0, 1, 2, 3].map((index) => (
          <Skeleton key={index} className="h-[132px] w-full rounded-xl" />
        ))}
      </div>
      <div className="grid gap-5 lg:grid-cols-2">
        <Skeleton className="h-64 w-full rounded-xl" />
        <Skeleton className="h-64 w-full rounded-xl" />
      </div>
    </div>
  );
}

/**
 * Le tableau de bord est composé par l'API selon le rôle (§5.6) : l'interface
 * se contente d'aiguiller vers la vue correspondante, sans jamais déduire un
 * droit par elle-même.
 */
export function DashboardPanel() {
  const [donnees, setDonnees] = useState<TableauDeBord | null>(null);
  const [erreur, setErreur] = useState<string | null>(null);
  const [chargement, setChargement] = useState(true);

  useEffect(() => {
    let annule = false;

    fetchTableauDeBord()
      .then((tableau) => {
        if (!annule) {
          setDonnees(tableau);
        }
      })
      .catch((error: unknown) => {
        if (!annule) {
          setErreur(
            extractApiErrorMessage(
              error,
              'Impossible de charger le tableau de bord.',
            ),
          );
        }
      })
      .finally(() => {
        if (!annule) {
          setChargement(false);
        }
      });

    return () => {
      annule = true;
    };
  }, []);

  if (chargement) {
    return <DashboardSkeleton />;
  }

  if (erreur !== null || donnees === null) {
    return (
      <Alert variant="destructive">
        <AlertCircle className="h-4 w-4" />
        <AlertTitle>Erreur</AlertTitle>
        <AlertDescription>
          {erreur ?? 'Impossible de charger le tableau de bord.'}
        </AlertDescription>
      </Alert>
    );
  }

  return (
    <div className="animate-fade-in">
      <Hero donnees={donnees} />

      {donnees.role === 'UTI-G' ? <DashboardUtiG donnees={donnees} /> : null}
      {donnees.role === 'UTI-F' ? <DashboardUtiF donnees={donnees} /> : null}
      {donnees.role === 'UTI-S' ? <DashboardUtiS donnees={donnees} /> : null}
    </div>
  );
}
