import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useState } from 'react';
import { useNavigate, useParams } 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 { ApiError, apiDelete, apiGet, apiPost } from '@/lib/api';
import {
  MISSION_STATUS_ACCENT,
  MISSION_STATUS_LABEL,
  missionKeys,
  type Mission,
  type MissionStatus,
  type TransitionPayload,
} from '@/lib/missions';

const TABS = ['tests', 'members', 'synthesis', 'export'] as const;
type Tab = (typeof TABS)[number];

const ALLOWED_TRANSITIONS: Record<MissionStatus, MissionStatus[]> = {
  draft: ['in_progress', 'archived'],
  in_progress: ['completed', 'archived'],
  completed: ['archived'],
  archived: [],
};

function useMission(id: string) {
  return useQuery({
    queryKey: missionKeys.detail(id),
    queryFn: () => apiGet<Mission>(`/missions/${id}`),
    enabled: !!id,
  });
}

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

export function MissionDetailPage() {
  const params = useParams();
  const missionId = params.id ?? '';
  const navigate = useNavigate();
  const qc = useQueryClient();

  const [tab, setTab] = useState<Tab>('tests');
  const detail = useMission(missionId);

  const transition = useMutation({
    mutationFn: (body: TransitionPayload) =>
      apiPost<Mission>(`/missions/${missionId}/transition`, body),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: missionKeys.detail(missionId) });
      qc.invalidateQueries({ queryKey: missionKeys.list() });
    },
  });

  const remove = useMutation({
    mutationFn: () => apiDelete<{ ok: true }>(`/missions/${missionId}`),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: missionKeys.list() });
      navigate('/missions');
    },
  });

  const apiErr = detail.error instanceof ApiError ? detail.error : null;
  const m = detail.data;

  if (apiErr) {
    return (
      <section>
        <SectionHeader prefix="Mission" highlight="Not found" accent="rose" />
        <Alert accent="rose">{apiErr.message}</Alert>
      </section>
    );
  }
  if (!m) {
    return <p className="font-mono text-xs text-text-dim">Loading mission…</p>;
  }

  const accent = MISSION_STATUS_ACCENT[m.status];
  const allowedNext = ALLOWED_TRANSITIONS[m.status];

  return (
    <section data-testid={`mission-detail-${m.id}`}>
      <div className="flex items-baseline justify-between flex-wrap gap-3">
        <SectionHeader prefix="Mission" highlight={m.name} accent={accent} />
        <div className="flex items-center gap-2">
          <Tag accent={accent}>{MISSION_STATUS_LABEL[m.status]}</Tag>
          {allowedNext.map((target) => (
            <Button
              key={target}
              accent={target === 'archived' ? 'teal' : 'cyan'}
              onClick={() => transition.mutate({ status: target })}
              data-testid={`mission-transition-${target}`}
              disabled={transition.isPending}
            >
              → {MISSION_STATUS_LABEL[target]}
            </Button>
          ))}
          <Button
            accent="rose"
            variant="ghost"
            onClick={() => {
              if (
                window.confirm(
                  `Soft-delete mission "${m.name}"? An admin can restore from the trash.`,
                )
              ) {
                remove.mutate();
              }
            }}
            data-testid="mission-delete"
            disabled={remove.isPending}
          >
            Delete
          </Button>
        </div>
      </div>

      <Card className="mb-4">
        <dl className="grid grid-cols-2 gap-3 md:grid-cols-4 font-mono text-2xs">
          <div>
            <dt className="text-text-dim uppercase tracking-wider2">Client</dt>
            <dd className="text-text-bright">{m.client_target ?? '—'}</dd>
          </div>
          <div>
            <dt className="text-text-dim uppercase tracking-wider2">Dates</dt>
            <dd className="text-text-bright">
              {formatDateRange(m.date_start, m.date_end)}
            </dd>
          </div>
          <div>
            <dt className="text-text-dim uppercase tracking-wider2">Scenarios</dt>
            <dd className="text-text-bright">{m.scenarios_count}</dd>
          </div>
          <div>
            <dt className="text-text-dim uppercase tracking-wider2">Tests</dt>
            <dd className="text-text-bright">{m.tests_count}</dd>
          </div>
        </dl>
        {m.description_md && (
          <pre className="mt-3 whitespace-pre-wrap font-mono text-xs text-text">{m.description_md}</pre>
        )}
      </Card>

      <nav className="flex gap-1 border-b border-border mb-4" aria-label="Mission tabs">
        {TABS.map((t) => (
          <button
            key={t}
            type="button"
            onClick={() => setTab(t)}
            data-testid={`mission-tab-${t}`}
            className={`px-3 py-2 font-mono text-2xs uppercase tracking-wider2 ${
              tab === t
                ? 'text-cyan border-b-2 border-cyan -mb-px'
                : 'text-text-dim hover:text-text-bright'
            }`}
          >
            {t}
          </button>
        ))}
      </nav>

      {tab === 'tests' && (
        <Card>
          {m.scenarios.length === 0 ? (
            <p className="font-mono text-xs text-text-dim">
              No scenarios snapshotted yet.
            </p>
          ) : (
            <div className="flex flex-col gap-4" data-testid="mission-scenarios">
              {m.scenarios.map((sc) => (
                <div
                  key={sc.id}
                  className="rounded-md border border-border bg-bg-card p-3"
                  data-testid={`mission-scenario-${sc.id}`}
                >
                  <div className="flex items-center gap-2 mb-2">
                    <Tag accent="cyan">#{sc.position + 1}</Tag>
                    <p className="font-mono text-xs text-text-bright">
                      {sc.snapshot_name}
                    </p>
                  </div>
                  {sc.snapshot_description && (
                    <p className="mb-2 font-mono text-2xs text-text-dim">
                      {sc.snapshot_description}
                    </p>
                  )}
                  <table className="w-full font-mono text-2xs">
                    <thead>
                      <tr className="text-text-dim uppercase tracking-wider2">
                        <th className="text-left py-1">#</th>
                        <th className="text-left py-1">Test</th>
                        <th className="text-left py-1">MITRE</th>
                        <th className="text-left py-1">OPSEC</th>
                        <th className="text-left py-1">State</th>
                      </tr>
                    </thead>
                    <tbody>
                      {sc.tests.map((t) => (
                        <tr
                          key={t.id}
                          className="border-t border-border/40"
                          data-testid={`mission-test-${t.id}`}
                        >
                          <td className="py-1 text-text-dim">{t.position + 1}</td>
                          <td className="py-1 text-text-bright">{t.snapshot_name}</td>
                          <td className="py-1">
                            <div className="flex flex-wrap gap-1">
                              {t.mitre_tags.map((tag) => (
                                <Tag
                                  accent="cyan"
                                  key={`${tag.kind}-${tag.external_id}`}
                                >
                                  {tag.external_id}
                                </Tag>
                              ))}
                            </div>
                          </td>
                          <td className="py-1 text-text">
                            {t.snapshot_opsec_level}
                          </td>
                          <td className="py-1">
                            <Tag
                              accent={
                                t.state === 'pending'
                                  ? 'teal'
                                  : t.state === 'executed'
                                    ? 'orange'
                                    : t.state === 'reviewed_by_blue'
                                      ? 'green'
                                      : 'rose'
                              }
                            >
                              {t.state}
                            </Tag>
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              ))}
            </div>
          )}
        </Card>
      )}

      {tab === 'members' && (
        <Card>
          {m.members.length === 0 ? (
            <p className="font-mono text-xs text-text-dim">
              No members assigned. An admin can add them via the API.
            </p>
          ) : (
            <ul className="flex flex-col gap-2" data-testid="mission-members">
              {m.members.map((mb) => (
                <li
                  key={mb.user_id}
                  className="flex items-center justify-between rounded-md border border-border bg-bg-card p-3"
                  data-testid={`mission-member-${mb.user_id}`}
                >
                  <div>
                    <p className="font-mono text-xs text-text-bright">
                      {mb.user_display_name ?? mb.user_email}
                    </p>
                    {mb.user_display_name && (
                      <p className="font-mono text-2xs text-text-dim">
                        {mb.user_email}
                      </p>
                    )}
                  </div>
                  <Tag accent={mb.role_hint === 'red' ? 'red' : 'cyan'}>
                    {mb.role_hint}
                  </Tag>
                </li>
              ))}
            </ul>
          )}
        </Card>
      )}

      {tab === 'synthesis' && (
        <Card>
          <p className="font-mono text-xs text-text-dim">
            Reveal.js slide synthesis lands in M10.
          </p>
        </Card>
      )}

      {tab === 'export' && (
        <Card>
          <p className="font-mono text-xs text-text-dim">
            JSON / CSV exports land in M11.
          </p>
        </Card>
      )}
    </section>
  );
}
