import { useCallback, useState } from "react";
import type { WizardStateData, WizardStepInfo } from "../api/client";

const API_BASE = "/api";

interface SetupWizardProps {
	wizardState: WizardStateData;
	onWizardUpdate: (state: WizardStateData) => void;
	sendMessage: (message: string) => void;
}

/** Style constants for the wizard UI. */
const STEP_BG_PENDING = "#1a1f2e";
const STEP_BG_ACTIVE = "#1c2a1c";
const STEP_BG_DONE = "#1a2a1a";
const STEP_BORDER_PENDING = "#2a2f3e";
const STEP_BORDER_ACTIVE = "#2d4a2d";
const STEP_BORDER_DONE = "#2d4a2d";
const COLOR_LABEL = "#ccc";
const COLOR_LABEL_DONE = "#a0d4a0";
const COLOR_ACCENT = "#a0d4a0";

function statusIcon(status: string): string {
	switch (status) {
		case "confirmed":
			return "\u2713";
		case "skipped":
			return "\u2013";
		case "generating":
			return "\u2026";
		case "awaiting_confirmation":
			return "?";
		default:
			return "\u00B7";
	}
}

function stepBackground(status: string, isActive: boolean): string {
	if (status === "confirmed" || status === "skipped") return STEP_BG_DONE;
	if (isActive) return STEP_BG_ACTIVE;
	return STEP_BG_PENDING;
}

function stepBorder(status: string, isActive: boolean): string {
	if (status === "confirmed" || status === "skipped") return STEP_BORDER_DONE;
	if (isActive) return STEP_BORDER_ACTIVE;
	return STEP_BORDER_PENDING;
}

/** Messages sent to the chat to trigger agent generation for each step. */
const STEP_PROMPTS: Record<string, string> = {
	context:
		"Read the codebase and generate .huskies/specs/00_CONTEXT.md with a project context spec. Include High-Level Goal, Core Features, Domain Definition, and Glossary sections. Then call the wizard API to store the content: PUT /api/wizard/step/context/content",
	stack:
		"Read the tech stack and generate .huskies/specs/tech/STACK.md with a tech stack spec. Include Core Stack, Coding Standards, Quality Gates, and Libraries sections. Then call the wizard API to store the content: PUT /api/wizard/step/stack/content",
	test_script:
		"Read the project structure and create script/test — a bash script that runs the project's actual test suite. Then call the wizard API: PUT /api/wizard/step/test_script/content",
	release_script:
		"Read the project's deployment setup and create script/release tailored to the project. Then call the wizard API: PUT /api/wizard/step/release_script/content",
	test_coverage:
		"If the stack supports coverage reporting, create script/test_coverage. Then call the wizard API: PUT /api/wizard/step/test_coverage/content",
};

async function apiPost(path: string): Promise<WizardStateData | null> {
	try {
		const resp = await fetch(`${API_BASE}${path}`, { method: "POST" });
		if (!resp.ok) return null;
		return (await resp.json()) as WizardStateData;
	} catch {
		return null;
	}
}

function StepCard({
	step,
	isActive,
	onGenerate,
	onConfirm,
	onSkip,
}: {
	step: WizardStepInfo;
	isActive: boolean;
	onGenerate: () => void;
	onConfirm: () => void;
	onSkip: () => void;
}) {
	const isDone = step.status === "confirmed" || step.status === "skipped";

	return (
		<div
			data-testid={`wizard-step-${step.step}`}
			style={{
				padding: "16px",
				borderRadius: "8px",
				background: stepBackground(step.status, isActive),
				border: `1px solid ${stepBorder(step.status, isActive)}`,
				opacity: !isActive && !isDone ? 0.5 : 1,
				transition: "all 0.2s ease",
			}}
		>
			<div
				style={{
					display: "flex",
					alignItems: "center",
					gap: "12px",
				}}
			>
				<span
					style={{
						width: "24px",
						height: "24px",
						borderRadius: "50%",
						display: "flex",
						alignItems: "center",
						justifyContent: "center",
						fontSize: "14px",
						fontWeight: 600,
						background: isDone ? COLOR_ACCENT : "transparent",
						border: isDone ? "none" : `1px solid ${COLOR_LABEL}`,
						color: isDone ? "#1a1a1a" : COLOR_LABEL,
					}}
				>
					{statusIcon(step.status)}
				</span>
				<span
					style={{
						flex: 1,
						color: isDone ? COLOR_LABEL_DONE : COLOR_LABEL,
						fontWeight: isActive ? 600 : 400,
					}}
				>
					{step.label}
				</span>
				{isActive && step.status === "pending" && (
					<button
						type="button"
						data-testid={`wizard-generate-${step.step}`}
						onClick={onGenerate}
						style={{
							padding: "6px 14px",
							borderRadius: "6px",
							border: "none",
							backgroundColor: COLOR_ACCENT,
							color: "#1a1a1a",
							cursor: "pointer",
							fontSize: "0.85rem",
							fontWeight: 600,
						}}
					>
						Generate
					</button>
				)}
				{isActive && step.status === "generating" && (
					<span style={{ color: "#aaa", fontSize: "0.85rem" }}>
						Generating...
					</span>
				)}
			</div>

			{step.content && step.status === "awaiting_confirmation" && (
				<div style={{ marginTop: "12px" }}>
					<pre
						data-testid={`wizard-preview-${step.step}`}
						style={{
							background: "#111",
							padding: "12px",
							borderRadius: "6px",
							fontSize: "0.8rem",
							color: "#ddd",
							whiteSpace: "pre-wrap",
							maxHeight: "200px",
							overflow: "auto",
							margin: "0 0 12px 0",
						}}
					>
						{step.content}
					</pre>
					<div style={{ display: "flex", gap: "8px" }}>
						<button
							type="button"
							data-testid={`wizard-confirm-${step.step}`}
							onClick={onConfirm}
							style={{
								padding: "6px 14px",
								borderRadius: "6px",
								border: "none",
								backgroundColor: COLOR_ACCENT,
								color: "#1a1a1a",
								cursor: "pointer",
								fontSize: "0.85rem",
								fontWeight: 600,
							}}
						>
							Confirm
						</button>
						<button
							type="button"
							data-testid={`wizard-revise-${step.step}`}
							onClick={onGenerate}
							style={{
								padding: "6px 14px",
								borderRadius: "6px",
								border: "1px solid #555",
								backgroundColor: "transparent",
								color: "#ccc",
								cursor: "pointer",
								fontSize: "0.85rem",
							}}
						>
							Revise
						</button>
						<button
							type="button"
							data-testid={`wizard-skip-${step.step}`}
							onClick={onSkip}
							style={{
								padding: "6px 14px",
								borderRadius: "6px",
								border: "1px solid #555",
								backgroundColor: "transparent",
								color: "#888",
								cursor: "pointer",
								fontSize: "0.85rem",
							}}
						>
							Skip
						</button>
					</div>
				</div>
			)}

			{isActive && step.status === "pending" && !step.content && (
				<div style={{ marginTop: "8px", display: "flex", gap: "8px" }}>
					<button
						type="button"
						data-testid={`wizard-skip-${step.step}`}
						onClick={onSkip}
						style={{
							padding: "4px 10px",
							borderRadius: "6px",
							border: "1px solid #444",
							backgroundColor: "transparent",
							color: "#888",
							cursor: "pointer",
							fontSize: "0.8rem",
						}}
					>
						Skip this step
					</button>
				</div>
			)}
		</div>
	);
}

export default function SetupWizard({
	wizardState,
	onWizardUpdate,
	sendMessage,
}: SetupWizardProps) {
	const [, setRefreshKey] = useState(0);

	const handleGenerate = useCallback(
		(step: WizardStepInfo) => {
			const prompt = STEP_PROMPTS[step.step];
			if (prompt) {
				sendMessage(prompt);
			}
		},
		[sendMessage],
	);

	const handleConfirm = useCallback(
		async (step: WizardStepInfo) => {
			const result = await apiPost(`/wizard/step/${step.step}/confirm`);
			if (result) {
				onWizardUpdate(result);
				setRefreshKey((k) => k + 1);
			}
		},
		[onWizardUpdate],
	);

	const handleSkip = useCallback(
		async (step: WizardStepInfo) => {
			const result = await apiPost(`/wizard/step/${step.step}/skip`);
			if (result) {
				onWizardUpdate(result);
				setRefreshKey((k) => k + 1);
			}
		},
		[onWizardUpdate],
	);

	if (wizardState.completed) {
		return (
			<div
				data-testid="wizard-complete"
				style={{
					padding: "24px",
					borderRadius: "12px",
					background: STEP_BG_DONE,
					border: `1px solid ${STEP_BORDER_DONE}`,
					textAlign: "center",
				}}
			>
				<h3 style={{ margin: "0 0 8px 0", color: COLOR_ACCENT }}>
					Setup Complete
				</h3>
				<p style={{ margin: 0, color: COLOR_LABEL }}>
					Your project is configured. You can start writing stories.
				</p>
			</div>
		);
	}

	return (
		<div
			data-testid="setup-wizard"
			style={{
				display: "flex",
				flexDirection: "column",
				gap: "12px",
			}}
		>
			<div style={{ marginBottom: "8px" }}>
				<h3
					style={{
						margin: "0 0 4px 0",
						color: COLOR_ACCENT,
						fontSize: "1.1rem",
					}}
				>
					Project Setup Wizard
				</h3>
				<p style={{ margin: 0, color: "#999", fontSize: "0.85rem" }}>
					Step {wizardState.current_step_index + 1} of{" "}
					{wizardState.steps.length}
				</p>
			</div>

			{wizardState.steps.map((step, idx) => (
				<StepCard
					key={step.step}
					step={step}
					isActive={idx === wizardState.current_step_index}
					onGenerate={() => handleGenerate(step)}
					onConfirm={() => handleConfirm(step)}
					onSkip={() => handleSkip(step)}
				/>
			))}
		</div>
	);
}
