'use client';

import { FileText, Sparkles, CheckCircle2, ShieldCheck, XCircle, Circle } from 'lucide-react';
import { formatDistanceToNow } from 'date-fns';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { cn } from '@/lib/utils';

export type TimelineEntry =
  | { kind: 'report'; at: string; reportId: string; ticketNumber: string | null; companyName: string | null }
  | {
      kind: 'classification';
      at: string;
      verdict: 'SPAM' | 'UNWANTED' | 'THREAT' | 'USER_AWARENESS';
      confidence: string | null;
    }
  | { kind: 'audit'; at: string; eventType: string; actor: string | null; payload: unknown };

interface TimelineCardProps {
  timeline: TimelineEntry[];
}

const VERDICT_TINT: Record<'SPAM' | 'UNWANTED' | 'THREAT' | 'USER_AWARENESS', string> = {
  SPAM: 'bg-slate-500 text-slate-600',
  UNWANTED: 'bg-amber-500 text-amber-600',
  THREAT: 'bg-destructive text-destructive',
  USER_AWARENESS: 'bg-emerald-500 text-emerald-600',
};

function humanizeEventType(eventType: string): string {
  return eventType
    .split('_')
    .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ');
}

function renderEntry(entry: TimelineEntry): {
  label: string;
  icon: React.ComponentType<{ className?: string }>;
  dotClass: string;
  textClass: string;
} {
  if (entry.kind === 'report') {
    const ticketLabel = entry.ticketNumber ? `Ticket #${entry.ticketNumber}` : 'Ticket';
    const company = entry.companyName ? ` (${entry.companyName})` : '';
    return {
      label: `Report linked — ${ticketLabel}${company}`,
      icon: FileText,
      dotClass: 'bg-muted-foreground',
      textClass: 'text-muted-foreground',
    };
  }

  if (entry.kind === 'classification') {
    const confidencePct = entry.confidence != null ? Number(entry.confidence) : NaN;
    const confidence = Number.isFinite(confidencePct) ? ` (${Math.round(confidencePct * 100)}%)` : '';
    // Defensive fallback: phishing-timeline.ts emits verdict as a plain
    // unvalidated runtime `string`, so a value outside this component's
    // narrowed union must never crash the render (T-23-12).
    const tint = VERDICT_TINT[entry.verdict] ?? 'bg-muted-foreground text-muted-foreground';
    return {
      label: `Classified as ${entry.verdict}${confidence}`,
      icon: Sparkles,
      dotClass: tint.split(' ')[0],
      textClass: tint.split(' ')[1],
    };
  }

  // entry.kind === 'audit'
  const payload = (entry.payload ?? {}) as Record<string, unknown>;
  switch (entry.eventType) {
    case 'remediation_approved': {
      const count =
        (Array.isArray(payload.actionIds) && payload.actionIds.length) ||
        (Array.isArray(payload.actions) && payload.actions.length) ||
        0;
      return {
        label: `${count} action(s) approved by ${entry.actor ?? 'unknown'}`,
        icon: CheckCircle2,
        dotClass: 'bg-blue-500',
        textClass: 'text-blue-600',
      };
    }
    case 'remediation_completed':
      return {
        label: 'Remediation completed',
        icon: ShieldCheck,
        dotClass: 'bg-green-500',
        textClass: 'text-green-600',
      };
    case 'campaign_marked_false_positive':
      return {
        label: 'Marked as false positive',
        icon: XCircle,
        dotClass: 'bg-slate-500',
        textClass: 'text-slate-600',
      };
    case 'campaign_marked_accidental_report':
      return {
        label: 'Marked as accidental report — reporter notified',
        icon: CheckCircle2,
        dotClass: 'bg-blue-500',
        textClass: 'text-blue-600',
      };
    case 'campaign_classified': {
      const verdict = payload.verdict as 'SPAM' | 'UNWANTED' | 'THREAT' | 'USER_AWARENESS' | undefined;
      const tint = (verdict && VERDICT_TINT[verdict]) || 'bg-muted-foreground text-muted-foreground';
      return {
        label: verdict ? `Classified as ${verdict}` : 'Campaign classified',
        icon: Sparkles,
        dotClass: tint.split(' ')[0],
        textClass: tint.split(' ')[1],
      };
    }
    default:
      return {
        label: humanizeEventType(entry.eventType),
        icon: Circle,
        dotClass: 'bg-muted-foreground',
        textClass: 'text-muted-foreground',
      };
  }
}

export function TimelineCard({ timeline }: TimelineCardProps) {
  return (
    <Card>
      <CardHeader>
        <CardTitle className="font-bold">Timeline</CardTitle>
      </CardHeader>
      <CardContent>
        {timeline.length === 0 ? (
          <p className="text-sm text-muted-foreground">No timeline events yet.</p>
        ) : (
          <div className="space-y-0">
            {timeline.map((entry, idx) => {
              const { label, icon: Icon, dotClass, textClass } = renderEntry(entry);
              const isLast = idx === timeline.length - 1;
              const actor = entry.kind === 'audit' ? entry.actor : null;
              const absolute = new Date(entry.at).toLocaleString();
              const relative = formatDistanceToNow(new Date(entry.at), { addSuffix: true });
              return (
                <div key={idx} className="flex gap-3">
                  <div className="flex flex-col items-center">
                    <span
                      className={cn('h-2 w-2 rounded-full shrink-0 mt-1.5', dotClass)}
                    />
                    {!isLast && <span className="border-l flex-1 w-0 min-h-4" />}
                  </div>
                  <div className="pb-4 min-w-0">
                    <div className="flex items-center gap-1.5 text-sm">
                      <Icon className={cn('h-3.5 w-3.5 shrink-0', textClass)} />
                      <span>{label}</span>
                    </div>
                    <div className="flex items-center gap-2 mt-0.5">
                      <span className="font-mono text-xs text-muted-foreground" title={absolute}>
                        {relative}
                      </span>
                      {actor && (
                        <span className="text-xs text-muted-foreground">{actor}</span>
                      )}
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </CardContent>
    </Card>
  );
}
