import { useState, useEffect, useCallback, useMemo } from "react";
import { useDebounce } from "../useDebounce";
import useEmployeeService from "./useEmployeeService";
import {
  type Employee,
  type EmployeeFilters,
  type CreateEmployeeData,
  type UpdateEmployeeData,
} from "../../services/employeeService";

interface UseEmployeeState {
  employees: Employee[];
  total: number;
  currentPage: number;
  totalPages: number;
  itemsPerPage: number;
  searchTerm: string;
  statusFilter: "all" | "active" | "inactive";
  departmentFilter: number | "all";
  roleFilter: number | "all";
  teamLeadFilter: string | "all";
  order: string;
  columnName: string | null;
  loading: boolean;
  error: string | null;
}

interface UseEmployeeActions {
  setSearchTerm: (term: string) => void;
  setStatusFilter: (filter: "all" | "active" | "inactive") => void;
  setDepartmentFilter: (filter: number | "all") => void;
  setRoleFilter: (filter: number | "all") => void;
  setTeamLeadFilter: (filter: string | "all") => void;
  setOrder: (order: string) => void;
  setColumnName: (columnName: string | null) => void;
  setCurrentPage: (page: number) => void;
  setItemsPerPage: (items: number) => void;
  clearFilters: () => void;
  refreshData: () => Promise<void>;
  createEmployee: (data: CreateEmployeeData) => Promise<boolean>;
  updateEmployee: (data: UpdateEmployeeData) => Promise<boolean>;
  deleteEmployee: (id: string) => Promise<boolean>;
  toggleEmployeeStatus: (id: string) => Promise<boolean>;
  getEmployeeById: (id: string) => Promise<Employee | null>;
}

const INITIAL_STATE: UseEmployeeState = {
  employees: [],
  total: 0,
  currentPage: 1,
  totalPages: 0,
  itemsPerPage: 100,
  searchTerm: "",
  statusFilter: "all",
  departmentFilter: "all",
  roleFilter: "all",
  teamLeadFilter: "all",
  order: "",
  columnName: null,
  loading: false,
  error: null,
};

function useEmployee() {
  const [state, setState] = useState<UseEmployeeState>(INITIAL_STATE);
  const service = useEmployeeService();

  // Debounce search term with 500ms delay
  const debouncedSearchTerm = useDebounce(state.searchTerm, 500);

  // Memoize filters to prevent unnecessary API calls
  const filters = useMemo<EmployeeFilters>(() => {
    let status: number | undefined = undefined;
    let department_id: number | undefined = undefined;
    let role_id: number | undefined = undefined;
    let team_lead_id: string | undefined = undefined;

    if (state.statusFilter === "active") status = 1;
    if (state.statusFilter === "inactive") status = 0;

    if (state.departmentFilter !== "all") {
      department_id = state.departmentFilter as number;
    }

    if (state.roleFilter !== "all") {
      role_id = state.roleFilter as number;
    }

    if (state.teamLeadFilter !== "all") {
      team_lead_id = state.teamLeadFilter as string;
    }

    const result: EmployeeFilters = {
      search: debouncedSearchTerm,
      status,
      department_id,
      role_id,
      team_lead_id,
      page: state.currentPage,
      limit: state.itemsPerPage,
    };

    if (state.order && state.columnName) {
      result.order = state.order.toLowerCase() as 'ASC' | 'DESC';
      result.column_name = state.columnName;
    }

    return result;
  }, [
    debouncedSearchTerm,
    state.statusFilter,
    state.departmentFilter,
    state.roleFilter,
    state.teamLeadFilter,
    state.currentPage,
    state.itemsPerPage,
    state.order,
    state.columnName,
  ]);

  // Auto-fetch when filters change
  useEffect(() => {
    const fetchEmployees = async () => {
      setState((prev) => ({ ...prev, loading: true, error: null }));

      const result = await service.getEmployees(filters);

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

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

    fetchEmployees();
  }, [filters]);

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

  const setStatusFilter = useCallback((filter: "all" | "active" | "inactive") => {
    setState((prev) => ({ ...prev, statusFilter: filter, currentPage: 1 }));
  }, []);

  const setDepartmentFilter = useCallback((filter: number | "all") => {
    setState((prev) => ({ ...prev, departmentFilter: filter, currentPage: 1 }));
  }, []);

  const setRoleFilter = useCallback((filter: number | "all") => {
    setState((prev) => ({ ...prev, roleFilter: filter, currentPage: 1 }));
  }, []);

  const setTeamLeadFilter = useCallback((filter: string | "all") => {
    setState((prev) => ({ ...prev, teamLeadFilter: filter, currentPage: 1 }));
  }, []);

  const setOrder = useCallback((order: string) => {
    setState((prev) => ({ ...prev, order }));
  }, []);

  const setColumnName = useCallback((columnName: string | null) => {
    setState((prev) => ({ ...prev, columnName }));
  }, []);

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

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

  // Clear only filter dropdowns; do not clear search
  const clearFilters = useCallback(() => {
    setState((prev) => ({
      ...prev,
      statusFilter: "all",
      departmentFilter: "all",
      roleFilter: "all",
      teamLeadFilter: "all",
      order: "",
      columnName: null,
      currentPage: 1,
    }));
  }, []);

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

    const result = await service.getEmployees(filters);

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

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

  // CRUD operations
  const createEmployee = useCallback(
    async (data: CreateEmployeeData | FormData): Promise<boolean> => {
      const result = await service.createEmployee(data);
      if (result.success) {
        await refreshData();
      }
      return result.success;
    },
    [service, refreshData]
  );

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

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

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

  const getEmployeeById = useCallback(
    async (id: string): Promise<Employee | null> => {
      const result = await service.getEmployeeById(id);
      return result.success && result.data ? result.data.data : null;
    },
    [service]
  );

  const actions: UseEmployeeActions = {
    setSearchTerm,
    setStatusFilter,
    setDepartmentFilter,
    setRoleFilter,
    setTeamLeadFilter,
    setOrder,
    setColumnName,
    setCurrentPage,
    setItemsPerPage,
    clearFilters,
    refreshData,
    createEmployee,
    updateEmployee,
    deleteEmployee,
    toggleEmployeeStatus,
    getEmployeeById,
  };

  return {
    ...state,
    loading: state.loading || service.loading,
    ...actions,
  };
}

export default useEmployee;
