import { useState, type ReactNode } from 'react';
import { Link } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import { Panel } from '@/components/ui/Panel';
import { Pill } from '@/components/ui/Pill';
import { Button } from '@/components/ui/Button';
import { ApiClientError } from '@/lib/api';
import type { Engagement, EngagementStatus } from '@/types/api';
import { ENGAGEMENTS_QUERY_KEY, fetchEngagements } from './engagementsApi';
import { EngagementCreateDialog } from './EngagementCreateDialog';

const STATUS_TONE: Record<EngagementStatus, 'running' | 'soc' | 'success' | 'pending'> = {
  active: 'running',
  reporting: 'soc',
  archived: 'pending',
  planning: 'success',
};

export function EngagementsPage() {
  const [createOpen, setCreateOpen] = useState(false);

  const query = useQuery<Engagement[]>({
    queryKey: ENGAGEMENTS_QUERY_KEY,
    queryFn: ({ signal }) => fetchEngagements(signal),
  });

  const engagements = query.data ?? [];

  return (
    <div className="px-8 py-6 space-y-6 max-w-[1400px] mx-auto">
      <header className="flex items-end justify-between">
        <div>
          <div className="label-system mb-1">// Engagements</div>
          <h1
            className="font-display text-fg-default"
            style={{ fontSize: '22px', letterSpacing: '0.02em' }}
          >
            Mission roster
          </h1>
          <p className="text-fg-muted mt-1" style={{ fontSize: '12.5px' }}>
            Each engagement is a multi-tenant container. Pick one to access its hosts, scenarios,
            runs, and reports.
          </p>
        </div>
        <Button variant="primary" onClick={() => setCreateOpen(true)}>
          + New engagement
        </Button>
      </header>

      <Panel
        title="Active and recent"
        meta={
          <span className="tabular">
            {query.isLoading
              ? 'loading …'
              : query.isError
                ? 'error'
                : `${String(engagements.length)} entries`}
          </span>
        }
      >
        {query.isLoading ? (
          <LoadingRow />
        ) : query.isError ? (
          <ErrorRow error={query.error} onRetry={() => void query.refetch()} />
        ) : engagements.length === 0 ? (
          <EmptyRow onCreate={() => setCreateOpen(true)} />
        ) : (
          <EngagementsTable engagements={engagements} />
        )}
      </Panel>

      {createOpen && <EngagementCreateDialog onClose={() => setCreateOpen(false)} />}
    </div>
  );
}

function EngagementsTable({ engagements }: { engagements: Engagement[] }) {
  return (
    <table className="w-full" style={{ fontSize: 12.5 }}>
      <thead>
        <tr className="text-fg-subtle">
          <Th>Name</Th>
          <Th>Client</Th>
          <Th>Status</Th>
          <Th>C2</Th>
          <Th>Window</Th>
          <Th />
        </tr>
      </thead>
      <tbody>
        {engagements.map((eng, idx) => (
          <tr
            key={eng.id}
            style={{
              borderTop:
                idx === 0 ? '1px solid var(--line-default)' : '1px solid var(--line-faint)',
            }}
          >
            <Td>
              <div
                className="font-display text-fg-default"
                style={{ letterSpacing: '0.06em' }}
              >
                {eng.name}
              </div>
              <div className="font-mono text-fg-faint" style={{ fontSize: '10.5px' }}>
                {eng.id}
              </div>
            </Td>
            <Td>{eng.client_name ?? <span className="text-fg-faint">—</span>}</Td>
            <Td>
              <Pill tone={STATUS_TONE[eng.status]}>
                <span className="status-dot" style={{ color: 'currentColor' }} />
                {eng.status}
              </Pill>
            </Td>
            <Td>
              {eng.c2_type ? (
                <span className="font-mono tabular">{eng.c2_type.toUpperCase()}</span>
              ) : (
                <span className="text-fg-faint">—</span>
              )}
            </Td>
            <Td>
              {eng.start_date || eng.end_date ? (
                <span className="font-mono tabular text-fg-muted">
                  {eng.start_date ?? '—'} → {eng.end_date ?? '—'}
                </span>
              ) : (
                <span className="text-fg-faint">—</span>
              )}
            </Td>
            <Td align="right">
              <Link to="/runs">
                <Button variant="ghost" size="sm">
                  Enter →
                </Button>
              </Link>
            </Td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function LoadingRow() {
  return (
    <div className="px-4 py-12 flex items-center gap-3 text-fg-faint label-system">
      <span className="status-dot text-fg-faint pulsing" />
      <span>fetching engagements …</span>
    </div>
  );
}

function ErrorRow({ error, onRetry }: { error: unknown; onRetry: () => void }) {
  const message =
    error instanceof ApiClientError
      ? `HTTP ${String(error.status)} · ${error.message}`
      : 'Unable to reach the backend.';
  return (
    <div className="px-4 py-8 flex items-center justify-between gap-4">
      <div>
        <div className="label-system" style={{ color: 'var(--state-failed)' }}>
          // Fetch failed
        </div>
        <div className="text-fg-muted mt-1" style={{ fontSize: 12.5 }}>
          {message}
        </div>
      </div>
      <Button variant="ghost" size="sm" onClick={onRetry}>
        ↻ Retry
      </Button>
    </div>
  );
}

function EmptyRow({ onCreate }: { onCreate: () => void }) {
  return (
    <div className="px-4 py-12 flex flex-col items-start gap-3">
      <div className="label-system">// No engagements yet</div>
      <p className="text-fg-muted" style={{ fontSize: 12.5 }}>
        Create your first engagement to start composing scenarios and running them against client
        infrastructure.
      </p>
      <Button variant="primary" size="sm" onClick={onCreate}>
        + New engagement
      </Button>
    </div>
  );
}

function Th({ children, align = 'left' }: { children?: ReactNode; align?: 'left' | 'right' }) {
  return (
    <th
      className="label-system px-3 py-2"
      style={{ textAlign: align, fontWeight: 500 }}
    >
      {children}
    </th>
  );
}

function Td({ children, align = 'left' }: { children?: ReactNode; align?: 'left' | 'right' }) {
  return (
    <td className="px-3 py-3 align-middle" style={{ textAlign: align }}>
      {children}
    </td>
  );
}
