import { useState } from "react";
import {
	createProject,
	deleteProject,
	listProjects,
	updateProject,
	type ProjectCreateInput,
	type ProjectUpdateInput,
} from "../api/projects";
import { deleteWorkspace, syncWorkspace } from "../api/workspaces";
import { useAsyncData } from "./use-async-data";
import type { ProjectWithRepos, WorkspaceSummary } from "../types";

type DialogMode = "none" | "create" | "edit";

export const useProjects = () => {
	const {
		data: projects,
		status,
		reload,
	} = useAsyncData<ProjectWithRepos[]>(listProjects, []);
	const [dialogMode, setDialogMode] = useState<DialogMode>("none");
	const [editingProject, setEditingProject] = useState<ProjectWithRepos | null>(
		null,
	);
	const [formName, setFormName] = useState("");
	const [formDescription, setFormDescription] = useState("");
	const [formError, setFormError] = useState<string | null>(null);
	const [deleteConfirmId, setDeleteConfirmId] = useState<string | null>(null);
	const [expandedProject, setExpandedProject] = useState<string | null>(null);
	const [creatingWorkspace, setCreatingWorkspace] = useState<{
		projectId: string;
		repoId: string;
	} | null>(null);
	const [workspaceLoading, setWorkspaceLoading] = useState<string | null>(null);

	const safeProjects = projects ?? [];

	const openCreate = () => {
		setFormName("");
		setFormDescription("");
		setFormError(null);
		setEditingProject(null);
		setDialogMode("create");
	};

	const openEdit = (project: ProjectWithRepos) => {
		setFormName(project.name);
		setFormDescription(project.description ?? "");
		setFormError(null);
		setEditingProject(project);
		setDialogMode("edit");
	};

	const closeDialog = () => {
		setDialogMode("none");
		setEditingProject(null);
		setFormError(null);
	};

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

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

		try {
			if (dialogMode === "create") {
				const input: ProjectCreateInput = {
					name: formName.trim(),
					description: formDescription.trim() || null,
				};
				await createProject(input);
			} else if (dialogMode === "edit" && editingProject) {
				const input: ProjectUpdateInput = {
					name: formName.trim(),
					description: formDescription.trim() || null,
				};
				await updateProject(editingProject.id, input);
			}
			closeDialog();
			reload();
		} catch {
			setFormError("Failed to save project");
		}
	};

	const handleDelete = async (projectId: string) => {
		try {
			await deleteProject(projectId);
			setDeleteConfirmId(null);
			reload();
		} catch {
			setDeleteConfirmId(null);
		}
	};

	const handleSyncWorkspace = async (
		projectId: string,
		repoId: string,
		workspace: WorkspaceSummary,
	) => {
		setWorkspaceLoading(workspace.id);
		try {
			await syncWorkspace(projectId, repoId, workspace.id);
			reload();
		} catch (err) {
			alert(err instanceof Error ? err.message : "Failed to sync workspace");
		} finally {
			setWorkspaceLoading(null);
		}
	};

	const handleDeleteWorkspace = async (workspace: WorkspaceSummary) => {
		if (!confirm(`Delete workspace "${workspace.name}"?`)) return;
		setWorkspaceLoading(workspace.id);
		try {
			await deleteWorkspace(workspace.id);
			reload();
		} catch (err) {
			alert(err instanceof Error ? err.message : "Failed to delete workspace");
		} finally {
			setWorkspaceLoading(null);
		}
	};

	return {
		projects: safeProjects,
		status,
		reload,
		dialogMode,
		formName,
		setFormName,
		formDescription,
		setFormDescription,
		formError,
		deleteConfirmId,
		setDeleteConfirmId,
		expandedProject,
		setExpandedProject,
		creatingWorkspace,
		setCreatingWorkspace,
		workspaceLoading,
		openCreate,
		openEdit,
		closeDialog,
		handleSubmit,
		handleDelete,
		handleSyncWorkspace,
		handleDeleteWorkspace,
	};
};
