/** Unified workspace creation form with project/repo/branch selectors. */

import { useState, useEffect, useCallback } from "react";
import { Icon } from "./icon";
import { listProjects } from "../api/projects";
import { listRepositories } from "../api/git_repositories";
import { createWorkspaceTopLevel } from "../api/workspaces";
import { useGitRepo } from "../hooks/use-git-repo";
import type { ProjectWithRepos } from "../types";
import type { GitRepository } from "../api/git_repositories";

export interface WorkspaceCreateFormProps {
	/** Called after successful creation. */
	onSubmit: () => void | Promise<void>;
	/** Cancel callback. */
	onCancel: () => void;
	/** Optional: pre-selected project ID (hides project selector). */
	defaultProjectId?: string;
	/** Optional: pre-selected repo ID (hides repo selector). */
	defaultRepoId?: string;
}

export function WorkspaceCreateForm({
	onSubmit,
	onCancel,
	defaultProjectId,
	defaultRepoId,
}: WorkspaceCreateFormProps) {
	const isContextual = Boolean(defaultProjectId && defaultRepoId);

	const [projects, setProjects] = useState<ProjectWithRepos[]>([]);
	const [repos, setRepos] = useState<GitRepository[]>([]);
	const [selectedProject, setSelectedProject] = useState(
		defaultProjectId ?? "",
	);
	const [selectedRepo, setSelectedRepo] = useState(defaultRepoId ?? "");
	const [selectedBranch, setSelectedBranch] = useState("");
	const [newBranchName, setNewBranchName] = useState("");
	const [isNewBranch, setIsNewBranch] = useState(false);
	const [name, setName] = useState("");
	const [submitting, setSubmitting] = useState(false);
	const [fetchingProjects, setFetchingProjects] = useState(!isContextual);
	const [error, setError] = useState<string | null>(null);

	/* Git repo hook handles branch fetching, loading, errors */
	const git = useGitRepo(
		selectedProject || undefined,
		selectedRepo || undefined,
	);

	/* Sync local branch state with hook data */
	useEffect(() => {
		if (git.branches.length > 0 && !selectedBranch) {
			const preferred =
				git.defaultBranch && git.branches.includes(git.defaultBranch)
					? git.defaultBranch
					: git.branches[0];
			setSelectedBranch(preferred);
			setIsNewBranch(false);
		} else if (git.error && git.branches.length === 0 && !isNewBranch) {
			// API failed — default to manual entry so user can type a branch
			setIsNewBranch(true);
			setSelectedBranch("__manual__");
		}
	}, [git.branches, git.defaultBranch, git.error, selectedBranch, isNewBranch]);

	/* ── Load projects (standalone mode only) ── */
	const loadProjects = useCallback(async () => {
		if (isContextual) return;
		try {
			const data = await listProjects();
			setProjects(data);
			if (data.length === 1 && !defaultProjectId) {
				setSelectedProject(data[0].id);
			}
		} catch {
			setError("Failed to load projects");
		} finally {
			setFetchingProjects(false);
		}
	}, [isContextual, defaultProjectId]);

	useEffect(() => {
		void loadProjects();
	}, [loadProjects]);

	/* ── Load repos when project changes ── */
	useEffect(() => {
		if (!selectedProject) {
			setRepos([]);
			if (!defaultRepoId) setSelectedRepo("");
			return;
		}
		const loadRepos = async () => {
			try {
				const data = await listRepositories(selectedProject);
				setRepos(data);
				if (data.length === 1 && !defaultRepoId) {
					setSelectedRepo(data[0].id);
				}
			} catch {
				setError("Failed to load repositories");
			}
		};
		void loadRepos();
	}, [selectedProject, defaultRepoId]);

	const handleBranchChange = (value: string) => {
		if (value === "__new__") {
			setIsNewBranch(true);
			setSelectedBranch("__new__");
			setNewBranchName("");
		} else if (value === "__manual__") {
			setIsNewBranch(true);
			setSelectedBranch("__manual__");
			setNewBranchName("");
		} else {
			setIsNewBranch(false);
			setSelectedBranch(value);
		}
	};

	const handleSubmit = async (e: React.FormEvent) => {
		e.preventDefault();
		if (!selectedRepo) {
			setError("Please select a repository");
			return;
		}
		if (!name.trim()) {
			setError("Workspace name is required");
			return;
		}
		const branchName = isNewBranch ? newBranchName.trim() : selectedBranch;
		if (!branchName) {
			setError("Please select or enter a branch");
			return;
		}
		setSubmitting(true);
		setError(null);
		try {
			await createWorkspaceTopLevel({
				repo_id: selectedRepo,
				name: name.trim(),
				branch: branchName,
			});
			await onSubmit();
		} catch (err) {
			setError(
				err instanceof Error ? err.message : "Failed to create workspace",
			);
		} finally {
			setSubmitting(false);
		}
	};

	/* Show single combined error */
	const displayError = error || git.error;

	if (fetchingProjects) {
		return (
			<div className="card workspace-create-inline">
				<p className="muted">Loading projects...</p>
			</div>
		);
	}

	const branchSelectDisabled =
		!selectedRepo || submitting || (git.loading && git.branches.length === 0);

	return (
		<div className="card workspace-create-inline">
			<h3>
				<Icon name="add" size="sm" /> Create Workspace
			</h3>
			<form onSubmit={handleSubmit} className="workspace-create-form-grid">
				{/* Project selector (standalone only) */}
				{!isContextual && (
					<div className="form-group">
						<label>Project</label>
						<select
							value={selectedProject}
							onChange={(e) => {
								setSelectedProject(e.target.value);
								setSelectedBranch("");
							}}
							required
						>
							<option value="">Select project...</option>
							{projects.map((p) => (
								<option key={p.id} value={p.id}>
									{p.name}
								</option>
							))}
						</select>
					</div>
				)}

				{/* Repo selector (standalone only) */}
				{!isContextual && (
					<div className="form-group">
						<label>Repository</label>
						<select
							value={selectedRepo}
							onChange={(e) => {
								setSelectedRepo(e.target.value);
								setSelectedBranch("");
							}}
							required
							disabled={!selectedProject || repos.length === 0}
						>
							<option value="">
								{!selectedProject
									? "Select a project first"
									: repos.length === 0
										? "No repositories"
										: "Select repository..."}
							</option>
							{repos.map((r) => (
								<option key={r.id} value={r.id}>
									{r.name}
								</option>
							))}
						</select>
					</div>
				)}

				<div className="form-group">
					<label>Name</label>
					<input
						type="text"
						value={name}
						onChange={(e) => setName(e.target.value)}
						placeholder="e.g., feature-branch"
						required
						disabled={submitting}
					/>
				</div>

				<div className="form-group">
					<label>
						<Icon name="branch" size="sm" /> Branch
					</label>

					{/* Show a hint when branches couldn’t be loaded */}
					{git.error && git.branches.length === 0 && selectedRepo && (
						<p
							className="muted"
							style={{
								fontSize: "var(--font-size-xs)",
								marginBottom: "0.25rem",
							}}
						>
							Couldn’t load branches — type one manually.
						</p>
					)}

					<select
						value={selectedBranch}
						onChange={(e) => handleBranchChange(e.target.value)}
						required
						disabled={branchSelectDisabled}
					>
						<option value="">
							{git.loading && git.branches.length === 0
								? "Loading branches..."
								: !selectedRepo
									? "Select a repository first"
									: "Select branch..."}
						</option>

						{git.branches.map((b) => (
							<option key={b} value={b}>
								{b}
								{b === git.defaultBranch ? " (default)" : ""}
							</option>
						))}

						<option value="__new__">+ Create new branch...</option>
					</select>

					{/* Text input for new branch or manual entry */}
					{isNewBranch && (
						<input
							type="text"
							value={newBranchName}
							onChange={(e) => setNewBranchName(e.target.value)}
							placeholder="new-branch-name"
							required
							style={{ marginTop: "0.5rem" }}
							disabled={submitting}
						/>
					)}
				</div>

				{displayError && (
					<div className="form-error" style={{ gridColumn: "1 / -1" }}>
						{displayError}
					</div>
				)}

				<div className="form-actions" style={{ gridColumn: "1 / -1" }}>
					<button
						type="button"
						className="btn btn-secondary"
						onClick={onCancel}
						disabled={submitting}
					>
						Cancel
					</button>
					<button
						type="submit"
						className="btn btn-primary"
						disabled={submitting || !selectedRepo}
					>
						{submitting ? "Creating..." : "Create Workspace"}
					</button>
				</div>
			</form>
		</div>
	);
}
