import { useCallback } from "react";
import { useShallow } from "zustand/react/shallow";
import { useAppState } from "../store/appState";
import * as commands from "../lib/tauri-commands";
import type { ProjectPath } from "../lib/types";

export function useProjects() {
  const {
    projects,
    selectedProjectId,
    setProjects,
    setSelectedProject,
    updateProjectInList,
    removeProjectFromList,
  } = useAppState(
    useShallow(s => ({
      projects: s.projects,
      selectedProjectId: s.selectedProjectId,
      setProjects: s.setProjects,
      setSelectedProject: s.setSelectedProject,
      updateProjectInList: s.updateProjectInList,
      removeProjectFromList: s.removeProjectFromList,
    }))
  );

  const selectedProject = projects.find((p) => p.id === selectedProjectId) ?? null;

  const refresh = useCallback(async () => {
    const list = await commands.listProjects();
    setProjects(list);
  }, [setProjects]);

  const add = useCallback(
    async (name: string, paths: ProjectPath[]) => {
      const project = await commands.addProject(name, paths);
      // Refresh from backend to avoid stale closure issues
      const list = await commands.listProjects();
      setProjects(list);
      setSelectedProject(project.id);
      return project;
    },
    [setProjects, setSelectedProject],
  );

  const remove = useCallback(
    async (id: string) => {
      await commands.removeProject(id);
      removeProjectFromList(id);
    },
    [removeProjectFromList],
  );

  const setOptimisticStatus = useCallback(
    (id: string, status: "starting" | "stopping") => {
      const { projects } = useAppState.getState();
      const project = projects.find((p) => p.id === id);
      if (project) {
        updateProjectInList({ ...project, status });
      }
    },
    [updateProjectInList],
  );

  const start = useCallback(
    async (id: string) => {
      setOptimisticStatus(id, "starting");
      const updated = await commands.startProjectContainer(id);
      updateProjectInList(updated);
      return updated;
    },
    [updateProjectInList, setOptimisticStatus],
  );

  const stop = useCallback(
    async (id: string) => {
      setOptimisticStatus(id, "stopping");
      await commands.stopProjectContainer(id);
      const list = await commands.listProjects();
      setProjects(list);
    },
    [setProjects, setOptimisticStatus],
  );

  const rebuild = useCallback(
    async (id: string) => {
      setOptimisticStatus(id, "starting");
      const updated = await commands.rebuildProjectContainer(id);
      updateProjectInList(updated);
      return updated;
    },
    [updateProjectInList, setOptimisticStatus],
  );

  const update = useCallback(
    async (project: Parameters<typeof commands.updateProject>[0]) => {
      const updated = await commands.updateProject(project);
      updateProjectInList(updated);
      return updated;
    },
    [updateProjectInList],
  );

  return {
    projects,
    selectedProject,
    selectedProjectId,
    setSelectedProject,
    refresh,
    add,
    remove,
    start,
    stop,
    rebuild,
    update,
  };
}
