"use client";

import { useEffect, useMemo, useState } from "react";
import { getDefaultProjectState, type ProjectState, type ProjectStateSource } from "@/lib/project-state";

type Project = ProjectStateSource & {
  id: string;
};

export function useProjectStates(projects: Project[]) {
  const projectIds = useMemo(() => projects.map((project) => project.id), [projects]);
  const [savedStates, setSavedStates] = useState<Record<string, ProjectState>>({});

  useEffect(() => {
    let isActive = true;

    async function loadStates() {
      if (projectIds.length === 0) {
        return;
      }

      try {
        const response = await fetch(`/api/project-states?projectIds=${encodeURIComponent(projectIds.join(","))}`);

        if (!response.ok) {
          return;
        }

        const data = (await response.json()) as { statesByProject?: Record<string, ProjectState> };

        if (isActive && data.statesByProject) {
          setSavedStates(data.statesByProject);
        }
      } catch {
        // Project states keep their date-based defaults if the local database is temporarily unavailable.
      }
    }

    void loadStates();

    return () => {
      isActive = false;
    };
  }, [projectIds]);

  const statesByProject = useMemo(
    () =>
      Object.fromEntries(
        projects.map((project) => [project.id, savedStates[project.id] ?? getDefaultProjectState(project)])
      ) as Record<string, ProjectState>,
    [projects, savedStates]
  );

  function setProjectState(projectId: string, state: ProjectState) {
    setSavedStates((current) => ({ ...current, [projectId]: state }));
    void saveProjectState(projectId, state);
  }

  return { statesByProject, setProjectState };
}

async function saveProjectState(projectId: string, state: ProjectState) {
  try {
    await fetch("/api/project-states", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ projectId, state })
    });
  } catch {
    // The UI updates immediately; persistence will work again once the local database is reachable.
  }
}
