import { useQuery } from '@tanstack/react-query';
import { useMemo, useState } from 'react';
import { Link } from 'react-router-dom';

import { Alert } from '@/components/ui/Alert';
import { Button } from '@/components/ui/Button';
import { Card } from '@/components/ui/Card';
import { SectionHeader } from '@/components/ui/SectionHeader';
import { Tag } from '@/components/ui/Tag';
import { TextField } from '@/components/ui/TextField';
import { ApiError, apiGet } from '@/lib/api';
import { useAuth } from '@/lib/auth';
import {
  MISSION_STATUS_ACCENT,
  MISSION_STATUS_LABEL,
  buildMissionQueryString,
  missionKeys,
  type MissionFilters,
  type MissionListResponse,
  type MissionStatus,
} from '@/lib/missions';

const STATUS_OPTIONS: Array<{ value: '' | MissionStatus; label: string }> = [
  { value: '', label: 'All statuses' },
  { value: 'draft', label: MISSION_STATUS_LABEL.draft },
  { value: 'in_progress', label: MISSION_STATUS_LABEL.in_progress },
  { value: 'completed', label: MISSION_STATUS_LABEL.completed },
  { value: 'archived', label: MISSION_STATUS_LABEL.archived },
];

function useMissions(filters: MissionFilters) {
  return useQuery({
    queryKey: missionKeys.list(filters),
    queryFn: () =>
      apiGet<MissionListResponse>(`/missions${buildMissionQueryString(filters)}`),
  });
}

function formatDateRange(start: string | null, end: string | null): string {
  if (!start && !end) return '—';
  if (start && end) return `${start} → ${end}`;
  return start ?? end ?? '—';
}

export function MissionsListPage() {
  const { state } = useAuth();
  const canCreate =
    state.user?.is_admin || state.user?.permissions.includes('mission.create');

  const [q, setQ] = useState('');
  const [status, setStatus] = useState<'' | MissionStatus>('');
  const [client, setClient] = useState('');

  const filters = useMemo<MissionFilters>(
    () => ({
      q: q.trim() || undefined,
      status: status || undefined,
      client: client.trim() || undefined,
    }),
    [q, status, client],
  );

  const { data, error, isLoading } = useMissions(filters);
  const apiErr = error instanceof ApiError ? error : null;

  return (
    <section data-testid="missions-list">
      <div className="flex items-baseline justify-between">
        <SectionHeader prefix="Plan" highlight="Missions" accent="cyan" />
        {canCreate && (
          <Link to="/missions/new" data-testid="missions-new-link">
            <Button accent="cyan">+ New mission</Button>
          </Link>
        )}
      </div>

      <Card className="mb-6">
        <div className="grid grid-cols-1 gap-3 md:grid-cols-3">
          <TextField
            label="Search"
            placeholder="name or description"
            value={q}
            onChange={(e) => setQ(e.target.value)}
            data-testid="missions-filter-q"
          />
          <TextField
            label="Client"
            placeholder="acme corp"
            value={client}
            onChange={(e) => setClient(e.target.value)}
            data-testid="missions-filter-client"
          />
          <div className="flex flex-col gap-1">
            <label className="font-mono text-2xs uppercase tracking-wider2 text-text-dim">
              Status
            </label>
            <select
              value={status}
              onChange={(e) => setStatus(e.target.value as '' | MissionStatus)}
              data-testid="missions-filter-status"
              className="bg-bg-card border border-border rounded px-3 py-2 font-mono text-xs text-text-bright"
            >
              {STATUS_OPTIONS.map((opt) => (
                <option key={opt.value} value={opt.value}>
                  {opt.label}
                </option>
              ))}
            </select>
          </div>
        </div>
      </Card>

      {apiErr && (
        <div data-testid="missions-error">
          <Alert accent="red">{apiErr.message}</Alert>
        </div>
      )}

      {isLoading && (
        <p className="font-mono text-xs text-text-dim">Loading missions…</p>
      )}

      {data && data.items.length === 0 && !isLoading && (
        <Card>
          <p className="font-mono text-xs text-text-dim" data-testid="missions-empty">
            No missions match the filters. {canCreate ? 'Create one to get started.' : ''}
          </p>
        </Card>
      )}

      <div className="grid grid-cols-1 gap-3 lg:grid-cols-2" data-testid="missions-grid">
        {data?.items.map((m) => {
          const accent = MISSION_STATUS_ACCENT[m.status];
          return (
            <Link key={m.id} to={`/missions/${m.id}`} data-testid={`mission-card-${m.id}`}>
              <Card
                accent={accent}
                title={m.name}
                sub={m.client_target ?? 'No client'}
                className="h-full"
              >
                <div className="flex flex-wrap items-center gap-2">
                  <Tag accent={accent}>{MISSION_STATUS_LABEL[m.status]}</Tag>
                  <Tag accent="cyan">{m.scenarios_count} scenarios</Tag>
                  <Tag accent="purple">{m.tests_count} tests</Tag>
                  <Tag accent="teal">{m.members_count} members</Tag>
                </div>
                <p className="mt-3 font-mono text-2xs text-text-dim">
                  {formatDateRange(m.date_start, m.date_end)}
                </p>
              </Card>
            </Link>
          );
        })}
      </div>

      {data && (
        <p
          className="mt-4 font-mono text-2xs text-text-dim"
          data-testid="missions-total"
        >
          {data.total} mission{data.total === 1 ? '' : 's'} total
        </p>
      )}
    </section>
  );
}
