import type { PlayerCharacter } from "@initiative/domain";
import { X } from "lucide-react";
import { useEffect, useState } from "react";
import { ColorPalette } from "./color-palette";
import { IconGrid } from "./icon-grid";
import { Button } from "./ui/button";
import { Dialog } from "./ui/dialog";
import { Input } from "./ui/input";

function parseLevel(value: string): number | undefined | "invalid" {
	if (value.trim() === "") return undefined;
	const n = Number.parseInt(value, 10);
	if (Number.isNaN(n) || n < 1 || n > 20) return "invalid";
	return n;
}

interface CreatePlayerModalProps {
	open: boolean;
	onClose: () => void;
	onSave: (
		name: string,
		ac: number,
		maxHp: number,
		color: string | undefined,
		icon: string | undefined,
		level: number | undefined,
	) => void;
	playerCharacter?: PlayerCharacter;
}

export function CreatePlayerModal({
	open,
	onClose,
	onSave,
	playerCharacter,
}: Readonly<CreatePlayerModalProps>) {
	const [name, setName] = useState("");
	const [ac, setAc] = useState("10");
	const [maxHp, setMaxHp] = useState("10");
	const [color, setColor] = useState("blue");
	const [icon, setIcon] = useState("sword");
	const [level, setLevel] = useState("");
	const [error, setError] = useState("");

	const isEdit = !!playerCharacter;

	useEffect(() => {
		if (open) {
			if (playerCharacter) {
				setName(playerCharacter.name);
				setAc(String(playerCharacter.ac));
				setMaxHp(String(playerCharacter.maxHp));
				setColor(playerCharacter.color ?? "");
				setIcon(playerCharacter.icon ?? "");
				setLevel(
					playerCharacter.level === undefined
						? ""
						: String(playerCharacter.level),
				);
			} else {
				setName("");
				setAc("10");
				setMaxHp("10");
				setColor("");
				setIcon("");
				setLevel("");
			}
			setError("");
		}
	}, [open, playerCharacter]);

	const handleSubmit = (e: React.SubmitEvent<HTMLFormElement>) => {
		e.preventDefault();
		const trimmed = name.trim();
		if (trimmed === "") {
			setError("Name is required");
			return;
		}
		const acNum = Number.parseInt(ac, 10);
		if (Number.isNaN(acNum) || acNum < 0) {
			setError("AC must be a non-negative number");
			return;
		}
		const hpNum = Number.parseInt(maxHp, 10);
		if (Number.isNaN(hpNum) || hpNum < 1) {
			setError("Max HP must be at least 1");
			return;
		}
		const levelNum = parseLevel(level);
		if (levelNum === "invalid") {
			setError("Level must be between 1 and 20");
			return;
		}
		onSave(
			trimmed,
			acNum,
			hpNum,
			color || undefined,
			icon || undefined,
			levelNum,
		);
		onClose();
	};

	return (
		<Dialog open={open} onClose={onClose} className="card-glow w-full max-w-md">
			<div className="mb-4 flex items-center justify-between">
				<h2 className="font-semibold text-foreground text-lg">
					{isEdit ? "Edit Player" : "Create Player"}
				</h2>
				<Button
					variant="ghost"
					size="icon"
					onClick={onClose}
					className="text-muted-foreground"
				>
					<X size={20} />
				</Button>
			</div>

			<form onSubmit={handleSubmit} className="flex flex-col gap-4">
				<div>
					<span className="mb-1 block text-muted-foreground text-sm">Name</span>
					<Input
						type="text"
						value={name}
						onChange={(e) => {
							setName(e.target.value);
							setError("");
						}}
						placeholder="Character name"
						aria-label="Name"
						autoFocus
					/>
					{!!error && <p className="mt-1 text-destructive text-sm">{error}</p>}
				</div>

				<div className="flex gap-3">
					<div className="flex-1">
						<span className="mb-1 block text-muted-foreground text-sm">AC</span>
						<Input
							type="text"
							inputMode="numeric"
							value={ac}
							onChange={(e) => setAc(e.target.value)}
							placeholder="AC"
							aria-label="AC"
							className="text-center"
						/>
					</div>
					<div className="flex-1">
						<span className="mb-1 block text-muted-foreground text-sm">
							Max HP
						</span>
						<Input
							type="text"
							inputMode="numeric"
							value={maxHp}
							onChange={(e) => setMaxHp(e.target.value)}
							placeholder="Max HP"
							aria-label="Max HP"
							className="text-center"
						/>
					</div>
					<div className="flex-1">
						<span className="mb-1 block text-muted-foreground text-sm">
							Level
						</span>
						<Input
							type="text"
							inputMode="numeric"
							value={level}
							onChange={(e) => setLevel(e.target.value)}
							placeholder="1-20"
							aria-label="Level"
							className="text-center"
						/>
					</div>
				</div>

				<div>
					<span className="mb-2 block text-muted-foreground text-sm">
						Color
					</span>
					<ColorPalette value={color} onChange={setColor} />
				</div>

				<div>
					<span className="mb-2 block text-muted-foreground text-sm">Icon</span>
					<IconGrid value={icon} onChange={setIcon} />
				</div>

				<div className="flex justify-end gap-2 pt-2">
					<Button type="button" variant="ghost" onClick={onClose}>
						Cancel
					</Button>
					<Button type="submit">{isEdit ? "Save" : "Create"}</Button>
				</div>
			</form>
		</Dialog>
	);
}
