import { useEffect, useRef, useState } from "react";

import {
	createRepository,
	parseGitUrl,
	type GitRepositoryCreate,
	type URLParseResult,
} from "../../../api/git-repositories";
import { listSSHKeys, type SSHKey } from "../../../api/ssh-keys";
import { Icon } from "../../icon";

type CreateMode = "clone" | "blank";
type UrlValidationStatus =
	| "idle"
	| "validating"
	| "valid"
	| "needs-parsing"
	| "invalid";

interface RepositoryCreateDialogProps {
	projectId: string;
	open: boolean;
	title: string;
	onClose: () => void;
	onCreated: () => Promise<void> | void;
}

export const RepositoryCreateDialog = ({
	projectId,
	open,
	title,
	onClose,
	onCreated,
}: RepositoryCreateDialogProps) => {
	const [createMode, setCreateMode] = useState<CreateMode>("clone");
	const [formName, setFormName] = useState("");
	const [owner, setOwner] = useState("");
	const [repoName, setRepoName] = useState("");
	const [advancedUrl, setAdvancedUrl] = useState("");
	const [useAdvancedUrl, setUseAdvancedUrl] = useState(true);
	const [formError, setFormError] = useState<string | null>(null);
	const [urlValidation, setUrlValidation] = useState<{
		status: UrlValidationStatus;
		result: URLParseResult | null;
	}>({ status: "idle", result: null });
	const [sshKeys, setSshKeys] = useState<SSHKey[]>([]);
	const [selectedSshKey, setSelectedSshKey] = useState<string>("");
	const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

	const isSshUrl = (url: string): boolean => {
		const u = url.trim().toLowerCase();
		return u.startsWith("git@") || u.startsWith("ssh://");
	};

	useEffect(() => {
		if (!open && debounceTimer.current) {
			clearTimeout(debounceTimer.current);
			debounceTimer.current = null;
		}
	}, [open]);

	useEffect(() => {
		if (!open) return;
		const loadKeys = async () => {
			try {
				const data = await listSSHKeys();
				setSshKeys(data);
			} catch {
				// ignore
			}
		};
		void loadKeys();
	}, [open]);

	useEffect(() => {
		if (!open) return;
		if (!useAdvancedUrl) {
			setUrlValidation({ status: "idle", result: null });
			return;
		}

		if (debounceTimer.current) {
			clearTimeout(debounceTimer.current);
		}

		if (!advancedUrl.trim()) {
			setUrlValidation({ status: "idle", result: null });
			return;
		}

		setUrlValidation({ status: "validating", result: null });

		debounceTimer.current = setTimeout(async () => {
			const trimmed = advancedUrl.trim();
			// Short-circuit SSH URLs — the backend parseGitUrl may not always
			// recognise them, but they are valid clone URLs by definition.
			if (isSshUrl(trimmed)) {
				setUrlValidation({
					status: "valid",
					result: {
						original_url: trimmed,
						base_url: trimmed,
						is_valid_clone_url: true,
						needs_parsing: false,
						host: null,
						message: "Valid SSH git URL",
						error_code: null,
					},
				});
				return;
			}
			try {
				const result = await parseGitUrl(trimmed);
				if (result.is_valid_clone_url) {
					setUrlValidation({ status: "valid", result });
				} else if (result.needs_parsing) {
					setUrlValidation({ status: "needs-parsing", result });
				} else {
					setUrlValidation({ status: "invalid", result });
				}
			} catch {
				setUrlValidation({ status: "invalid", result: null });
			}
		}, 300);

		return () => {
			if (debounceTimer.current) {
				clearTimeout(debounceTimer.current);
			}
		};
	}, [advancedUrl, open, useAdvancedUrl]);

	const resetForm = () => {
		setCreateMode("clone");
		setFormName("");
		setOwner("");
		setRepoName("");
		setAdvancedUrl("");
		setUseAdvancedUrl(true);
		setFormError(null);
		setUrlValidation({ status: "idle", result: null });
		setSelectedSshKey("");
	};

	const handleClose = () => {
		resetForm();
		onClose();
	};

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

		if (!formName.trim()) {
			setFormError("Repository name is required");
			return;
		}

		try {
			const input: GitRepositoryCreate = {
				name: formName.trim(),
				remote_url: undefined,
			};

			if (createMode === "clone") {
				let remoteUrl: string;
				if (useAdvancedUrl) {
					if (!advancedUrl.trim()) {
						setFormError("Remote URL is required for advanced cloning");
						return;
					}
					remoteUrl = advancedUrl.trim();
				} else {
					if (!owner.trim() || !repoName.trim()) {
						setFormError("Owner and repository name are required");
						return;
					}
					remoteUrl = `git@git.commumedia.org:${owner.trim()}/${repoName.trim()}.git`;
				}

				if (isSshUrl(remoteUrl) && !selectedSshKey) {
					setFormError("An SSH key is required for SSH URLs");
					return;
				}

				input.remote_url = remoteUrl;
				if (selectedSshKey) {
					input.ssh_key_id = selectedSshKey;
				}
			}

			await createRepository(projectId, input);
			handleClose();
			await onCreated();
		} catch (error: unknown) {
			const response = error as { response?: { data?: { detail?: string } } };
			const detail = response.response?.data?.detail;
			setFormError(
				typeof detail === "string" ? detail : "Failed to create repository",
			);
		}
	};

	const handleUseSuggestedUrl = () => {
		if (urlValidation.result?.base_url) {
			setAdvancedUrl(urlValidation.result.base_url);
			setUrlValidation({ status: "idle", result: null });
			setFormError(null);
		}
	};

	const getUrlInputClass = () => {
		switch (urlValidation.status) {
			case "valid":
				return "valid-url";
			case "needs-parsing":
				return "needs-parsing-url";
			case "invalid":
				return "invalid-url";
			default:
				return "";
		}
	};

	if (!open) return null;

	return (
		<div className="dialog-overlay" role="dialog" aria-modal="true">
			<div className="dialog">
				<h3>{title}</h3>
				<p className="muted">
					Clone an existing repository from git.commumedia.org, or create a
					blank bare repo here.
				</p>
				<form onSubmit={handleSubmit} className="stack">
					<div className="form-field repo-mode-radios">
						<label className="repo-mode-label">
							<input
								type="radio"
								name="repository-mode"
								checked={createMode === "clone"}
								onChange={() => setCreateMode("clone")}
							/>
							<span>Clone existing</span>
						</label>
						<label className="repo-mode-label">
							<input
								type="radio"
								name="repository-mode"
								checked={createMode === "blank"}
								onChange={() => setCreateMode("blank")}
							/>
							<span>Create blank</span>
						</label>
					</div>
					<label className="form-field">
						Repository name
						<input
							type="text"
							value={formName}
							onChange={(event) => setFormName(event.target.value)}
							placeholder="repository-name"
						/>
					</label>
					{createMode === "clone" && !useAdvancedUrl && (
						<>
							<label className="form-field">
								Owner
								<input
									type="text"
									value={owner}
									onChange={(event) => setOwner(event.target.value)}
									placeholder="owner"
								/>
							</label>
							<label className="form-field">
								Repository
								<input
									type="text"
									value={repoName}
									onChange={(event) => setRepoName(event.target.value)}
									placeholder="repo-name"
								/>
							</label>
							<label className="form-field">
								SSH Key
								<select
									value={selectedSshKey}
									onChange={(event) => setSelectedSshKey(event.target.value)}
								>
									<option value="">Select SSH key (optional)...</option>
									{sshKeys.map((k) => (
										<option key={k.id} value={k.id}>
											{k.name}
										</option>
									))}
								</select>
							</label>
							<p className="muted">
								SSH target: git@git.commumedia.org:{owner || "owner"}/
								{repoName || "repo"}.git
							</p>
							<button
								type="button"
								className="secondary-button small"
								onClick={() => setUseAdvancedUrl(true)}
							>
								Use full URL instead
							</button>
						</>
					)}
					{createMode === "clone" && useAdvancedUrl && (
						<>
							<label className="form-field">
								Remote URL
								<input
									type="text"
									value={advancedUrl}
									onChange={(event) => setAdvancedUrl(event.target.value)}
									placeholder="https://github.com/user/repo.git"
									className={getUrlInputClass()}
								/>
								{urlValidation.status === "validating" && (
									<span className="validation-status validating">
										Validating...
									</span>
								)}
								{urlValidation.status === "valid" && (
									<span className="validation-status valid">
										<Icon name="success" size="sm" /> Valid git URL
									</span>
								)}
								{urlValidation.status === "needs-parsing" &&
									urlValidation.result && (
										<div className="url-suggestion">
											<span className="validation-status warning">
												<Icon name="warning" size="sm" /> This looks like a
												browser URL
											</span>
											<div className="suggestion-actions">
												<span className="suggested-url">
													Suggested: {urlValidation.result.base_url}
												</span>
												<button
													type="button"
													className="secondary-button small"
													onClick={handleUseSuggestedUrl}
												>
													Use Suggested
												</button>
											</div>
										</div>
									)}
								{urlValidation.status === "invalid" && (
									<span className="validation-status invalid">
										<Icon name="error" size="sm" /> Invalid URL
									</span>
								)}
							</label>
							<label className="form-field">
								SSH Key
								<select
									value={selectedSshKey}
									onChange={(event) => setSelectedSshKey(event.target.value)}
								>
									<option value="">Select SSH key (optional)...</option>
									{sshKeys.map((k) => (
										<option key={k.id} value={k.id}>
											{k.name}
										</option>
									))}
								</select>
							</label>
							<button
								type="button"
								className="secondary-button small"
								onClick={() => setUseAdvancedUrl(false)}
							>
								Use owner/repo instead
							</button>
						</>
					)}
					{formError && (
						<div className="error-message">
							<p className="error-text">{formError}</p>
						</div>
					)}
					<div className="dialog-actions">
						<button
							className="secondary-button"
							onClick={handleClose}
							type="button"
						>
							<Icon name="cancel" size="sm" />
							Cancel
						</button>
						<button className="primary-button" type="submit">
							<Icon name="add" size="sm" />
							{createMode === "clone"
								? "Clone Repository"
								: "Create Blank Repository"}
						</button>
					</div>
				</form>
			</div>
		</div>
	);
};
