import {
  Alert,
  Badge,
  Button,
  Container,
  Form,
  Spinner,
  Table,
} from 'react-bootstrap';
import { Link, useNavigate } from 'react-router-dom';
import { useState } from 'react';
import { usePaperRuns, useCancelPaperRun } from '../api/hooks';
import type { PaperRun } from '../types/api';
import AppBreadcrumb from '../components/AppBreadcrumb';

const STATUS_OPTIONS = ['all', 'queued', 'running', 'complete', 'failed', 'cancelled'] as const;

const STATUS_BADGE: Record<PaperRun['status'], { bg: string; text?: string }> = {
  queued: { bg: 'info', text: 'dark' },
  running: { bg: 'primary' },
  complete: { bg: 'success' },
  failed: { bg: 'danger' },
  cancelled: { bg: 'secondary' },
};

function relativeTime(iso: string | null): string {
  if (!iso) return '--';
  const diff = Date.now() - new Date(iso).getTime();
  const seconds = Math.floor(diff / 1000);
  if (seconds < 60) return `${seconds}s ago`;
  const minutes = Math.floor(seconds / 60);
  if (minutes < 60) return `${minutes}m ago`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours}h ago`;
  const days = Math.floor(hours / 24);
  return `${days}d ago`;
}

function truncateId(id: string): string {
  return id.slice(0, 8);
}

function formatTimestamp(iso: string | null): string {
  if (!iso) return '--';
  return new Date(iso).toLocaleString(undefined, {
    year: 'numeric', month: 'short', day: 'numeric',
    hour: '2-digit', minute: '2-digit', second: '2-digit',
    hour12: false,
  });
}

export default function PaperRunsPage() {
  const [statusFilter, setStatusFilter] = useState<string>('all');
  const navigate = useNavigate();
  const cancelMutation = useCancelPaperRun();

  const queryStatus = statusFilter === 'all' ? undefined : statusFilter;
  const { data, isLoading, isError, error } = usePaperRuns(queryStatus);

  return (
    <Container>
      <AppBreadcrumb />
      <div className="d-flex align-items-center justify-content-between mb-3">
        <h5 className="mb-0">Paper Runs</h5>
        <div className="d-flex gap-2">
          <Link to="/paper-runs/new" className="btn btn-primary btn-sm">
            New Run
          </Link>
          <Form.Select
            style={{ width: 'auto' }}
            value={statusFilter}
            onChange={(e) => setStatusFilter(e.target.value)}
          >
            {STATUS_OPTIONS.map((s) => (
              <option key={s} value={s}>
                {s === 'all' ? 'All' : s.charAt(0).toUpperCase() + s.slice(1)}
              </option>
            ))}
          </Form.Select>
        </div>
      </div>

      {isLoading && <Spinner animation="border" />}
      {isError && <Alert variant="danger">{(error as Error).message}</Alert>}

      {data && (
        <Table striped bordered hover size="sm">
          <thead>
            <tr>
              <th>ID</th>
              <th>Status</th>
              <th>Mode</th>
              <th>Starts At</th>
              <th>Finishes At</th>
              <th>Worker</th>
              <th>Created</th>
              <th>Started</th>
              <th>Completed</th>
              <th>Actions</th>
            </tr>
          </thead>
          <tbody>
            {data.map((run) => {
              const badge = STATUS_BADGE[run.status];
              return (
                <tr
                  key={run.id}
                  style={{ cursor: 'pointer' }}
                  onClick={() => navigate(`/paper-runs/${run.id}`)}
                >
                  <td>
                    <code>{truncateId(run.id)}</code>
                  </td>
                  <td>
                    <Badge bg={badge.bg} text={badge.text as never}>
                      {run.status === 'running' && (
                        <Spinner
                          size="sm"
                          animation="border"
                          className="me-1"
                          style={{ width: '0.7em', height: '0.7em' }}
                        />
                      )}
                      {run.status}
                    </Badge>
                  </td>
                  <td>
                    <Badge bg={run.mode === 'backtest' ? 'secondary' : 'primary'}>
                      {run.mode}
                    </Badge>
                  </td>
                  <td>{formatTimestamp(run.starts_at)}</td>
                  <td>{formatTimestamp(run.finishes_at)}</td>
                  <td>{run.worker_id ? <code>{truncateId(run.worker_id)}</code> : '--'}</td>
                  <td>{relativeTime(run.created_at)}</td>
                  <td>{relativeTime(run.started_at)}</td>
                  <td>{relativeTime(run.completed_at)}</td>
                  <td>
                    {run.status === 'queued' && (
                      <Button
                        size="sm"
                        variant="outline-danger"
                        disabled={cancelMutation.isPending}
                        onClick={(e) => {
                          e.stopPropagation();
                          cancelMutation.mutate(run.id);
                        }}
                      >
                        Cancel
                      </Button>
                    )}
                    {(run.status === 'complete' || run.status === 'failed') && (
                      <Button
                        size="sm"
                        variant="outline-primary"
                        onClick={(e) => {
                          e.stopPropagation();
                          navigate(`/paper-runs/${run.id}`);
                        }}
                      >
                        View
                      </Button>
                    )}
                  </td>
                </tr>
              );
            })}
            {data.length === 0 && (
              <tr>
                <td colSpan={10} className="text-center text-muted">
                  No paper runs found.
                </td>
              </tr>
            )}
          </tbody>
        </Table>
      )}

      {cancelMutation.isError && (
        <Alert variant="danger" className="mt-2">
          {(cancelMutation.error as Error).message}
        </Alert>
      )}
    </Container>
  );
}
