import * as React from 'react';
import { Link, useNavigate, useParams } from 'react-router-dom';
import { ArrowLeft, Check, X } from 'lucide-react';

import { api, type Proposal, type Skill } from '../api';
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card';
import { Badge } from '../components/ui/badge';
import { Button } from '../components/ui/button';
import { Textarea, Label } from '../components/ui/input';
import { Diff } from '../components/Diff';

export function ProposalDetailPage(): React.JSX.Element {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const [proposal, setProposal] = React.useState<Proposal | null>(null);
  const [existing, setExisting] = React.useState<string | null>(null);
  const [reason, setReason] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);

  React.useEffect(() => {
    let cancelled = false;
    async function load(): Promise<void> {
      try {
        const p = await api.get<Proposal>(`/api/v1/proposals/${String(id)}`);
        if (cancelled) return;
        setProposal(p);

        // Fetch existing resource (if any) for the diff.
        const projectName = p.project?.name;
        try {
          if (p.resourceType === 'prompt') {
            const params = new URLSearchParams();
            if (projectName) params.set('project', projectName);
            const list = await api.get<Array<{ name: string; content: string }>>(`/api/v1/prompts?${params.toString()}`);
            const match = list.find((x) => x.name === p.name);
            if (!cancelled) setExisting(match?.content ?? '');
          } else {
            const params = new URLSearchParams();
            if (projectName) params.set('project', projectName);
            const list = await api.get<Skill[]>(`/api/v1/skills?${params.toString()}`);
            const match = list.find((x) => x.name === p.name);
            if (!cancelled) setExisting(match?.content ?? '');
          }
        } catch {
          if (!cancelled) setExisting('');
        }
      } catch (err) {
        if (!cancelled) setError((err as Error).message);
      }
    }
    void load();
    return () => { cancelled = true; };
  }, [id]);

  if (error !== null) return (
    <div className="space-y-3">
      <Link to="/proposals" className="inline-flex items-center gap-1 text-sm text-(--color-primary) hover:underline">
        <ArrowLeft className="size-3.5" /> Proposals
      </Link>
      <div className="text-(--color-danger)">Error: {error}</div>
    </div>
  );
  if (proposal === null) return <div className="text-(--color-fg-muted)">Loading…</div>;

  const proposed = (proposal.body as { content?: string }).content ?? '';
  const isPending = proposal.status === 'pending';
  const willCreateNew = (existing ?? '').length === 0;
  const scope = proposal.project?.name ?? proposal.agent?.name ?? 'global';

  async function approve(): Promise<void> {
    if (!proposal) return;
    setBusy(true);
    try {
      await api.post(`/api/v1/proposals/${proposal.id}/approve`, {});
      navigate('/proposals');
    } finally {
      setBusy(false);
    }
  }

  async function reject(): Promise<void> {
    if (!proposal) return;
    if (reason.trim().length === 0) return;
    setBusy(true);
    try {
      await api.post(`/api/v1/proposals/${proposal.id}/reject`, { reviewerNote: reason });
      navigate('/proposals');
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="space-y-6">
      <Link to="/proposals" className="inline-flex items-center gap-1 text-sm text-(--color-primary) hover:underline">
        <ArrowLeft className="size-3.5" /> Proposals
      </Link>

      <header className="flex items-start justify-between gap-6">
        <div className="space-y-2">
          <div className="flex items-center gap-3">
            <h1 className="font-mono text-2xl font-semibold tracking-tight">{proposal.name}</h1>
            <Badge variant="outline">{proposal.resourceType}</Badge>
            <Badge variant={proposal.status === 'pending' ? 'warning' : proposal.status === 'approved' ? 'success' : 'danger'}>
              {proposal.status}
            </Badge>
          </div>
          <div className="flex items-center gap-3 text-xs text-(--color-fg-subtle)">
            <span>scope: {scope}</span>
            <span>session: <code className="font-mono">{proposal.createdBySession ?? '—'}</code></span>
            <span>created: {new Date(proposal.createdAt).toLocaleString()}</span>
          </div>
          {proposal.reviewerNote && (
            <div className="rounded-md border border-(--color-border) bg-(--color-surface-hi) p-3 text-sm">
              <span className="text-(--color-fg-muted)">Reviewer note:</span> {proposal.reviewerNote}
            </div>
          )}
        </div>

        {isPending && (
          <div className="flex items-center gap-2">
            <Button variant="primary" onClick={approve} disabled={busy}>
              <Check className="size-4" />
              Approve
            </Button>
          </div>
        )}
      </header>

      <Card>
        <CardHeader>
          <CardTitle className="text-sm">
            {willCreateNew ? `Would create a new ${proposal.resourceType}` : 'Diff against current'}
          </CardTitle>
        </CardHeader>
        <CardContent>
          {willCreateNew ? (
            <pre className="overflow-x-auto whitespace-pre-wrap rounded bg-(--color-canvas) p-3 font-mono text-xs leading-relaxed">
              {proposed}
            </pre>
          ) : (
            <Diff before={existing ?? ''} after={proposed} />
          )}
        </CardContent>
      </Card>

      {isPending && (
        <Card className="border-(--color-danger)/30">
          <CardHeader>
            <CardTitle className="text-sm">Reject</CardTitle>
          </CardHeader>
          <CardContent className="space-y-3">
            <div className="space-y-2">
              <Label htmlFor="reject-reason">Reviewer note (required)</Label>
              <Textarea
                id="reject-reason"
                placeholder="Explain why this is being rejected so the proposer can learn from it."
                value={reason}
                onChange={(e) => setReason(e.target.value)}
                rows={3}
              />
            </div>
            <Button variant="danger" onClick={reject} disabled={busy || reason.trim().length === 0}>
              <X className="size-4" />
              Reject with note
            </Button>
          </CardContent>
        </Card>
      )}
    </div>
  );
}
