import { useCallback, useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
import { requests as requestsApi, ApiError } from "../api/client";
import type { ChangeRequest } from "../api/types";
import { useNotifications } from "../context/NotificationsContext";
import { Button, Card, Spinner } from "../components/ui";
import { StateBadge } from "../components/StateBadge";
import { ChangeList } from "../components/ChangeRenderer";
import { AgentAvatar } from "../components/AgentAvatar";
import { DecisionModal } from "../components/DecisionModal";
import { expiresIn, formatDateTime, relativeTime } from "../utils";

type Decision = "APPROVE" | "REJECT" | "REQUEST_CHANGES";

export function RequestDetailPage() {
	const { id } = useParams<{ id: string }>();
	const { requestEventTick } = useNotifications();
	const [request, setRequest] = useState<ChangeRequest | null>(null);
	const [loading, setLoading] = useState(true);
	const [error, setError] = useState<string | null>(null);
	const [decision, setDecision] = useState<Decision | null>(null);

	const load = useCallback(async () => {
		if (!id) return;
		try {
			setRequest(await requestsApi.get(id));
			setError(null);
		} catch (err) {
			setError(err instanceof ApiError ? err.message : "Failed to load");
		} finally {
			setLoading(false);
		}
	}, [id]);

	useEffect(() => {
		load();
	}, [load, requestEventTick]);

	if (loading) {
		return (
			<div className="flex justify-center py-20 text-primary">
				<Spinner className="h-7 w-7" />
			</div>
		);
	}
	if (error || !request) {
		return (
			<Card className="p-10 text-center">
				<p className="text-muted">{error ?? "Not found"}</p>
				<Link to="/requests" className="mt-4 inline-block text-primary hover:underline">
					← Back to requests
				</Link>
			</Card>
		);
	}

	const exp = expiresIn(request.expires_at);
	const canDecide = request.state === "PENDING";

	return (
		<div className="animate-fade-in">
			<Link to="/requests" className="mb-4 inline-block text-sm text-muted hover:text-text">
				← Back to requests
			</Link>

			{request.resubmitted && request.state === "PENDING" && (
				<div className="mb-4 flex items-center gap-3 rounded-xl border border-changes/40 bg-changes/10 px-4 py-3">
					<span className="animate-pulse-ring rounded-full bg-changes/25 px-2 py-0.5 text-xs font-bold text-changes">
						UPDATED
					</span>
					<p className="text-sm text-text">
						This request was revised by the agent after you requested changes (update #{request.update_count}).
						Please re-review the changes below.
					</p>
				</div>
			)}

			<div className="grid gap-6 lg:grid-cols-3">
				<div className="order-2 lg:order-1 lg:col-span-2">
					<div className="mb-4 flex items-start justify-between gap-4">
						<div>
							<div className="flex flex-wrap items-center gap-2">
								<h1 className="break-words text-xl font-bold tracking-tight sm:text-2xl">{request.title}</h1>
								<StateBadge state={request.state} />
							</div>
							{request.description && <p className="mt-2 text-muted">{request.description}</p>}
						</div>
					</div>

					{request.comment && (
						<div className="mb-5 rounded-xl border border-border bg-surface-raised/40 p-4">
							<p className="mb-1 text-xs font-semibold uppercase tracking-wide text-faint">
								{request.state === "CHANGES_REQUESTED" ? "Changes requested" : "Reviewer note"}
							</p>
							<p className="text-sm text-text">{request.comment}</p>
						</div>
					)}

					<h2 className="mb-3 text-sm font-semibold uppercase tracking-wide text-faint">
						Proposed changes ({request.changes.length})
					</h2>
					<ChangeList changes={request.changes} />
				</div>

				<div className="order-1 space-y-4 lg:order-2">
					{canDecide && (
						<Card className="space-y-2 p-4">
							<p className="mb-1 text-sm font-semibold">Your decision</p>
							<Button variant="success" className="w-full" onClick={() => setDecision("APPROVE")}>
								Approve
							</Button>
							<Button variant="primary" className="w-full" onClick={() => setDecision("REQUEST_CHANGES")}>
								Request changes
							</Button>
							<Button variant="danger" className="w-full" onClick={() => setDecision("REJECT")}>
								Reject
							</Button>
							<p className={`pt-1 text-center text-xs ${exp.urgent ? "text-pending" : "text-faint"}`}>
								{exp.text}
							</p>
						</Card>
					)}

					<Card className="p-4">
						<p className="mb-3 text-sm font-semibold">Agent</p>
						{request.agent ? (
							<div className="flex items-center gap-3">
								<AgentAvatar name={request.agent.name} iconUrl={request.agent.icon_url} />
								<div className="min-w-0">
									<p className="truncate text-sm font-medium">{request.agent.name}</p>
									{request.agent.website && (
										<a
											href={request.agent.website}
											target="_blank"
											rel="noreferrer"
											className="truncate text-xs text-primary hover:underline"
										>
											{request.agent.website}
										</a>
									)}
								</div>
							</div>
						) : (
							<p className="text-sm text-muted">Unknown</p>
						)}
						{request.agent?.description && (
							<p className="mt-2 text-xs text-muted">{request.agent.description}</p>
						)}
					</Card>

					<Card className="space-y-2 p-4 text-xs">
						<Row label="Request ID" value={<code className="text-[11px]">{request.request_id}</code>} />
						<Row
							label="Content hash"
							value={<code className="text-[11px] break-all text-muted">{request.content_hash}</code>}
						/>
						<Row label="Created" value={relativeTime(request.created_at)} />
						<Row label="Expires" value={formatDateTime(request.expires_at)} />
						{request.decided_at && <Row label="Decided" value={formatDateTime(request.decided_at)} />}
						{request.consumed_at && <Row label="Consumed" value={formatDateTime(request.consumed_at)} />}
						{request.update_count > 0 && <Row label="Updates" value={String(request.update_count)} />}
					</Card>

					{request.metadata && Object.keys(request.metadata).length > 0 && (
						<Card className="p-4">
							<p className="mb-2 text-sm font-semibold">Metadata</p>
							<div className="space-y-1 text-xs">
								{Object.entries(request.metadata).map(([k, v]) => (
									<Row key={k} label={k} value={<span className="text-muted">{String(v)}</span>} />
								))}
							</div>
						</Card>
					)}

					{request.receipt && (
						<Card className="border-approved/30 bg-approved/5 p-4">
							<p className="mb-2 flex items-center gap-2 text-sm font-semibold text-approved">
								<span>🔏</span> Signed receipt
							</p>
							<div className="space-y-1 text-xs">
								<Row label="Decision" value={request.receipt.payload.decision} />
								<Row label="Algorithm" value={request.receipt.algorithm} />
								<Row
									label="Signature"
									value={<code className="text-[11px] break-all text-muted">{request.receipt.signature}</code>}
								/>
							</div>
						</Card>
					)}
				</div>
			</div>

			<DecisionModal request={request} decision={decision} onClose={() => setDecision(null)} onDone={setRequest} />
		</div>
	);
}

function Row({ label, value }: { label: string; value: React.ReactNode }) {
	return (
		<div className="flex flex-col gap-1 sm:flex-row sm:items-start sm:justify-between sm:gap-3">
			<span className="shrink-0 text-faint">{label}</span>
			<span className="break-all text-text sm:text-right">{value}</span>
		</div>
	);
}
