import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { api, Job, SyncPair } from '../api/client';
import { Button } from '@/components/ui/Button';
import { Select, SelectValue, SelectTrigger, SelectContent, SelectItem } from '@/components/ui/Select';
import { Badge } from '@/components/ui/Badge';
import { PageHeader } from '@/components/ui/PageHeader';
import {
  Table,
  TableHeader,
  TableBody,
  TableHead,
  TableRow,
  TableCell,
} from '@/components/ui/Table';
import { EmptyState } from '@/components/ui/EmptyState';
import { Skeleton } from '@/components/ui/Skeleton';
import { History, XCircle, ChevronLeft, ChevronRight, RefreshCw } from 'lucide-react';
import { toast } from 'sonner';
import { cn } from '@/lib/utils';
import { statusVariant, statusLabel } from '@/lib/status';
import { formatDuration } from '@/lib/utils';

export default function JobHistory() {
  const [jobs, setJobs] = useState<Job[]>([]);
  const [pairs, setPairs] = useState<SyncPair[]>([]);
  const [filterStatus, setFilterStatus] = useState('');
  const [filterPair, setFilterPair] = useState('');
  const [filterRange, setFilterRange] = useState('7d');
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(0);
  const [loading, setLoading] = useState(true);
  const limit = 50;

  useEffect(() => {
    loadPairs();
  }, []);

  useEffect(() => {
    load();
  }, [filterStatus, filterPair, filterRange, page]);

  async function load() {
    setLoading(true);
    try {
      let url = `/api/jobs?limit=${limit}&offset=${page * limit}`;
      if (filterStatus) url += `&status=${filterStatus}`;
      if (filterPair) url += `&sync_pair_id=${filterPair}`;
      if (filterRange === '24h') {
        const from = new Date(Date.now() - 24 * 3600 * 1000).toISOString();
        url += `&from=${encodeURIComponent(from)}`;
      } else if (filterRange === '7d') {
        const from = new Date(Date.now() - 7 * 24 * 3600 * 1000).toISOString();
        url += `&from=${encodeURIComponent(from)}`;
      } else if (filterRange === '30d') {
        const from = new Date(Date.now() - 30 * 24 * 3600 * 1000).toISOString();
        url += `&from=${encodeURIComponent(from)}`;
      }
      const res = await fetch(url, { credentials: 'include' });
      const totalCount = res.headers.get('X-Total-Count');
      if (totalCount) setTotal(Number(totalCount));
      const data = await res.json();
      setJobs(data);
    } catch {
    } finally {
      setLoading(false);
    }
  }

  async function loadPairs() {
    try {
      setPairs(await api<SyncPair[]>('/api/sync-pairs'));
    } catch {}
  }

  async function cancel(id: number) {
    try {
      await api(`/api/jobs/${id}/cancel`, { method: 'POST' });
      toast.success('Job cancelled');
      load();
    } catch (e: unknown) {
      toast.error((e as Error).message);
    }
  }

  function pairName(id: number) {
    const p = pairs.find(p => p.id === id);
    return p ? p.name : `Pair ${id}`;
  }

  const totalPages = Math.ceil(total / limit);

  const FilterChip = ({
    label,
    value,
    onChange,
  }: {
    label: string;
    value: string;
    onChange: (v: string) => void;
  }) => (
    <Select value={value} onValueChange={onChange}>
      <SelectTrigger className="w-auto min-w-[140px]">
        <SelectValue placeholder={label} />
      </SelectTrigger>
      <SelectContent>
        <SelectItem value="">{label}</SelectItem>
        {label === 'All Pairs' &&
          pairs.map(p => (
            <SelectItem key={p.id} value={p.id.toString()}>
              {p.name}
            </SelectItem>
          ))}
        {label === 'All Statuses' &&
          [
            { value: 'queued', label: 'Queued' },
            { value: 'waking_up', label: 'Waking Up' },
            { value: 'running', label: 'Running' },
            { value: 'success', label: 'Success' },
            { value: 'failed', label: 'Failed' },
            { value: 'cancelled', label: 'Cancelled' },
          ].map(s => (
            <SelectItem key={s.value} value={s.value}>
              {s.label}
            </SelectItem>
          ))}
        {label === 'Time Range' &&
          [
            { value: '24h', label: 'Last 24h' },
            { value: '7d', label: 'Last 7 days' },
            { value: '30d', label: 'Last 30 days' },
            { value: 'all', label: 'All time' },
          ].map(r => (
            <SelectItem key={r.value} value={r.value}>
              {r.label}
            </SelectItem>
          ))}
      </SelectContent>
    </Select>
  );

  return (
    <div className="space-y-6">
      <PageHeader
        title="Job History"
        description={`${total} job${total !== 1 ? 's' : ''} found`}
        actions={
          <Button
            variant="secondary"
            size="sm"
            onClick={() => load()}
            disabled={loading}
          >
            <RefreshCw className={cn('h-4 w-4', loading && 'animate-spin')} />
            Refresh
          </Button>
        }
      />

      <div className="flex flex-wrap items-center gap-3">
        <FilterChip label="All Pairs" value={filterPair} onChange={v => { setFilterPair(v); setPage(0); }} />
        <FilterChip label="All Statuses" value={filterStatus} onChange={v => { setFilterStatus(v); setPage(0); }} />
        <FilterChip label="Time Range" value={filterRange} onChange={v => { setFilterRange(v); setPage(0); }} />
        {(filterStatus || filterPair || filterRange !== '7d') && (
          <Button
            variant="ghost"
            size="sm"
            onClick={() => { setFilterStatus(''); setFilterPair(''); setFilterRange('7d'); setPage(0); }}
            className="text-fg-subtle"
          >
            <XCircle className="h-3.5 w-3.5" />
            Clear filters
          </Button>
        )}
      </div>

      <Card className="p-0">
        {loading ? (
          <div className="p-5 space-y-3">
            {Array.from({ length: 5 }).map((_, i) => (
              <Skeleton key={i} className="h-12 w-full" />
            ))}
          </div>
        ) : jobs.length === 0 ? (
          <EmptyState
            icon={<History className="h-5 w-5" />}
            title="No jobs found"
            description={
              filterStatus || filterPair || filterRange !== '7d'
                ? 'Try adjusting your filters'
                : 'Sync pairs will appear here once jobs are executed'
            }
          />
        ) : (
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>ID</TableHead>
                <TableHead>Sync Pair</TableHead>
                <TableHead>Trigger</TableHead>
                <TableHead>Status</TableHead>
                <TableHead>Duration</TableHead>
                <TableHead>Started</TableHead>
                <TableHead>Finished</TableHead>
                <TableHead className="w-20">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {jobs.map(j => (
                <TableRow key={j.id}>
                  <TableCell>
                    <Link
                      to={`/jobs/${j.id}`}
                      className="text-accent hover:text-accent-hover font-mono text-xs"
                    >
                      #{j.id}
                    </Link>
                  </TableCell>
                  <TableCell className="text-fg-muted">
                    {pairName(j.sync_pair_id)}
                  </TableCell>
                  <TableCell>
                    <span className="text-xs text-fg-muted capitalize">
                      {j.trigger_type}
                    </span>
                  </TableCell>
                  <TableCell>
                    <Badge
                      variant={statusVariant(j.status)}
                      label={statusLabel(j.status)}
                    />
                  </TableCell>
                  <TableCell className="text-fg-muted font-mono text-xs">
                    {j.started_at
                      ? formatDuration(
                          (j.finished_at
                            ? new Date(j.finished_at).getTime()
                            : Date.now()) -
                            new Date(j.started_at).getTime()
                        )
                      : '-'}
                  </TableCell>
                  <TableCell className="text-fg-muted text-xs">
                    {j.started_at
                      ? new Date(j.started_at).toLocaleString()
                      : '-'}
                  </TableCell>
                  <TableCell className="text-fg-muted text-xs">
                    {j.finished_at
                      ? new Date(j.finished_at).toLocaleString()
                      : '-'}
                  </TableCell>
                  <TableCell>
                    {['queued', 'waking_up', 'running'].includes(j.status) && (
                      <Button
                        variant="ghost"
                        size="icon-sm"
                        onClick={() => cancel(j.id)}
                        className="text-rose-400 hover:text-rose-300 hover:bg-rose-500/10"
                        title="Cancel job"
                      >
                        <XCircle className="h-3.5 w-3.5" />
                      </Button>
                    )}
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        )}

        {totalPages > 1 && (
          <div className="flex items-center justify-between px-5 py-3 border-t border-border">
            <div className="text-xs text-fg-muted">
              Page {page + 1} of {totalPages} ({total} total)
            </div>
            <div className="flex items-center gap-2">
              <Button
                variant="secondary"
                size="icon-sm"
                onClick={() => setPage(p => Math.max(0, p - 1))}
                disabled={page === 0}
              >
                <ChevronLeft className="h-4 w-4" />
              </Button>
              <Button
                variant="secondary"
                size="icon-sm"
                onClick={() => setPage(p => Math.min(totalPages - 1, p + 1))}
                disabled={page >= totalPages - 1}
              >
                <ChevronRight className="h-4 w-4" />
              </Button>
            </div>
          </div>
        )}
      </Card>
    </div>
  );
}

function Card({ children, className }: { children: React.ReactNode; className?: string }) {
  return (
    <div className={cn('rounded-card border border-border bg-surface shadow-card', className)}>
      {children}
    </div>
  )
}
