'use client';

/**
 * Phishing Campaigns list page (D-00) — minimal entry point for the
 * "Phishing" nav item. Browses recent campaigns and navigates into the
 * ticket-scoped review page (`/phishing/tickets/{firstReportTicketId}`),
 * which is the actual LiveLink-addressable surface (REVIEW-01..06).
 */

import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { ShieldAlert } from 'lucide-react';
import { formatDistanceToNow } from 'date-fns';
import DataTable, { type Column } from '@/components/admin/DataTable';
import { PageHeader } from '@/components/navigation/page-header';
import { EmptyState } from '@/components/ui/empty-state';
import { StatusBadge } from '@/components/ui/status-badge';

interface Campaign {
  id: string;
  campaignKey: string | null;
  groupMethod: string | null;
  firstSeenAt: string | null;
  lastSeenAt: string | null;
  reportCount: number;
  status: string;
  createdAt: string;
  firstReportTicketId: string | null;
}

const STATUS_VARIANT_CLASS: Record<string, string> = {
  open: 'bg-slate-500/15 text-slate-600',
  false_positive: 'bg-slate-500/15 text-slate-600',
};

function statusBadgeClass(status: string): string {
  return STATUS_VARIANT_CLASS[status] ?? 'bg-slate-500/15 text-slate-600';
}

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

function relativeWithAbsolute(value: string | null) {
  if (!value) return <span className="text-muted-foreground">—</span>;
  const absolute = new Date(value).toLocaleString();
  return (
    <span className="font-mono text-xs" title={absolute}>
      {formatDistanceToNow(new Date(value), { addSuffix: true })}
    </span>
  );
}

export default function PhishingCampaignsPage() {
  const router = useRouter();
  const [campaigns, setCampaigns] = useState<Campaign[]>([]);
  const [totalCount, setTotalCount] = useState(0);
  const [page, setPage] = useState(1);
  const [pageSize] = useState(50);
  const [isLoading, setIsLoading] = useState(false);

  const fetchCampaigns = async (currentPage: number) => {
    setIsLoading(true);
    try {
      const params = new URLSearchParams({
        limit: pageSize.toString(),
        offset: String((currentPage - 1) * pageSize),
      });
      const response = await fetch(`/api/phishing/campaigns?${params}`);
      const result = await response.json();
      setCampaigns(result.items ?? []);
      setTotalCount(result.total ?? 0);
    } catch (error) {
      console.error('Failed to fetch campaigns:', error);
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => {
    void fetchCampaigns(page);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [page]);

  const columns: Column<Campaign>[] = [
    {
      key: 'campaignKey',
      label: 'Campaign',
      render: (value: string | null, row: Campaign) => (
        <span className="font-mono text-sm">{value ?? `Campaign ${row.id.slice(0, 8)}`}</span>
      ),
    },
    {
      key: 'status',
      label: 'Status',
      render: (value: string) => (
        <StatusBadge variantClass={statusBadgeClass(value)}>{humanizeStatus(value)}</StatusBadge>
      ),
    },
    {
      key: 'reportCount',
      label: 'Reports',
      render: (value: number) => <span className="num text-right block">{value}</span>,
    },
    {
      key: 'firstSeenAt',
      label: 'First seen',
      render: (value: string | null) => relativeWithAbsolute(value),
    },
    {
      key: 'lastSeenAt',
      label: 'Last seen',
      render: (value: string | null) => relativeWithAbsolute(value),
    },
  ];

  return (
    <>
      <PageHeader
        title="Phishing Campaigns"
        description="Automatically detected phishing and spam campaigns awaiting triage."
      />
      <main className="container mx-auto px-6 py-6">
        {!isLoading && campaigns.length === 0 ? (
          <EmptyState
            icon={ShieldAlert}
            title="No campaigns yet"
            description="Campaigns appear here once the ticket scanner or an on-demand analysis groups a reported message."
          />
        ) : (
          <DataTable
            columns={columns}
            data={campaigns}
            totalCount={totalCount}
            page={page}
            pageSize={pageSize}
            onPageChange={setPage}
            onRowClick={(campaign) => {
              if (campaign.firstReportTicketId) {
                router.push(`/phishing/tickets/${campaign.firstReportTicketId}`);
              }
            }}
            isLoading={isLoading}
          />
        )}
      </main>
    </>
  );
}
