import { useCallback, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { Icon } from "../../icon";
import { LoadingOverlay } from "../../loading-overlay";
import type { ToolInstance } from "../../../api/sessions";
import {
	deleteInstance,
	listInstances,
	restartInstance,
	startInstance,
	stopInstance,
} from "../../../api/sessions";
import type { ToolType } from "../../../api/tool-types";
import { CreateSessionForm } from "../session/create-session-form";
import {
	listConfigProfiles,
	type ConfigProfile,
} from "../../../api/config-profiles";
import { listSSHKeys, type SSHKey } from "../../../api/ssh-keys";
import { useEventContext } from "../../../state/events";
import { useSessions } from "../../../state/sessions";

const API_BASE_URL =
	import.meta.env.VITE_API_BASE_URL ?? "http://localhost:8000";

interface InstanceListProps {
	projectId: string;
	repoId: string;
	projectName?: string;
	repoName?: string;
	toolTypes: ToolType[];
}

export const InstanceList = ({
	projectId,
	repoId,
	projectName,
	repoName,
	toolTypes,
}: InstanceListProps) => {
	const navigate = useNavigate();
	const { refreshSessions } = useSessions();
	const [instances, setInstances] = useState<ToolInstance[]>([]);
	const [loading, setLoading] = useState(false);
	const [showCreate, setShowCreate] = useState(false);
	const [error, setError] = useState<string | null>(null);

	// Stop confirmation
	const [stopConfirmId, setStopConfirmId] = useState<string | null>(null);

	// Config profile selection for start/restart
	const [configProfiles, setConfigProfiles] = useState<ConfigProfile[]>([]);
	const [profileSelectInstanceId, setProfileSelectInstanceId] = useState<
		string | null
	>(null);
	const [selectedProfileForAction, setSelectedProfileForAction] = useState("");
	const [selectedSshKeyIdsForAction, setSelectedSshKeyIdsForAction] = useState<
		string[]
	>([]);
	const [sshKeys, setSshKeys] = useState<SSHKey[]>([]);

	// Per-instance busy state for actions
	const [busyInstanceId, setBusyInstanceId] = useState<string | null>(null);
	const [busyLabel, setBusyLabel] = useState("Working...");

	const loadInstances = useCallback(async () => {
		setLoading(true);
		try {
			const data = await listInstances(projectId, repoId);
			setInstances(data);
		} catch {
			setError("Failed to load instances");
		} finally {
			setLoading(false);
		}
	}, [projectId, repoId]);

	const { events } = useEventContext();

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

	// Lightweight list refresh every 60 seconds for resilience
	useEffect(() => {
		const interval = setInterval(() => void loadInstances(), 60000);
		return () => clearInterval(interval);
	}, [loadInstances]);

	// Real-time status updates from SSE events
	useEffect(() => {
		if (events.length === 0) return;
		const latestEvent = events[events.length - 1];
		const statusEvents = [
			"instance.started",
			"instance.health_changed",
			"instance.error",
			"instance.stopped",
			"instance.restarted",
		];
		if (!statusEvents.includes(latestEvent.event)) return;

		setInstances((prev) =>
			prev.map((inst) =>
				inst.id === latestEvent.instance_id
					? { ...inst, status: latestEvent.status ?? inst.status }
					: inst,
			),
		);
	}, [events]);

	const handleCreateSuccess = async () => {
		setShowCreate(false);
		await loadInstances();
		await refreshSessions();
	};

	const loadConfigProfiles = useCallback(
		async (toolTypeId: string) => {
			try {
				const [profiles, keys] = await Promise.all([
					listConfigProfiles(projectId, toolTypeId),
					listSSHKeys(),
				]);
				setConfigProfiles(profiles);
				setSshKeys(keys);
			} catch {
				// ignore
			}
		},
		[projectId],
	);

	const handleStart = async (
		instanceId: string,
		configProfileId?: string,
		sshKeyIds?: string[],
	) => {
		setBusyInstanceId(instanceId);
		setBusyLabel("Starting...");
		try {
			await startInstance(
				projectId,
				repoId,
				instanceId,
				configProfileId,
				sshKeyIds,
			);
			setProfileSelectInstanceId(null);
			setSelectedProfileForAction("");
			setSelectedSshKeyIdsForAction([]);
			await loadInstances();
		} catch {
			setError("Failed to start instance");
		} finally {
			setBusyInstanceId(null);
		}
	};

	const handleStop = async (instanceId: string) => {
		setBusyInstanceId(instanceId);
		setBusyLabel("Stopping...");
		try {
			await stopInstance(projectId, repoId, instanceId);
			setStopConfirmId(null);
			await loadInstances();
		} catch {
			setError("Failed to stop instance");
		} finally {
			setBusyInstanceId(null);
		}
	};

	const handleRestart = async (
		instanceId: string,
		configProfileId?: string,
		sshKeyIds?: string[],
	) => {
		setBusyInstanceId(instanceId);
		setBusyLabel("Restarting...");
		try {
			await restartInstance(
				projectId,
				repoId,
				instanceId,
				configProfileId,
				sshKeyIds,
			);
			setProfileSelectInstanceId(null);
			setSelectedProfileForAction("");
			setSelectedSshKeyIdsForAction([]);
			await loadInstances();
		} catch {
			setError("Failed to restart instance");
		} finally {
			setBusyInstanceId(null);
		}
	};

	const handleDelete = async (instanceId: string) => {
		if (!confirm("Are you sure you want to delete this instance?")) return;
		setBusyInstanceId(instanceId);
		setBusyLabel("Deleting...");
		try {
			await deleteInstance(projectId, repoId, instanceId);
			// Update state immediately instead of reloading
			setInstances((prev) => prev.filter((i) => i.id !== instanceId));
			await refreshSessions();
		} catch {
			setError("Failed to delete instance");
		} finally {
			setBusyInstanceId(null);
		}
	};

	const getStatusColor = (status: string) => {
		switch (status) {
			case "running":
				return "var(--success)";
			case "starting":
			case "probing":
				return "var(--info)";
			case "unhealthy":
				return "var(--warning)";
			case "error":
				return "var(--danger)";
			case "pending":
			case "building":
				return "var(--warning)";
			default:
				return "var(--muted)";
		}
	};

	return (
		<div className="instance-list">
			<div className="instance-list-header">
				<h3>Tool Instances</h3>
				<button
					className="secondary-button small"
					onClick={() => setShowCreate(true)}
					type="button"
				>
					<Icon name="add" size="sm" />
					Launch Tool
				</button>
			</div>

			{error && <div className="error-message">{error}</div>}

			{loading ? (
				<p className="muted">Loading instances...</p>
			) : instances.length === 0 ? (
				<p className="muted">No instances yet. Launch a tool to get started.</p>
			) : (
				<div className="instance-grid">
					{instances.map((instance) => (
						<div key={instance.id} className="instance-card">
							<LoadingOverlay
								visible={busyInstanceId === instance.id}
								label={busyLabel}
							/>
							<div className="instance-info">
								<div className="instance-name">{instance.display_name}</div>
								<div className="instance-meta">
									<span
										className="status-dot"
										style={{ backgroundColor: getStatusColor(instance.status) }}
									/>
									{instance.status}
								</div>
								{instance.selected_config_profile_id && (
									<div className="instance-profile">
										<span className="badge">
											Profile:{" "}
											{configProfiles.find(
												(p) => p.id === instance.selected_config_profile_id,
											)?.name || instance.selected_config_profile_id}
										</span>
									</div>
								)}
							</div>
							<div className="instance-actions">
								{instance.status === "running" &&
									instance.url &&
									instance.tool_type_interfaces.includes("web") && (
										<>
											<a
												href={
													instance.url.startsWith("http")
														? instance.url
														: `${API_BASE_URL}${instance.url}`
												}
												target={`instance-${instance.id}`}
												rel="noreferrer"
												className="secondary-button small"
											>
												<Icon name="external" size="sm" />
												Open
											</a>
										</>
									)}
								{instance.status === "running" &&
									instance.tool_type_interfaces.includes("terminal") && (
										<button
											className="secondary-button small"
											onClick={() =>
												navigate(`/instances/${instance.id}/terminal`)
											}
											type="button"
											disabled={busyInstanceId === instance.id}
										>
											<Icon name="terminal" size="sm" />
											Terminal
										</button>
									)}
								{instance.status !== "running" && (
									<>
										{profileSelectInstanceId === instance.id ? (
											<div className="inline-profile-select">
												<select
													value={selectedProfileForAction}
													onChange={(e) =>
														setSelectedProfileForAction(e.target.value)
													}
												>
													<option value="">Default (none)</option>
													{configProfiles.map((p) => (
														<option key={p.id} value={p.id}>
															{p.name}
														</option>
													))}
												</select>
												<div
													style={{
														display: "flex",
														flexWrap: "wrap",
														gap: "0.25rem",
														marginTop: "0.25rem",
													}}
												>
													{sshKeys.map((key) => (
														<label
															key={key.id}
															className="checkbox-label"
															style={{
																fontSize: "0.75rem",
																display: "flex",
																alignItems: "center",
																gap: "0.25rem",
															}}
														>
															<input
																type="checkbox"
																checked={selectedSshKeyIdsForAction.includes(
																	key.id,
																)}
																onChange={(e) => {
																	if (e.target.checked) {
																		setSelectedSshKeyIdsForAction((prev) => [
																			...prev,
																			key.id,
																		]);
																	} else {
																		setSelectedSshKeyIdsForAction((prev) =>
																			prev.filter((id) => id !== key.id),
																		);
																	}
																}}
															/>
															{key.name}
														</label>
													))}
												</div>
												<button
													className="primary-button small"
													onClick={() =>
														void handleStart(
															instance.id,
															selectedProfileForAction || undefined,
															selectedSshKeyIdsForAction.length > 0
																? selectedSshKeyIdsForAction
																: undefined,
														)
													}
													type="button"
													disabled={busyInstanceId === instance.id}
												>
													<Icon name="play" size="sm" />
													Start
												</button>
												<button
													className="ghost-button small"
													onClick={() => {
														setProfileSelectInstanceId(null);
														setSelectedProfileForAction("");
														setSelectedSshKeyIdsForAction([]);
													}}
													type="button"
													disabled={busyInstanceId === instance.id}
												>
													Cancel
												</button>
											</div>
										) : (
											<button
												className="secondary-button small"
												onClick={() => {
													const toolType = toolTypes.find(
														(t) => t.id === instance.tool_type_id,
													);
													if (toolType) {
														void loadConfigProfiles(toolType.id);
													}
													setProfileSelectInstanceId(instance.id);
													setSelectedProfileForAction(
														instance.selected_config_profile_id || "",
													);
													setSelectedSshKeyIdsForAction(
														instance.ssh_key_ids || [],
													);
												}}
												type="button"
												disabled={busyInstanceId === instance.id}
											>
												<Icon name="play" size="sm" />
												Start
											</button>
										)}
									</>
								)}
								{instance.status === "running" && (
									<>
										{stopConfirmId === instance.id ? (
											<div className="inline-confirm">
												<span>Stop?</span>
												<button
													className="ghost-button small danger-text"
													onClick={() => void handleStop(instance.id)}
													type="button"
													disabled={busyInstanceId === instance.id}
												>
													Yes
												</button>
												<button
													className="ghost-button small"
													onClick={() => setStopConfirmId(null)}
													type="button"
													disabled={busyInstanceId === instance.id}
												>
													No
												</button>
											</div>
										) : (
											<button
												className="ghost-button small"
												onClick={() => setStopConfirmId(instance.id)}
												type="button"
												disabled={busyInstanceId === instance.id}
											>
												<Icon name="stop" size="sm" />
											</button>
										)}
										{profileSelectInstanceId === instance.id ? (
											<div className="inline-profile-select">
												<select
													value={selectedProfileForAction}
													onChange={(e) =>
														setSelectedProfileForAction(e.target.value)
													}
												>
													<option value="">Default (none)</option>
													{configProfiles.map((p) => (
														<option key={p.id} value={p.id}>
															{p.name}
														</option>
													))}
												</select>
												<div
													style={{
														display: "flex",
														flexWrap: "wrap",
														gap: "0.25rem",
														marginTop: "0.25rem",
													}}
												>
													{sshKeys.map((key) => (
														<label
															key={key.id}
															className="checkbox-label"
															style={{
																fontSize: "0.75rem",
																display: "flex",
																alignItems: "center",
																gap: "0.25rem",
															}}
														>
															<input
																type="checkbox"
																checked={selectedSshKeyIdsForAction.includes(
																	key.id,
																)}
																onChange={(e) => {
																	if (e.target.checked) {
																		setSelectedSshKeyIdsForAction((prev) => [
																			...prev,
																			key.id,
																		]);
																	} else {
																		setSelectedSshKeyIdsForAction((prev) =>
																			prev.filter((id) => id !== key.id),
																		);
																	}
																}}
															/>
															{key.name}
														</label>
													))}
												</div>
												<button
													className="primary-button small"
													onClick={() =>
														void handleRestart(
															instance.id,
															selectedProfileForAction || undefined,
															selectedSshKeyIdsForAction.length > 0
																? selectedSshKeyIdsForAction
																: undefined,
														)
													}
													type="button"
													disabled={busyInstanceId === instance.id}
												>
													<Icon name="refresh" size="sm" />
													Restart
												</button>
												<button
													className="ghost-button small"
													onClick={() => {
														setProfileSelectInstanceId(null);
														setSelectedProfileForAction("");
														setSelectedSshKeyIdsForAction([]);
													}}
													type="button"
													disabled={busyInstanceId === instance.id}
												>
													Cancel
												</button>
											</div>
										) : (
											<button
												className="ghost-button small"
												onClick={() => {
													const toolType = toolTypes.find(
														(t) => t.id === instance.tool_type_id,
													);
													if (toolType) {
														void loadConfigProfiles(toolType.id);
													}
													setProfileSelectInstanceId(instance.id);
													setSelectedProfileForAction(
														instance.selected_config_profile_id || "",
													);
													setSelectedSshKeyIdsForAction(
														instance.ssh_key_ids || [],
													);
												}}
												type="button"
												disabled={busyInstanceId === instance.id}
											>
												<Icon name="refresh" size="sm" />
											</button>
										)}
									</>
								)}
								<button
									className="ghost-button small danger-text"
									onClick={() => void handleDelete(instance.id)}
									type="button"
									disabled={busyInstanceId === instance.id}
								>
									<Icon name="delete" size="sm" />
								</button>
							</div>
						</div>
					))}
				</div>
			)}

			{showCreate && (
				<div className="dialog-overlay" role="dialog" aria-modal="true">
					<div className="dialog">
						<h2>Launch Tool</h2>
						<CreateSessionForm
							projects={[]}
							repositories={[]}
							toolTypes={toolTypes}
							fixedProjectId={projectId}
							fixedRepoId={repoId}
							projectName={projectName}
							repoName={repoName}
							onSuccess={handleCreateSuccess}
							onCancel={() => setShowCreate(false)}
							submitLabel="Launch"
						/>
					</div>
				</div>
			)}
		</div>
	);
};
