// ============================================================
// src/modules/portail/composants/TimelineSinistre.tsx
// Timeline verticale d'un sinistre avec fichiers joints par étape
// ============================================================

import { CheckCircle2, Clock, Circle, FileText, Eye, Download } from 'lucide-react';
import { useQuery } from '@tanstack/react-query';
import apiClient from '../../../noyau/api/client';
import { formaterDate } from '../../../noyau/utilitaires/formateurs';
import { serviceSinistrePortail } from '../services/serviceSinistrePortail';

// ─── Types ────────────────────────────────────────────────────────────────────

interface DocumentEtape {
  id: string;
  nom_fichier: string;
  type_mime: string;
  taille_octets: number;
  cree_le: string;
}

interface EtapeTimeline {
  id_etape: string;
  id_sinistre: string;
  statut_etape: 'en_cours' | 'termine' | 'saute';
  date_debut: string;
  date_fin: string | null;
  commentaire: string | null;
  libelle_etape: string;
  ordre_etape: number;
  code_etape: string;
  delai_jours: number | null;
  documents: DocumentEtape[];
}

// ─── Hook ────────────────────────────────────────────────────────────────────

function useTimelineSinistre(idSinistre: string) {
  return useQuery({
    queryKey: ['portail-timeline-sinistre', idSinistre],
    queryFn: async (): Promise<EtapeTimeline[]> => {
      const { data } = await apiClient.get('/v_timeline_sinistre', {
        params: {
          id_sinistre: `eq.${idSinistre}`,
          order: 'ordre_etape.asc',
        },
      });
      return data;
    },
    enabled: !!idSinistre,
  });
}

// ─── Utilitaires ──────────────────────────────────────────────────────────────

function formaterTaille(octets: number): string {
  if (octets < 1024) return `${octets} o`;
  if (octets < 1024 * 1024) return `${Math.round(octets / 1024)} KB`;
  return `${(octets / (1024 * 1024)).toFixed(1)} MB`;
}

function formaterDateHeure(iso: string): string {
  const d = new Date(iso);
  const jour = d.toLocaleDateString('fr-FR', { day: '2-digit', month: 'short' }).toUpperCase();
  const heure = d.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' });
  return `${jour} ${heure}`;
}

async function telechargerDocument(idDoc: string, nomFichier: string) {
  try {
    await serviceSinistrePortail.telechargerDocument(idDoc, nomFichier);
  } catch (e) {
    console.error('Erreur téléchargement', e);
    alert('Impossible de télécharger ce document.');
  }
}

async function apercuDocument(idDoc: string) {
  try {
    await serviceSinistrePortail.ouvrirApercu(idDoc);
  } catch (e) {
    console.error('Erreur aperçu', e);
    alert('Impossible d\'afficher ce document.');
  }
}

// ─── Composants ──────────────────────────────────────────────────────────────

interface Props {
  idSinistre: string;
}

export function TimelineSinistre({ idSinistre }: Props) {
  const { data: etapes = [], isLoading } = useTimelineSinistre(idSinistre);

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-10">
        <div className="w-6 h-6 border-2 border-amber-500 border-t-transparent rounded-full animate-spin" />
      </div>
    );
  }

  if (etapes.length === 0) {
    return (
      <p className="text-sm text-slate-400 text-center py-6">
        Aucun suivi disponible pour ce sinistre.
      </p>
    );
  }

  return (
    <div className="relative">
      {/* Ligne verticale reliant les étapes */}
      <div className="absolute left-[15px] top-6 bottom-6 w-px bg-slate-200" />

      <div className="space-y-8">
        {etapes.map((etape, idx) => (
          <EtapeTimeline
            key={etape.id_etape}
            etape={etape}
            estDerniere={idx === etapes.length - 1}
          />
        ))}
      </div>
    </div>
  );
}

// ─── Étape individuelle ──────────────────────────────────────────────────────

function EtapeTimeline({
  etape,
  estDerniere,
}: {
  etape: EtapeTimeline;
  estDerniere: boolean;
}) {
  const termine = etape.statut_etape === 'termine';
  const enCours = etape.statut_etape === 'en_cours';
  const aVenir = !termine && !enCours;

  // Choix de l'icône
  const Icone = termine ? CheckCircle2 : enCours ? Clock : Circle;

  // Classes selon le statut
  const classesBulle = termine
    ? 'bg-emerald-500 text-white ring-4 ring-emerald-50'
    : enCours
      ? 'bg-emerald-100 text-emerald-600 ring-4 ring-emerald-50'
      : 'bg-slate-100 text-slate-400 ring-4 ring-slate-50';

  const classesTitre = aVenir ? 'text-slate-400' : 'text-slate-900';

  return (
    <div className="relative flex items-start gap-4">
      {/* Bulle statut */}
      <div
        className={`relative z-10 w-8 h-8 rounded-full flex items-center justify-center shrink-0 ${classesBulle}`}
      >
        <Icone size={16} />
      </div>

      {/* Contenu */}
      <div className="flex-1 min-w-0 pb-2">
        {/* En-tête : titre + date */}
        <div className="flex items-start justify-between gap-3 mb-1">
          <h3
            className={`text-sm font-bold uppercase tracking-wide ${classesTitre}`}
          >
            {etape.libelle_etape}
          </h3>
          <div className="text-right shrink-0">
            {termine && etape.date_fin ? (
              <span className="text-[11px] font-medium text-slate-400 whitespace-nowrap">
                {formaterDateHeure(etape.date_fin)}
              </span>
            ) : enCours ? (
              <span className="text-[11px] font-semibold text-amber-600 uppercase tracking-wider">
                En cours
              </span>
            ) : null}
          </div>
        </div>

        {/* Commentaire saisi par l'agent lors de l'étape */}
        {etape.commentaire && (
          <p
            className={`text-sm mb-3 ${
              aVenir ? 'text-slate-400' : 'text-slate-600'
            }`}
          >
            {etape.commentaire}
          </p>
        )}

        {/* Documents joints */}
        {etape.documents.length > 0 && (
          <div className="space-y-2 mt-3">
            {etape.documents.map((doc) => (
              <FichierJoint key={doc.id} doc={doc} />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

// ─── Ligne fichier joint ─────────────────────────────────────────────────────

function FichierJoint({ doc }: { doc: DocumentEtape }) {
  return (
    <div className="flex items-center justify-between p-3 bg-slate-50 rounded-lg border border-slate-100 hover:border-slate-200 transition-colors">
      <div className="flex items-center gap-3 min-w-0">
        <div className="w-9 h-9 rounded-lg bg-white border border-slate-200 flex items-center justify-center shrink-0">
          <FileText size={15} className="text-slate-400" />
        </div>
        <div className="min-w-0">
          <p className="text-sm font-semibold text-slate-800 truncate uppercase">
            {doc.nom_fichier}
          </p>
          <p className="text-[11px] text-slate-400">
            {formaterTaille(doc.taille_octets)}
          </p>
        </div>
      </div>

      <div className="flex items-center gap-1 shrink-0">
        <button
          onClick={() => apercuDocument(doc.id)}
          className="p-2 rounded-lg text-slate-400 hover:text-amber-600 hover:bg-amber-50 transition-colors"
          title="Aperçu"
        >
          <Eye size={15} />
        </button>
        <button
          onClick={() => telechargerDocument(doc.id, doc.nom_fichier)}
          className="p-2 rounded-lg text-slate-400 hover:text-amber-600 hover:bg-amber-50 transition-colors"
          title="Télécharger"
        >
          <Download size={15} />
        </button>
      </div>
    </div>
  );
}
