import { useState, useEffect, useCallback, useMemo } from "react";
import { useDebounce } from "../useDebounce";
import useEmployeeTechnologyService from "./useEmployeeTechnologyService";
import {
  type Technology,
  type TechnologyFilters,
  type CreateTechnologyData,
  type UpdateTechnologyData,
  type AssignEmployeesData,
} from "../../services/employeeTechnologyService";

interface UseEmployeeTechnologyState {
  technologies: Technology[];
  total: number;
  currentPage: number;
  totalPages: number;
  itemsPerPage: number;
  searchTerm: string;
  employeeFilter: number | undefined;
  loading: boolean;
  error: string | null;
}

const INITIAL_STATE: UseEmployeeTechnologyState = {
  technologies: [],
  total: 0,
  currentPage: 1,
  totalPages: 0,
  itemsPerPage: 10,
  searchTerm: "",
  employeeFilter: undefined,
  loading: false,
  error: null,
};

function useEmployeeTechnology() {
  const [state, setState] = useState<UseEmployeeTechnologyState>(INITIAL_STATE);
  const service = useEmployeeTechnologyService();

  const debouncedSearchTerm = useDebounce(state.searchTerm, 500);

  const filters = useMemo<TechnologyFilters>(() => {
    const result: TechnologyFilters = {
      search: debouncedSearchTerm,
      page: state.currentPage,
      limit: state.itemsPerPage,
    };

    if (state.employeeFilter !== undefined || state.employeeFilter !== null) {
      result.employee_id = state.employeeFilter;
    }

    return result;
  }, [
    debouncedSearchTerm,
    state.currentPage,
    state.itemsPerPage,
    state.employeeFilter,
  ]);

  useEffect(() => {
    const fetchTechnologies = async () => {
      setState((prev) => ({ ...prev, loading: true, error: null }));

      const result = await service.getTechnologies(filters);

      if (result.success && result.data) {
        const total = result.data.data?.count ?? 0;
        const limit = filters.limit ?? 10;

        setState((prev) => ({
          ...prev,
          technologies: result.data!.data?.data ?? [],
          total,
          totalPages: Math.ceil(total / limit),
          loading: false,
          error: null,
        }));
      } else {
        setState((prev) => ({
          ...prev,
          technologies: [],
          total: 0,
          totalPages: 0,
          loading: false,
          error: result.message,
        }));
      }
    };

    fetchTechnologies();
  }, [filters]);

  const setSearchTerm = useCallback((term: string) => {
    setState((prev) => ({ ...prev, searchTerm: term, currentPage: 1 }));
  }, []);

  const setEmployeeFilter = useCallback((employeeId: number | undefined) => {
    setState((prev) => ({
      ...prev,
      employeeFilter: employeeId,
      currentPage: 1,
    }));
  }, []);

  const setCurrentPage = useCallback((page: number) => {
    setState((prev) => ({ ...prev, currentPage: page }));
  }, []);

  const setItemsPerPage = useCallback((items: number) => {
    setState((prev) => ({ ...prev, itemsPerPage: items, currentPage: 1 }));
  }, []);

  const clearFilters = useCallback(() => {
    setState((prev) => ({
      ...prev,
      searchTerm: "",
      employeeFilter: undefined,
      currentPage: 1,
    }));
  }, []);

  const refreshData = useCallback(async () => {
    setState((prev) => ({ ...prev, loading: true, error: null }));

    const result = await service.getTechnologies(filters);

    if (result.success && result.data) {
      const total = result.data.data?.count ?? 0;
      const limit = filters.limit ?? 10;

      setState((prev) => ({
        ...prev,
        technologies: result.data!.data?.data ?? [],
        total,
        totalPages: Math.ceil(total / limit),
        loading: false,
        error: null,
      }));
    } else {
      setState((prev) => ({
        ...prev,
        technologies: [],
        total: 0,
        totalPages: 0,
        loading: false,
        error: result.message,
      }));
    }
  }, [service, filters]);

  const createTechnology = useCallback(
    async (data: CreateTechnologyData): Promise<boolean> => {
      const result = await service.createTechnology(data);
      if (result.success) {
        await refreshData();
      }
      return result.success;
    },
    [service, refreshData],
  );

  const updateTechnology = useCallback(
    async (data: UpdateTechnologyData): Promise<boolean> => {
      const result = await service.updateTechnology(data);
      if (result.success) {
        await refreshData();
      }
      return result.success;
    },
    [service, refreshData],
  );

  const assignEmployees = useCallback(
    async (data: AssignEmployeesData): Promise<boolean> => {
      const result = await service.assignEmployees(data);
      if (result.success) {
        await refreshData();
      }
      return result.success;
    },
    [service, refreshData],
  );

  return {
    ...state,
    loading: state.loading || service.loading,
    setSearchTerm,
    setEmployeeFilter,
    setCurrentPage,
    setItemsPerPage,
    clearFilters,
    refreshData,
    createTechnology,
    updateTechnology,
    assignEmployees,
  };
}

export default useEmployeeTechnology;
