import { format, parseISO } from "date-fns";
import { fr } from "date-fns/locale";
import { Send, CheckCircle2, Inbox, AlertTriangle, type LucideIcon } from "lucide-react";

import { Card } from "@/components/ui/Card";
import { Eyebrow } from "@/components/ui/Eyebrow";
import { cn } from "@/lib/utils";

/**
 * ActivityFeed — journal d'activité.
 * Pattern wireframe 4.1 : ce qui s'est passé pendant que l'user travaillait
 * sur son vrai métier (intention émotionnelle forte).
 */
export type ActivityKind =
  | "relance_sent"
  | "invoice_paid"
  | "invoice_imported"
  | "warning_drafted";

export type ActivityEvent = {
  id: string;
  kind: ActivityKind;
  /** ISO 8601 */
  at: string;
  /** Texte HTML simple — peut contenir <b> pour mettre en avant un nom. */
  label: string;
};

const ICONS: Record<ActivityKind, LucideIcon> = {
  relance_sent: Send,
  invoice_paid: CheckCircle2,
  invoice_imported: Inbox,
  warning_drafted: AlertTriangle,
};

const TONE: Record<ActivityKind, string> = {
  relance_sent: "text-ink-2",
  invoice_paid: "text-rubis-deep",
  invoice_imported: "text-ink-2",
  warning_drafted: "text-rubis-deep",
};

type ActivityFeedProps = {
  events: ActivityEvent[];
  /** Si la liste est vide, on affiche un empty state au lieu d'une carte vide. */
  emptyMessage?: string;
  className?: string;
};

export function ActivityFeed({
  events,
  emptyMessage = "Tout est calme. Allez vous chercher un café.",
  className,
}: ActivityFeedProps) {
  return (
    <Card padding="md" className={cn("min-w-0", className)}>
      <Eyebrow tone="ink">Aujourd&apos;hui</Eyebrow>

      {events.length === 0 ? (
        <p className="mt-4 text-[14px] text-ink-3 italic">{emptyMessage}</p>
      ) : (
        <ul className="mt-4 flex flex-col gap-3">
          {events.map((event) => {
            const Icon = ICONS[event.kind];
            return (
              <li
                key={event.id}
                className="flex items-start gap-3 text-[13.5px] text-ink-2"
              >
                <Icon
                  size={15}
                  strokeWidth={2}
                  className={cn("mt-0.5 shrink-0", TONE[event.kind])}
                  aria-hidden="true"
                />
                <span
                  className="flex-1 min-w-0 leading-relaxed"
                  // Le label vient du serveur — on autorise <b> pour mettre en avant
                  // un nom de client ou un numéro de facture. Pas de XSS ici car les
                  // mocks sont locaux ; à durcir avec sanitize si jamais on accepte
                  // de l'input utilisateur.
                  dangerouslySetInnerHTML={{ __html: event.label }}
                />
                <time
                  dateTime={event.at}
                  className="shrink-0 text-[12px] text-ink-3 tabular-nums"
                >
                  {format(parseISO(event.at), "HH:mm", { locale: fr })}
                </time>
              </li>
            );
          })}
        </ul>
      )}
    </Card>
  );
}
