import { Bot, Clock, Search, XCircle, Zap } from 'lucide-react';
import { toast } from 'sonner';

import { useState, useRef } from 'react';

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

import { AdminDataTable } from '@/Components/admin/AdminDataTable';
import { AdminStatsGrid, type StatCard } from '@/Components/admin/AdminStatsGrid';
import { PerPageSelector } from '@/Components/admin/PerPageSelector';
import { SortHeader } from '@/Components/admin/SortHeader';
import PageHeader from '@/Components/layout/PageHeader';
import { Badge } from '@/Components/ui/badge';
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from '@/Components/ui/breadcrumb';
import { Button } from '@/Components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/Components/ui/card';
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 { getAdminStatusVariant } from '@/lib/adminStatusBadge';
import { formatRelativeTime, formatNumber } from '@/lib/format';

interface AiJobRow {
  id: number;
  site_id: number;
  site_name: string | null;
  status: string;
  model: string;
  total_prompt_tokens: number;
  total_completion_tokens: number;
  total_recommendations: number;
  completed_recommendations: number;
  created_at: string;
}

interface BatchJobRow {
  id: number;
  site_id: number;
  site_name: string | null;
  status: string;
  total_jobs: number;
  completed_jobs: number;
  failed_jobs: number;
  total_estimated_cost: number;
  total_actual_cost: number;
  created_at: string;
}

interface PaginatedAiJobs {
  data: AiJobRow[];
  current_page: number;
  last_page: number;
  from: number | null;
  to: number | null;
  total: number;
}

interface Props {
  ai_jobs: PaginatedAiJobs;
  batch_jobs: BatchJobRow[];
  filters: {
    search?: string;
    status?: string;
    sort?: string;
    dir?: string;
    date_from?: string;
    date_to?: string;
    per_page?: number;
  };
  stats: {
    total_ai_jobs: number;
    active_ai_jobs: number;
    failed_ai_jobs: number;
    total_batch_jobs: number;
    total_tokens_30d: number;
  };
}

const statusBadge = (status: string) => (
  <Badge variant={getAdminStatusVariant(status)}>{status}</Badge>
);

export default function Index({ ai_jobs, batch_jobs, filters, stats }: Props) {
  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set());
  const [cancelConfirm, setCancelConfirm] = useState(false);
  const { search, setSearch, updateFilter, handleSort, handlePage } = useAdminFilters({
    route: 'admin.ai-jobs.index',
    filters,
  });
  const isNavigating = useNavigationState();
  const searchInputRef = useRef<HTMLInputElement>(null);

  const currentPage = ai_jobs.current_page;
  const lastPage = ai_jobs.last_page;
  useAdminKeyboardShortcuts({
    onSearch: () => searchInputRef.current?.focus(),
    onNextPage: currentPage < lastPage ? () => handlePage(currentPage + 1) : undefined,
    onPrevPage: currentPage > 1 ? () => handlePage(currentPage - 1) : undefined,
  });

  const cancellableStatuses = ['pending', 'processing'];

  function toggleSelect(id: number) {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
  }

  function handleBulkCancel() {
    router.post(
      route('admin.ai-jobs.bulk-cancel'),
      { job_ids: [...selectedIds] },
      {
        onSuccess: () => { setSelectedIds(new Set()); setCancelConfirm(false); },
        onError: () => { toast.error('Operation failed. Your session may have expired — refresh and try again.'); },
      },
    );
  }

  const statCards: StatCard[] = [
    { title: 'Total AI Jobs', value: stats.total_ai_jobs, icon: Bot },
    { title: 'Active', value: stats.active_ai_jobs, icon: Clock },
    {
      title: 'Failed',
      value: stats.failed_ai_jobs,
      icon: Zap,
      valueClassName: stats.failed_ai_jobs > 0 ? 'text-destructive' : '',
    },
    {
      title: 'Tokens (30d)',
      value: stats.total_tokens_30d,
      format: formatNumber,
    },
  ];

  return (
    <AdminLayout>
      <Head title="AI Jobs" />
      <div className="container py-6 space-y-6">
        <Breadcrumb>
          <BreadcrumbList>
            <BreadcrumbItem>
              <BreadcrumbLink asChild>
                <Link href="/admin">Admin</Link>
              </BreadcrumbLink>
            </BreadcrumbItem>
            <BreadcrumbSeparator />
            <BreadcrumbItem>
              <BreadcrumbPage>AI Jobs</BreadcrumbPage>
            </BreadcrumbItem>
          </BreadcrumbList>
        </Breadcrumb>
        <PageHeader
          title="AI Jobs & Batch Jobs"
          description="Monitor AI generation pipelines"
          actions={<ExportButton href={route('admin.ai-jobs.export')} />}
        />

        <AdminStatsGrid stats={statCards} />

        <div className="flex items-center gap-4">
          <div className="relative flex-1">
            <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
            <Input
              ref={searchInputRef}
              placeholder="Search by site..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="pl-9"
            />
          </div>
          <Select
            value={filters.status ?? 'all'}
            onValueChange={(val) => updateFilter({ status: val === 'all' ? undefined : val })}
          >
            <SelectTrigger className="w-[160px]">
              <SelectValue placeholder="Status" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All Statuses</SelectItem>
              <SelectItem value="completed">Completed</SelectItem>
              <SelectItem value="processing">Processing</SelectItem>
              <SelectItem value="failed">Failed</SelectItem>
              <SelectItem value="pending">Pending</SelectItem>
            </SelectContent>
          </Select>
          <Input
            type="date"
            value={filters.date_from ?? ''}
            onChange={(e) => updateFilter({ date_from: e.target.value || undefined })}
            className="w-[160px]"
            aria-label="Filter from date"
          />
          <Input
            type="date"
            value={filters.date_to ?? ''}
            onChange={(e) => updateFilter({ date_to: e.target.value || undefined })}
            className="w-[160px]"
            aria-label="Filter to date"
          />
          <PerPageSelector
            value={filters.per_page ?? 25}
            onChange={(perPage) => updateFilter({ per_page: perPage })}
          />
        </div>

        {selectedIds.size > 0 && (
          <div className="flex items-center gap-3 p-3 rounded-lg border bg-muted/40">
            <span className="text-sm text-muted-foreground">{selectedIds.size} selected</span>
            <Button size="sm" variant="destructive" onClick={() => setCancelConfirm(true)}>
              <XCircle className="h-3.5 w-3.5 mr-1" />
              Cancel Selected
            </Button>
            <Button size="sm" variant="ghost" onClick={() => setSelectedIds(new Set())}>
              Clear selection
            </Button>
          </div>
        )}

        <AdminDataTable
          isEmpty={ai_jobs.data.length === 0}
          isNavigating={isNavigating}
          pagination={ai_jobs}
          onPage={handlePage}
          paginationLabel="AI jobs"
          emptyIcon={Bot}
          emptyTitle="No AI jobs found"
        >
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-8" />
                <TableHead className="w-16">ID</TableHead>
                <TableHead>Site</TableHead>
                <TableHead>Status</TableHead>
                <TableHead>Model</TableHead>
                <TableHead>Tokens</TableHead>
                <SortHeader
                  column="created_at"
                  label="Created"
                  currentSort={filters.sort}
                  currentDir={filters.dir}
                  onSort={handleSort}
                />
                <TableHead className="w-16" />
              </TableRow>
            </TableHeader>
            <TableBody>
              {ai_jobs.data.map((job) => (
                <TableRow key={job.id}>
                  <TableCell>
                    {cancellableStatuses.includes(job.status) && (
                      <Checkbox
                        checked={selectedIds.has(job.id)}
                        onCheckedChange={() => toggleSelect(job.id)}
                        aria-label={`Select job ${job.id}`}
                      />
                    )}
                  </TableCell>
                  <TableCell className="font-mono text-xs">{job.id}</TableCell>
                  <TableCell className="text-sm">{job.site_name ?? '—'}</TableCell>
                  <TableCell>{statusBadge(job.status)}</TableCell>
                  <TableCell className="font-mono text-xs">{job.model}</TableCell>
                  <TableCell className="text-sm">
                    {formatNumber(job.total_prompt_tokens + job.total_completion_tokens)}
                  </TableCell>
                  <TableCell className="text-sm text-muted-foreground">
                    {formatRelativeTime(job.created_at)}
                  </TableCell>
                  <TableCell>
                    <Link
                      href={route('admin.ai-jobs.show', { aiJob: job.id })}
                      className="text-xs text-primary hover:underline"
                    >
                      View
                    </Link>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </AdminDataTable>

        {batch_jobs.length > 0 && (
          <Card>
            <CardHeader>
              <CardTitle className="text-base">Batch Jobs ({stats.total_batch_jobs})</CardTitle>
            </CardHeader>
            <CardContent className="p-0">
              <div className="overflow-x-auto">
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead className="w-16">ID</TableHead>
                      <TableHead>Site</TableHead>
                      <TableHead>Status</TableHead>
                      <TableHead>Progress</TableHead>
                      <TableHead>Cost</TableHead>
                      <TableHead>Created</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {batch_jobs.map((batch) => (
                      <TableRow key={batch.id}>
                        <TableCell className="font-mono text-xs">{batch.id}</TableCell>
                        <TableCell className="text-sm">{batch.site_name ?? '—'}</TableCell>
                        <TableCell>{statusBadge(batch.status)}</TableCell>
                        <TableCell className="text-sm">
                          {batch.completed_jobs}/{batch.total_jobs}
                          {batch.failed_jobs > 0 && (
                            <span className="ml-1 text-destructive">
                              ({batch.failed_jobs} failed)
                            </span>
                          )}
                        </TableCell>
                        <TableCell className="text-sm font-mono">
                          $
                          {batch.total_actual_cost > 0
                            ? batch.total_actual_cost.toFixed(3)
                            : batch.total_estimated_cost.toFixed(3)}
                        </TableCell>
                        <TableCell className="text-sm text-muted-foreground">
                          {formatRelativeTime(batch.created_at)}
                        </TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              </div>
            </CardContent>
          </Card>
        )}
      </div>
      <ConfirmDialog
        open={cancelConfirm}
        onOpenChange={setCancelConfirm}
        title="Cancel selected AI jobs?"
        description={`This will cancel ${selectedIds.size} AI job(s) that are pending or processing.`}
        confirmLabel="Cancel Jobs"
        variant="destructive"
        onConfirm={handleBulkCancel}
      />
    </AdminLayout>
  );
}
