import { useCallback, useEffect, useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";

import { listProjects } from "../api/projects";
import { getUserSessions } from "../api/sessions";
import { listToolTypes } from "../api/tool-types";
import { getUserConfig } from "../api/settings";
import { Icon } from "../components/ui/Icon";
import { LoadingState, ErrorState } from "../components/ui";
import { CreateSessionForm, SessionList } from "../components/features/session";
import type { Project } from "../types/project";
import type { Session } from "../types/session";
import type { ToolType } from "../types/tool-type";

type SessionsStatus = "loading" | "ready" | "error";

export const SessionsPage = () => {
	const navigate = useNavigate();
	const [status, setStatus] = useState<SessionsStatus>("loading");
	const [sessions, setSessions] = useState<Session[]>([]);
	const [lastSessionId, setLastSessionId] = useState<string | null>(null);
	const [projects, setProjects] = useState<Project[]>([]);
	const [toolTypes, setToolTypes] = useState<ToolType[]>([]);

	const loadSessions = useCallback(async () => {
		setStatus("loading");
		try {
			const [sessionsData, config] = await Promise.all([
				getUserSessions(),
				getUserConfig(),
			]);
			setSessions(sessionsData);
			setLastSessionId(config.last_session_id ?? null);
			setStatus("ready");
		} catch {
			setStatus("error");
		}
	}, []);

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

	useEffect(() => {
		const loadProjects = async () => {
			try {
				setProjects(await listProjects());
			} catch {
				/* ignore */
			}
		};
		void loadProjects();
	}, []);

	useEffect(() => {
		const loadToolTypes = async () => {
			try {
				setToolTypes(await listToolTypes());
			} catch {
				/* ignore */
			}
		};
		void loadToolTypes();
	}, []);

	const activeSessions = useMemo(
		() =>
			sessions.filter((s) =>
				["running", "building", "pending"].includes(s.status),
			),
		[sessions],
	);

	const recentSessions = useMemo(
		() =>
			sessions
				.filter((s) => ["stopped", "error"].includes(s.status))
				.slice(0, 5),
		[sessions],
	);

	const lastSession = useMemo(
		() => sessions.find((s) => s.id === lastSessionId) ?? null,
		[sessions, lastSessionId],
	);

	const handleOpen = useCallback(
		(session: Session) => {
			if (session.tool_type_interfaces?.includes("terminal")) {
				navigate(`/instances/${session.id}/terminal`);
			} else {
				navigate(`/projects/${session.project_id}`);
			}
		},
		[navigate],
	);

	const handleResumeLast = useCallback(() => {
		if (!lastSession) return;
		const project = projects.find((p) => p.name === lastSession.project_name);
		if (project) navigate(`/projects/${project.id}`);
	}, [lastSession, projects, navigate]);

	return (
		<section className="stack sessions-page">
			<div className="page-header">
				<h1>Sessions</h1>
			</div>

			{status === "loading" && <LoadingState message="Loading sessions..." />}

			{status === "error" && (
				<ErrorState
					message="Failed to load sessions"
					onRetry={() => void loadSessions()}
				/>
			)}

			{status === "ready" && (
				<>
					{/* Last Session */}
					{lastSession && (
						<div className="last-session-section">
							<h2>Last Session</h2>
							<div className="card last-session-card">
								<div className="last-session-info">
									<h3>
										{lastSession.display_name ||
											lastSession.tool_type_name ||
											"Unnamed Session"}
									</h3>
									<p className="muted">
										{lastSession.tool_type_name} · {lastSession.project_name} ·{" "}
										{lastSession.repository_name}
									</p>
									{lastSession.url && (
										<p className="session-url">
											<a
												href={lastSession.url}
												target="_blank"
												rel="noopener noreferrer"
											>
												{lastSession.url}
											</a>
										</p>
									)}
									<span className={`status-badge ${lastSession.status}`}>
										{lastSession.status}
									</span>
								</div>
								<div className="last-session-actions">
									{lastSession.url ? (
										<a
											href={lastSession.url}
											target="_blank"
											rel="noopener noreferrer"
											className="primary-button"
										>
											<Icon name="external" size="sm" /> Open
										</a>
									) : (
										<button
											className="primary-button"
											onClick={handleResumeLast}
											type="button"
										>
											<Icon name="play" size="sm" /> Resume
										</button>
									)}
								</div>
							</div>
						</div>
					)}

					{/* Active Sessions */}
					<div className="active-sessions-section">
						<h2>
							Active Sessions
							{activeSessions.length > 0 && (
								<span className="badge">{activeSessions.length}</span>
							)}
						</h2>
						<SessionList
							sessions={activeSessions}
							variant="active"
							onSessionChange={loadSessions}
							onOpen={handleOpen}
						/>
					</div>

					{/* Recent Sessions */}
					{recentSessions.length > 0 && (
						<div className="recent-sessions-section">
							<h2>Recent Sessions</h2>
							<SessionList
								sessions={recentSessions}
								variant="recent"
								onSessionChange={loadSessions}
								onOpen={handleOpen}
							/>
						</div>
					)}

					{/* Create Session */}
					<CreateSessionForm
						projects={projects}
						toolTypes={toolTypes}
						onCreated={loadSessions}
					/>
				</>
			)}
		</section>
	);
};
