import { useState, useEffect } from "react";
import { Icon } from "../../icon";
import { LoadingOverlay } from "../../loading-overlay";
import {
	createInstance,
	startInstance,
	type ToolInstance,
} from "../../../api/sessions";
import type { Project } from "../../../types";
import type { GitRepository } from "../../../api/git-repositories";
import type { ToolType } from "../../../api/tool-types";
import { listSSHKeys, type SSHKey } from "../../../api/ssh-keys";
import {
	listConfigProfiles,
	type ConfigProfile,
} from "../../../api/config-profiles";
import { listWorkspaces, createWorkspace } from "../../../api/workspaces";
import type { Workspace } from "../../../types/workspace";

interface CreateSessionFormProps {
	projects: Project[];
	repositories: GitRepository[];
	toolTypes: ToolType[];
	fixedProjectId?: string;
	fixedRepoId?: string;
	projectName?: string;
	repoName?: string;
	showFixedFields?: boolean;
	onProjectChange?: (projectId: string) => void;
	onSuccess?: (instance: ToolInstance) => void;
	onCancel?: () => void;
	submitLabel?: string;
	className?: string;
}

export const CreateSessionForm = ({
	projects,
	repositories,
	toolTypes,
	fixedProjectId,
	fixedRepoId,
	projectName,
	repoName,
	showFixedFields = true,
	onProjectChange,
	onSuccess,
	onCancel,
	submitLabel = "Create Session",
	className = "",
}: CreateSessionFormProps) => {
	const [selectedProject, setSelectedProject] = useState(fixedProjectId || "");
	const [selectedRepo, setSelectedRepo] = useState(fixedRepoId || "");
	const [selectedToolType, setSelectedToolType] = useState("");
	const [displayName, setDisplayName] = useState("");
	const [sshKeys, setSshKeys] = useState<SSHKey[]>([]);
	const [configProfiles, setConfigProfiles] = useState<ConfigProfile[]>([]);
	const [selectedConfigProfile, setSelectedConfigProfile] = useState("");
	const [selectedSshKeyIds, setSelectedSshKeyIds] = useState<string[]>([]);

	const [workspaces, setWorkspaces] = useState<Workspace[]>([]);
	const [selectedWorkspaceId, setSelectedWorkspaceId] = useState("");
	const [isLoadingWorkspaces, setIsLoadingWorkspaces] = useState(false);

	const [isSubmitting, setIsSubmitting] = useState(false);
	const [error, setError] = useState<string | null>(null);

	// Load SSH keys
	useEffect(() => {
		const loadKeys = async () => {
			try {
				const keys = await listSSHKeys();
				setSshKeys(keys);
			} catch {
				// ignore
			}
		};
		void loadKeys();
	}, []);

	// Load config profiles when tool type is selected
	useEffect(() => {
		const projectId = fixedProjectId || selectedProject;
		if (!selectedToolType || !projectId) {
			setConfigProfiles([]);
			setSelectedConfigProfile("");
			return;
		}
		const loadProfiles = async () => {
			try {
				const profiles = await listConfigProfiles(projectId, selectedToolType);
				setConfigProfiles(profiles);
				// Auto-select default if available
				const defaultProfile = profiles.find((p) => p.is_default);
				if (defaultProfile) {
					setSelectedConfigProfile(defaultProfile.id);
				}
			} catch {
				// ignore
			}
		};
		void loadProfiles();
	}, [selectedToolType, selectedProject, fixedProjectId]);

	// Load workspaces when repository is selected
	useEffect(() => {
		const projectId = fixedProjectId || selectedProject;
		const repoId = fixedRepoId || selectedRepo;
		if (!projectId || !repoId) {
			setWorkspaces([]);
			setSelectedWorkspaceId("");
			return;
		}
		const loadWorkspaces = async () => {
			setIsLoadingWorkspaces(true);
			try {
				const data = await listWorkspaces(projectId, repoId);
				setWorkspaces(data);
				if (data.length > 0) {
					setSelectedWorkspaceId(data[0].id);
				} else {
					// Auto-create a default workspace so the user can start a tool
					const workspace = await createWorkspace(projectId, repoId, {
						name: "default",
						branch: "main",
					});
					setWorkspaces([workspace]);
					setSelectedWorkspaceId(workspace.id);
				}
			} catch (err) {
				setError(
					err instanceof Error ? err.message : "Failed to load workspaces",
				);
				setWorkspaces([]);
				setSelectedWorkspaceId("");
			} finally {
				setIsLoadingWorkspaces(false);
			}
		};
		void loadWorkspaces();
	}, [
		fixedProjectId,
		selectedProject,
		fixedRepoId,
		selectedRepo,
		repositories,
	]);

	// Filter repositories by selected project
	const availableRepos = selectedProject
		? repositories.filter((r) => r.project_id === selectedProject)
		: [];

	const resetForm = () => {
		if (!fixedProjectId) setSelectedProject("");
		if (!fixedRepoId) setSelectedRepo("");
		setSelectedToolType("");
		setDisplayName("");
		setSelectedSshKeyIds([]);
		setSelectedConfigProfile("");
		setWorkspaces([]);
		setSelectedWorkspaceId("");
	};

	const handleSubmit = async (event: React.FormEvent) => {
		event.preventDefault();
		setError(null);

		const projectId = fixedProjectId || selectedProject;
		const repoId = fixedRepoId || selectedRepo;

		if (!projectId || !repoId || !selectedToolType) {
			setError("Project, repository, and tool type are required");
			return;
		}

		setIsSubmitting(true);

		try {
			const workspaceId = selectedWorkspaceId || undefined;
			if (!workspaceId) {
				setError("No workspace available for the selected repository");
				setIsSubmitting(false);
				return;
			}

			const instance = await createInstance(
				projectId,
				repoId,
				selectedToolType,
				displayName || undefined,
				workspaceId,
				selectedConfigProfile || undefined,
				selectedSshKeyIds.length > 0 ? selectedSshKeyIds : undefined,
			);

			await startInstance(
				projectId,
				repoId,
				instance.id,
				selectedConfigProfile || undefined,
				selectedSshKeyIds.length > 0 ? selectedSshKeyIds : undefined,
			);

			resetForm();
			onSuccess?.(instance);
		} catch {
			setError("Failed to create session");
		} finally {
			setIsSubmitting(false);
		}
	};

	const hasProject = !!(fixedProjectId || selectedProject);
	const hasRepo = !!(fixedRepoId || selectedRepo);
	const hasToolType = !!selectedToolType;

	return (
		<div className={`create-session-form-wrapper ${className}`}>
			<LoadingOverlay visible={isSubmitting} label="Creating session..." />
			<form onSubmit={handleSubmit} className="stack create-session-form">
				{/* Project */}
				<div className="form-field">
					<label>Project</label>
					{fixedProjectId && showFixedFields ? (
						<input
							type="text"
							value={
								projectName ||
								projects.find((p) => p.id === fixedProjectId)?.name ||
								""
							}
							disabled
							readOnly
						/>
					) : (
						<select
							value={selectedProject}
							onChange={(e) => {
								const value = e.target.value;
								setSelectedProject(value);
								setSelectedRepo("");
								setSelectedToolType("");
								onProjectChange?.(value);
							}}
							disabled={isSubmitting}
						>
							<option value="">Select project...</option>
							{projects.map((p) => (
								<option key={p.id} value={p.id}>
									{p.name}
								</option>
							))}
						</select>
					)}
				</div>

				{/* Repository */}
				{hasProject && (
					<div className="form-field">
						<label>Repository</label>
						{fixedRepoId && showFixedFields ? (
							<input
								type="text"
								value={
									repoName ||
									repositories.find((r) => r.id === fixedRepoId)?.name ||
									""
								}
								disabled
								readOnly
							/>
						) : (
							<select
								value={selectedRepo}
								onChange={(e) => {
									setSelectedRepo(e.target.value);
									setSelectedToolType("");
									setSelectedWorkspaceId("");
								}}
								disabled={!hasProject || isSubmitting}
							>
								<option value="">Select repository...</option>
								{availableRepos.map((r) => (
									<option key={r.id} value={r.id}>
										{r.name}
									</option>
								))}
							</select>
						)}
					</div>
				)}

				{/* Workspace */}
				{hasRepo && (
					<div className="form-field">
						<label>Workspace</label>
						{isLoadingWorkspaces ? (
							<span className="muted">Loading workspaces...</span>
						) : workspaces.length === 0 ? (
							<span className="muted">No workspace available</span>
						) : (
							<select
								value={selectedWorkspaceId}
								onChange={(e) => setSelectedWorkspaceId(e.target.value)}
								disabled={!hasRepo || isSubmitting || isLoadingWorkspaces}
							>
								{workspaces.map((w) => (
									<option key={w.id} value={w.id}>
										{w.name} ({w.branch})
									</option>
								))}
							</select>
						)}
					</div>
				)}

				{/* Tool Type */}
				{hasRepo && (
					<div className="form-field">
						<label>Tool</label>
						<select
							value={selectedToolType}
							onChange={(e) => {
								setSelectedToolType(e.target.value);
							}}
							disabled={!hasRepo || isSubmitting}
						>
							<option value="">Select tool...</option>
							{toolTypes.map((t) => (
								<option key={t.id} value={t.id}>
									{t.display_name}
								</option>
							))}
						</select>
					</div>
				)}

				{/* Config Profile */}
				{hasToolType && (
					<div className="form-field">
						<label>Config Profile (optional)</label>
						<select
							value={selectedConfigProfile}
							onChange={(e) => setSelectedConfigProfile(e.target.value)}
							disabled={!hasToolType || isSubmitting}
						>
							<option value="">No profile (use tool defaults)</option>
							{configProfiles.map((p) => (
								<option key={p.id} value={p.id}>
									{p.name} {p.is_default ? "(default)" : ""}
								</option>
							))}
						</select>
					</div>
				)}

				{/* SSH Keys */}
				{hasToolType && (
					<div className="form-field">
						<label>SSH Keys (optional)</label>
						<div style={{ display: "flex", flexWrap: "wrap", gap: "0.5rem" }}>
							{sshKeys.length === 0 && (
								<span className="muted">No SSH keys configured.</span>
							)}
							{sshKeys.map((key) => (
								<label
									key={key.id}
									className="checkbox-label"
									style={{
										display: "flex",
										alignItems: "center",
										gap: "0.25rem",
										padding: "0.375rem 0.75rem",
										background: "var(--panel)",
										borderRadius: "0.375rem",
										border: "1px solid var(--border)",
										cursor: "pointer",
									}}
								>
									<input
										type="checkbox"
										checked={selectedSshKeyIds.includes(key.id)}
										onChange={(e) => {
											if (e.target.checked) {
												setSelectedSshKeyIds((prev) => [...prev, key.id]);
											} else {
												setSelectedSshKeyIds((prev) =>
													prev.filter((id) => id !== key.id),
												);
											}
										}}
										disabled={isSubmitting}
									/>
									{key.name}
								</label>
							))}
						</div>
						<div className="hint" style={{ marginTop: "0.5rem" }}>
							Selected keys will be mounted into the container at ~/.ssh
						</div>
					</div>
				)}

				{/* Display Name */}
				{hasToolType && (
					<div className="form-field">
						<label>Display Name (optional)</label>
						<input
							type="text"
							value={displayName}
							onChange={(e) => setDisplayName(e.target.value)}
							placeholder="My Development Environment"
							disabled={isSubmitting}
						/>
					</div>
				)}

				{/* Error & Submit */}
				{error && <p className="error-text">{error}</p>}

				{hasToolType && (
					<div className="form-actions">
						{onCancel && (
							<button
								className="secondary-button"
								type="button"
								onClick={onCancel}
								disabled={isSubmitting}
							>
								Cancel
							</button>
						)}
						<button
							className="primary-button"
							type="submit"
							disabled={isSubmitting}
						>
							{isSubmitting ? (
								<>
									<Icon name="loading" size="sm" />
									Creating...
								</>
							) : (
								<>
									<Icon name="add" size="sm" />
									{submitLabel}
								</>
							)}
						</button>
					</div>
				)}
			</form>
		</div>
	);
};
