import { AlertTriangle, Shield } from 'lucide-react';

import { useCallback, useMemo, useRef, useState } from 'react';

import { Head, Link, router } from '@inertiajs/react';

import { AdminDataTable } from '@/Components/admin/AdminDataTable';
import { PerPageSelector } from '@/Components/admin/PerPageSelector';
import { SortHeader } from '@/Components/admin/SortHeader';
import PageHeader from '@/Components/layout/PageHeader';
import { Alert, AlertDescription, AlertTitle } from '@/Components/ui/alert';
import { Badge } from '@/Components/ui/badge';
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from '@/Components/ui/breadcrumb';
import { Button } from '@/Components/ui/button';
import { Checkbox } from '@/Components/ui/checkbox';
import { ConfirmDialog } from '@/Components/ui/confirm-dialog';
import { ExportButton } from '@/Components/ui/export-button';
import { Input } from '@/Components/ui/input';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/Components/ui/select';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/Components/ui/table';
import { useAdminFilters } from '@/hooks/useAdminFilters';
import { useAdminKeyboardShortcuts } from '@/hooks/useAdminKeyboardShortcuts';
import { useNavigationState } from '@/hooks/useNavigationState';
import AdminLayout from '@/Layouts/AdminLayout';
import { formatDate } from '@/lib/format';

interface BreachIncident {
  id: number;
  description: string;
  severity: string;
  affected_count: number;
  status: string;
  is_notified: boolean;
  is_overdue: boolean;
  detected_at: string;
  notification_deadline: string;
  notified_at: string | null;
}

interface BreachIndexProps {
  incidents: {
    data: BreachIncident[];
    current_page: number;
    last_page: number;
    from: number | null;
    to: number | null;
    total: number;
  };
  filters: {
    search?: string;
    severity?: string;
    status?: string;
    date_from?: string;
    date_to?: string;
    sort?: string;
    dir?: string;
    per_page?: number;
    [key: string]: string | number | boolean | undefined;
  };
}

const SEVERITY_COLORS: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {
  low: 'outline',
  medium: 'secondary',
  high: 'default',
  critical: 'destructive',
};

const SEVERITY_BORDER: Record<string, string> = {
  critical: 'border-l-4 border-l-red-500',
  high: 'border-l-4 border-l-orange-500',
  medium: 'border-l-4 border-l-yellow-500',
};

export default function BreachIncidentsIndex({ incidents, filters }: BreachIndexProps) {
  const searchInputRef = useRef<HTMLInputElement>(null);

  useAdminKeyboardShortcuts({
    onSearch: () => searchInputRef.current?.focus(),
  });

  const isNavigating = useNavigationState();

  const { search, setSearch, updateFilter, handleSort, handlePage, clearFilters } = useAdminFilters({
    route: '/admin/breach-incidents',
    filters: filters ?? {},
    routerOptions: { preserveScroll: true },
  });

  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set());
  const [bulkConfirmOpen, setBulkConfirmOpen] = useState(false);
  const [bulkStatus, setBulkStatus] = useState('investigating');

  const hasFilters = !!(
    filters.search ||
    filters.severity ||
    filters.status ||
    filters.date_from ||
    filters.date_to
  );

  const overdueCount = useMemo(
    () => incidents.data.filter((i) => i.is_overdue && !i.is_notified).length,
    [incidents.data],
  );

  const toggleIncident = useCallback((id: number) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  }, []);

  const allSelected =
    incidents.data.length > 0 && incidents.data.every((i) => selectedIds.has(i.id));

  const toggleAll = useCallback(() => {
    if (allSelected) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(incidents.data.map((i) => i.id)));
    }
  }, [allSelected, incidents.data]);

  const executeBulkUpdate = useCallback((): Promise<void> => {
    return new Promise((resolve, reject) => {
      router.patch(
        route('admin.breach-incidents.bulk-update-status'),
        { incident_ids: Array.from(selectedIds), status: bulkStatus },
        {
          preserveState: true,
          onSuccess: () => {
            setSelectedIds(new Set());
            setBulkConfirmOpen(false);
            resolve();
          },
          onError: () => reject(),
        },
      );
    });
  }, [selectedIds, bulkStatus]);

  return (
    <AdminLayout>
      <Head title="Breach Incidents" />
      <div className="container py-6 space-y-6">
        <Breadcrumb>
          <BreadcrumbList>
            <BreadcrumbItem>
              <BreadcrumbLink asChild>
                <Link href="/admin">Admin</Link>
              </BreadcrumbLink>
            </BreadcrumbItem>
            <BreadcrumbSeparator />
            <BreadcrumbItem>
              <BreadcrumbPage aria-current={undefined} className="text-muted-foreground">
                GDPR
              </BreadcrumbPage>
            </BreadcrumbItem>
            <BreadcrumbSeparator />
            <BreadcrumbItem>
              <BreadcrumbPage>Breach Incidents</BreadcrumbPage>
            </BreadcrumbItem>
          </BreadcrumbList>
        </Breadcrumb>

        <PageHeader
          title="Data Breach Incidents"
          description={`GDPR Art. 33 — 72-hour notification requirement. Total: ${incidents.total ?? 0}`}
          actions={
            <div className="flex gap-2">
              <ExportButton href={route('admin.breach-incidents.export')} />
              <Button
                variant="outline"
                size="sm"
                onClick={() => router.visit(route('admin.breach-incidents.index'))}
              >
                Refresh
              </Button>
            </div>
          }
        />

        {overdueCount > 0 && (
          <Alert variant="destructive">
            <AlertTriangle className="h-4 w-4" />
            <AlertTitle>
              {overdueCount} breach incident{overdueCount !== 1 ? 's' : ''} overdue
            </AlertTitle>
            <AlertDescription>
              GDPR requires notification within 72 hours. Review overdue incidents immediately.
            </AlertDescription>
          </Alert>
        )}

        {/* Filters */}
        <fieldset className="flex flex-col sm:flex-row gap-3">
          <legend className="sr-only">Breach Incident Filters</legend>
          <Input
            ref={searchInputRef}
            placeholder="Search descriptions..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="max-w-sm"
            aria-label="Search breach incidents"
          />
          <Select
            value={filters.severity ?? 'all'}
            onValueChange={(value) =>
              updateFilter({ severity: value === 'all' ? undefined : value })
            }
          >
            <SelectTrigger className="w-[160px]" aria-label="Filter by severity">
              <SelectValue placeholder="Severity: All" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">Severity: All</SelectItem>
              <SelectItem value="low">Low</SelectItem>
              <SelectItem value="medium">Medium</SelectItem>
              <SelectItem value="high">High</SelectItem>
              <SelectItem value="critical">Critical</SelectItem>
            </SelectContent>
          </Select>
          <Select
            value={filters.status ?? 'all'}
            onValueChange={(value) => updateFilter({ status: value === 'all' ? undefined : value })}
          >
            <SelectTrigger className="w-[170px]" aria-label="Filter by status">
              <SelectValue placeholder="Status: All" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">Status: All</SelectItem>
              <SelectItem value="detected">Detected</SelectItem>
              <SelectItem value="investigating">Investigating</SelectItem>
              <SelectItem value="contained">Contained</SelectItem>
              <SelectItem value="notified">Notified</SelectItem>
              <SelectItem value="resolved">Resolved</SelectItem>
            </SelectContent>
          </Select>
          <Input
            type="date"
            value={filters.date_from ?? ''}
            onChange={(e) => updateFilter({ date_from: e.target.value || undefined })}
            className="w-[160px]"
            aria-label="From date"
          />
          <Input
            type="date"
            value={filters.date_to ?? ''}
            onChange={(e) => updateFilter({ date_to: e.target.value || undefined })}
            className="w-[160px]"
            aria-label="To date"
          />
          {hasFilters && (
            <Button variant="ghost" size="sm" onClick={clearFilters}>
              Clear filters
            </Button>
          )}
          <div className="sm:ml-auto">
            <PerPageSelector
              value={filters.per_page ?? 15}
              onChange={(perPage) => updateFilter({ per_page: perPage })}
            />
          </div>
        </fieldset>

        {/* Bulk Action Bar */}
        {selectedIds.size > 0 && (
          <div
            className="flex items-center gap-3 rounded-lg border bg-muted/50 px-4 py-2"
            role="status"
            aria-live="polite"
          >
            <span className="text-sm font-medium">{selectedIds.size} incident(s) selected</span>
            <Select value={bulkStatus} onValueChange={setBulkStatus}>
              <SelectTrigger className="w-[160px] h-8">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="investigating">Investigating</SelectItem>
                <SelectItem value="contained">Contained</SelectItem>
                <SelectItem value="resolved">Resolved</SelectItem>
              </SelectContent>
            </Select>
            <Button size="sm" onClick={() => setBulkConfirmOpen(true)}>
              Update Status
            </Button>
            <Button variant="ghost" size="sm" onClick={() => setSelectedIds(new Set())}>
              Clear
            </Button>
          </div>
        )}

        <AdminDataTable
          isNavigating={isNavigating}
          isEmpty={incidents.data.length === 0}
          pagination={incidents}
          onPage={handlePage}
          paginationLabel="incidents"
          emptyIcon={Shield}
          emptyTitle="No breach incidents"
          emptyDescription="No data breach incidents have been recorded."
        >
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="w-[40px]">
                    <Checkbox
                      checked={allSelected && incidents.data.length > 0}
                      onCheckedChange={toggleAll}
                      aria-label="Select all"
                      disabled={incidents.data.length === 0}
                    />
                  </TableHead>
                  <TableHead scope="col">ID</TableHead>
                  <TableHead scope="col">Description</TableHead>
                  <SortHeader
                    column="severity"
                    label="Severity"
                    currentSort={filters?.sort}
                    currentDir={filters?.dir}
                    onSort={handleSort}
                  />
                  <TableHead scope="col">Affected</TableHead>
                  <SortHeader
                    column="status"
                    label="Status"
                    currentSort={filters?.sort}
                    currentDir={filters?.dir}
                    onSort={handleSort}
                  />
                  <SortHeader
                    column="detected_at"
                    label="Deadline"
                    currentSort={filters?.sort}
                    currentDir={filters?.dir}
                    onSort={handleSort}
                  />
                  <TableHead scope="col">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {incidents.data.map((i) => (
                  <TableRow
                    key={i.id}
                    className={
                      `${SEVERITY_BORDER[i.severity] ?? ''} ${
                        i.is_overdue && !i.is_notified
                          ? 'bg-destructive/5 hover:bg-destructive/10'
                          : ''
                      }`.trim() || undefined
                    }
                  >
                    <TableCell>
                      <Checkbox
                        checked={selectedIds.has(i.id)}
                        onCheckedChange={() => toggleIncident(i.id)}
                        aria-label={`Select incident #${i.id}`}
                      />
                    </TableCell>
                    <TableCell className="font-mono text-xs text-muted-foreground">
                      #{i.id}
                    </TableCell>
                    <TableCell className="font-medium text-foreground max-w-xs truncate">
                      {i.description}
                    </TableCell>
                    <TableCell>
                      <Badge variant={SEVERITY_COLORS[i.severity] ?? 'default'}>{i.severity}</Badge>
                    </TableCell>
                    <TableCell className="text-muted-foreground">{i.affected_count}</TableCell>
                    <TableCell>
                      <Badge
                        variant={
                          i.is_notified ? 'outline' : i.is_overdue ? 'destructive' : 'secondary'
                        }
                      >
                        {i.status}
                      </Badge>
                    </TableCell>
                    <TableCell className="text-xs text-muted-foreground">
                      {formatDate(i.notification_deadline)}
                      {i.is_overdue && !i.is_notified && (
                        <span className="ml-1 text-destructive font-bold">OVERDUE</span>
                      )}
                    </TableCell>
                    <TableCell>
                      <Button
                        size="sm"
                        variant="outline"
                        onClick={() => router.visit(route('admin.breach-incidents.show', i.id))}
                      >
                        View
                      </Button>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
        </AdminDataTable>
      </div>
      <ConfirmDialog
        open={bulkConfirmOpen}
        onOpenChange={setBulkConfirmOpen}
        onConfirm={executeBulkUpdate}
        title="Bulk Update Status"
        description={`Update ${selectedIds.size} incident(s) to "${bulkStatus}"?`}
        confirmLabel="Update"
      />
    </AdminLayout>
  );
}
