import { useCallback, useEffect, useState } from "react";
import { cacheData, getCachedData } from "../slices/apiDataManager";
import ProjectRepository from "../repositories/ProjectRepository";
import { useProfile } from "./useProfile";
import { useDispatch, useSelector } from "react-redux";
import { setProjectId } from "../slices/localVariablesSlice";
import EmployeeList from "../components/Directory/EmployeeList";
import eventBus from "../services/eventBus";

export const useProjects = () => {
  const loggedUser = useSelector((store) => store.globalVariables.loginUser);
  const [projects, setProjects] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  const fetchData = async () => {
    const projectIds = loggedUser?.projects || [];

    const filterProjects = (projectsList) => {
      return projectsList
        .filter((proj) => projectIds.includes(String(proj.id)))
        .sort((a, b) => a?.name?.localeCompare(b.name));
    };

    const projects_cache = getCachedData("projectslist");

    if (!projects_cache) {
      setLoading(true);
      try {
        const response = await ProjectRepository.getProjectList();
        const allProjects = response.data;
        const filtered = filterProjects(allProjects);
        setProjects(filtered);
        cacheData("projectslist", allProjects);
      } catch (err) {
        setError("Failed to fetch data.");
      } finally {
        setLoading(false);
      }
    } else {
      if (!projects.length) {
        const filtered = filterProjects(projects_cache);
        setProjects(filtered);
        setLoading(false);
      }
    }
  };
  useEffect(() => {
    if (loggedUser) {
      fetchData();
    }
  }, [loggedUser]);

  return { projects, loading, error, refetch: fetchData };
};

export const useEmployeesByProjectAllocated = (selectedProject) => {
  const [projectEmployees, setEmployeeList] = useState([]);
  const [loading, setLoading] = useState(true);
  const [projects, setProjects] = useState([]);

  const fetchData = async (projectid) => {
    try {
      let EmployeeByProject_Cache = getCachedData("empListByProjectAllocated");
      if (
        !EmployeeByProject_Cache ||
        !EmployeeByProject_Cache.projectId === projectid
      ) {
        let response = await ProjectRepository.getProjectAllocation(projectid);
        setEmployeeList(response.data);
        cacheData("empListByProjectAllocated", {
          data: response.data,
          projectId: projectid,
        });
        setLoading(false);
      } else {
        setEmployeeList(EmployeeByProject_Cache.data);
        setLoading(false);
      }
    } catch (err) {
      setError("Failed to fetch data.");
      setLoading(false);
    }
  };

  useEffect(() => {
    if (selectedProject) {
      fetchData(selectedProject);
    }
  }, [selectedProject]);

  return { projectEmployees, loading, projects };
};

export const useProjectDetails = (projectId) => {
  const { profile } = useProfile();
  const [projects_Details, setProject_Details] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  const fetchData = async () => {
    setLoading(true);

    const project_cache = getCachedData("projectInfo");
    if (!project_cache || project_cache?.projectId != projectId) {
      ProjectRepository.getProjectByprojectId(projectId)
        .then((response) => {
          setProject_Details(response.data);
          cacheData("projectInfo", {
            projectId: projectId,
            data: response.data,
          });
          setLoading(false);
        })
        .catch((error) => {
          console.error(error);
          setError("Failed to fetch data.");
          setLoading(false);
        });
    } else {
      setProject_Details(project_cache.data);
      setLoading(false);
    }
  };

  useEffect(() => {
    if (profile && projectId != undefined) {
      fetchData();
    }
  }, [projectId, profile]);

  return { projects_Details, loading, error, refetch: fetchData };
};

export const useProjectsByEmployee = (employeeId) => {
  const [projectList, setProjectList] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");

  const fetchProjects = async (id) => {
    try {
      setLoading(true);
      setError(""); // clear previous error
      const res = await ProjectRepository.getProjectsByEmployee(id);
      setProjectList(res.data);
      cacheData("ProjectsByEmployee", { data: res.data, employeeId: id });
      setLoading(false);
    } catch (err) {
      setError(err?.message || "Failed to fetch projects");
      setLoading(false);
    }
  };

  useEffect(() => {
    if (!employeeId) return;

    const cache_project = getCachedData("ProjectsByEmployee");

    if (!cache_project?.data || cache_project?.employeeId !== employeeId) {
      fetchProjects(employeeId);
    } else {
      setProjectList(cache_project.data);
    }
  }, [employeeId]);

  return {
    projectList,
    loading,
    error,
    refetch: fetchProjects,
  };
};

export const useProjectName = () => {
  const [loading, setLoading] = useState(true);
  const [projectNames, setProjectName] = useState([]);
  const [Error, setError] = useState();
  const dispatch = useDispatch();

  const fetchData = async () => {
    try {
      let response = await ProjectRepository.projectNameList();
      setProjectName(response.data);
      cacheData("basicProjectNameList", response.data);
      setLoading(false);
      if(response.data.length === 1){
        dispatch(setProjectId(response.data[0]?.id));
      }
    } catch (err) {
      setError("Failed to fetch data.");
      setLoading(false);
    }
  };
  useEffect(() => {
    fetchData();
  }, []);

  return { projectNames, loading, Error, fetchData };
};
