import { useEffect, useState } from "react";
import { toast } from "react-toastify";
import { requests } from "../api/client";
import type { ChangeRequest } from "../api/types";
import { Modal } from "./Modal";
import { Button } from "./ui";

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

const MAX = 500;

const meta: Record<Decision, { title: string; verb: string; variant: "success" | "danger" | "primary"; blurb: string; commentRequired: boolean }> = {
	APPROVE: {
		title: "Approve request",
		verb: "Approve",
		variant: "success",
		blurb: "The agent will be allowed to proceed. A platform-signed receipt will be issued.",
		commentRequired: false,
	},
	REJECT: {
		title: "Reject request",
		verb: "Reject",
		variant: "danger",
		blurb: "This is a hard blocker. The agent must submit a new request to try again.",
		commentRequired: false,
	},
	REQUEST_CHANGES: {
		title: "Request changes",
		verb: "Request changes",
		variant: "primary",
		blurb: "The agent will see your notes and can update the request for re-review.",
		commentRequired: true,
	},
};

export function DecisionModal({
	request,
	decision,
	onClose,
	onDone,
}: {
	request: ChangeRequest;
	decision: Decision | null;
	onClose: () => void;
	onDone: (updated: ChangeRequest) => void;
}) {
	const [comment, setComment] = useState("");
	const [loading, setLoading] = useState(false);

	useEffect(() => {
		setComment("");
	}, [decision]);

	if (!decision) return null;
	const m = meta[decision];
	const tooLong = comment.length > MAX;
	const missingRequired = m.commentRequired && comment.trim().length === 0;

	const submit = async () => {
		if (tooLong || missingRequired) return;
		setLoading(true);
		try {
			const updated = await requests.decide(request.request_id, decision, comment.trim() || undefined);
			toast.success(`${m.verb}d`);
			onDone(updated);
			onClose();
		} catch (err) {
			toast.error(err instanceof Error ? err.message : "Failed");
		} finally {
			setLoading(false);
		}
	};

	return (
		<Modal
			open={!!decision}
			onClose={onClose}
			title={m.title}
			footer={
				<>
					<Button variant="ghost" onClick={onClose}>
						Cancel
					</Button>
					<Button variant={m.variant} onClick={submit} loading={loading} disabled={tooLong || missingRequired}>
						{m.verb}
					</Button>
				</>
			}
		>
			<div className="space-y-4">
				<div className="rounded-lg border border-border bg-surface-raised/50 p-3">
					<p className="text-sm font-medium text-text">{request.title}</p>
					<p className="mt-1 text-xs text-muted">
						{request.changes.length} change{request.changes.length === 1 ? "" : "s"} ·{" "}
						{request.agent?.name}
					</p>
				</div>
				<p className="text-sm text-muted">{m.blurb}</p>
				<div>
					<div className="mb-1 flex items-center justify-between">
						<span className="text-sm text-muted">
							Comment {m.commentRequired ? <span className="text-changes">(required)</span> : "(optional)"}
						</span>
						<span className={`text-xs ${tooLong ? "text-rejected" : comment.length > MAX * 0.8 ? "text-pending" : "text-faint"}`}>
							{comment.length}/{MAX}
						</span>
					</div>
					<textarea
						value={comment}
						onChange={(e) => setComment(e.target.value)}
						rows={4}
						autoFocus
						placeholder={m.commentRequired ? "Explain what needs to change…" : "Add an optional note…"}
						className={`w-full rounded-lg border bg-bg px-3 py-2 text-sm text-text outline-none focus:border-primary ${
							tooLong ? "border-rejected" : "border-border-strong"
						}`}
					/>
					{tooLong && <p className="mt-1 text-xs text-rejected">Comment is too long (max {MAX}).</p>}
					{missingRequired && (
						<p className="mt-1 text-xs text-changes">A comment is required when requesting changes.</p>
					)}
				</div>
			</div>
		</Modal>
	);
}
