import { create } from 'zustand';
import { devtools } from 'zustand/middleware';
import type {
  IEmployee,
  EmployeeFilters,
  PageResponse,
  EmployeeSearchParams,
} from '@/shared/types/employee';
import { employeesApi } from '@/shared/api/endpoints/hr/employees';

interface EmployeesState {
  // Data
  employees: IEmployee[];
  currentEmployee: IEmployee | null;
  totalEmployees: number;
  totalPages: number;

  // Loading states
  loading: boolean;
  creating: boolean;
  updating: boolean;
  deleting: boolean;
  copying: boolean;

  // Error states
  error: string | null;

  // Search and filters
  filters: EmployeeFilters;
  searchTerm: string;
  page: number;
  size: number;
  sortBy: string;
  sortDirection: 'asc' | 'desc';

  // Actions
  setLoading: (loading: boolean) => void;
  setError: (error: string | null) => void;
  setFilters: (filters: Partial<EmployeeFilters>) => void;
  setSearchTerm: (searchTerm: string) => void;
  setPagination: (page: number, size: number) => void;
  setSorting: (sortBy: string, sortDirection: 'asc' | 'desc') => void;

  // API Actions
  fetchEmployees: () => Promise<void>;
  fetchEmployeeById: (id: string) => Promise<IEmployee | null>;
  createEmployee: (employeeData: any) => Promise<IEmployee | null>;
  updateEmployee: (id: string, employeeData: any) => Promise<IEmployee | null>;
  deleteEmployee: (id: string) => Promise<boolean>;
  changeEmployeeStatus: (id: string, status: string) => Promise<IEmployee>;
  copyEmployee: (id: string) => Promise<IEmployee | null>;

  // Utility actions
  resetFilters: () => void;
  clearCurrentEmployee: () => void;
}

const initialFilters: EmployeeFilters = {
  lastName: '',
  firstName: '',
  email: '',
  phone: '',
  employeeNumber: '',
  department: '',
  status: undefined,
  type: undefined,
  registrationDateFrom: '',
  registrationDateTo: '',
  searchTerm: '',
};

export const useEmployeesStore = create<EmployeesState>()(
  devtools(
    (set, get) => ({
      // Initial state
      employees: [],
      currentEmployee: null,
      totalEmployees: 0,
      totalPages: 0,

      // Loading states
      loading: false,
      creating: false,
      updating: false,
      deleting: false,
      copying: false,

      // Error state
      error: null,

      // Search and filters
      filters: initialFilters,
      searchTerm: '',
      page: 0,
      size: 10,
      sortBy: 'id',
      sortDirection: 'asc',

      // Basic setters
      setLoading: (loading) => set({ loading }),
      setError: (error) => set({ error }),

      setFilters: (newFilters) =>
        set((state) => ({
          filters: { ...state.filters, ...newFilters },
          page: 0, // Reset to first page when filters change
        })),

      setSearchTerm: (searchTerm) =>
        set(() => ({
          searchTerm,
          page: 0, // Reset to first page when search term changes
        })),

      setPagination: (page, size) => set({ page, size }),

      setSorting: (sortBy, sortDirection) => set({ sortBy, sortDirection }),

      // API Actions
      fetchEmployees: async () => {
        const state = get();
        set({ loading: true, error: null });

        try {
          const params: EmployeeSearchParams = {
            ...state.filters,
            searchTerm: state.searchTerm,
            page: state.page,
            size: state.size,
            sortBy: state.sortBy,
            sortDirection: state.sortDirection,
          };

          const response = await employeesApi.getAllEmployees(params);
          const data: PageResponse<IEmployee> = response.data;

          set({
            employees: data.content,
            totalEmployees: data.totalElements,
            totalPages: data.totalPages,
            loading: false,
          });
        } catch (error: any) {
          console.error('Error fetching employees:', error);
          set({
            error: error.message || 'Failed to fetch employees',
            loading: false,
          });
        }
      },

      fetchEmployeeById: async (id: string) => {
        set({ loading: true, error: null });

        try {
          const response = await employeesApi.getEmployeeById(id);
          const employee: IEmployee = response.data;

          set({
            currentEmployee: employee,
            loading: false,
          });

          return employee;
        } catch (error: any) {
          console.error('Error fetching employee:', error);
          set({
            error: error.message || 'Failed to fetch employee',
            loading: false,
          });
          return null;
        }
      },

      createEmployee: async (employeeData: any) => {
        set({ creating: true, error: null });

        try {
          const response = await employeesApi.createEmployee(employeeData);
          const newEmployee: IEmployee = response.data;

          set((state) => ({
            employees: [newEmployee, ...state.employees],
            totalEmployees: state.totalEmployees + 1,
            creating: false,
          }));

          // Refresh the list to get updated pagination
          get().fetchEmployees();

          return newEmployee;
        } catch (error: any) {
          console.error('Error creating employee:', error);
          set({
            error: error.message || 'Failed to create employee',
            creating: false,
          });
          throw error; // Lancer l'erreur au lieu de retourner null
        }
      },

      updateEmployee: async (id: string, employeeData: any) => {
        set({ updating: true, error: null });

        try {
          const response = await employeesApi.updateEmployee(id, employeeData);

          const updatedEmployee: IEmployee = response.data;

          set((state) => ({
            employees: state.employees.map((emp) => (emp.id === id ? updatedEmployee : emp)),
            currentEmployee:
              state.currentEmployee?.id === id ? updatedEmployee : state.currentEmployee,
            updating: false,
          }));

          return updatedEmployee;
        } catch (error: any) {
          console.error('Error updating employee:', error);
          set({
            error: error.message || 'Failed to update employee',
            updating: false,
          });
          throw error; // Lancer l'erreur au lieu de retourner null
        }
      },

      deleteEmployee: async (id: string) => {
        set({ deleting: true, error: null });

        try {
          await employeesApi.deleteEmployee(id);

          set((state) => ({
            employees: state.employees.filter((emp) => emp.id !== id),
            totalEmployees: state.totalEmployees - 1,
            currentEmployee: state.currentEmployee?.id === id ? null : state.currentEmployee,
            deleting: false,
          }));

          // Refresh the list to get updated pagination
          get().fetchEmployees();

          return true;
        } catch (error: any) {
          console.error('Error deleting employee:', error);
          set({
            error: error.message || 'Failed to delete employee',
            deleting: false,
          });
          return false;
        }
      },

      changeEmployeeStatus: async (id: string, status: string) => {
        set({ loading: true, error: null });

        try {
          const response = await employeesApi.changeEmployeeStatus(id, status);
          const updatedEmployee = response.data;

          set((state) => ({
            employees: state.employees.map((emp) =>
              emp.id === id ? { ...emp, status: updatedEmployee.status } : emp
            ),
            // Update current employee if it's the same one
            currentEmployee:
              state.currentEmployee?.id === id
                ? { ...state.currentEmployee, status: updatedEmployee.status }
                : state.currentEmployee,
            loading: false,
          }));

          return updatedEmployee;
        } catch (error: any) {
          console.error('❌ Error changing employee status:', error);
          set({
            error: error.message || 'Failed to change employee status',
            loading: false,
          });
          throw error;
        }
      },

      copyEmployee: async (id: string) => {
        set({ copying: true, error: null });

        try {
          const response = await employeesApi.copyEmployee(id);
          const copiedEmployee: IEmployee = response.data;

          set((state) => ({
            employees: [copiedEmployee, ...state.employees],
            totalEmployees: state.totalEmployees + 1,
            copying: false,
          }));

          get().fetchEmployees();

          return copiedEmployee;
        } catch (error: any) {
          console.error('❌ Error copying employee:', error);
          set({
            error: error.message || 'Failed to copy employee',
            copying: false,
          });
          throw error;
        }
      },

      // Utility actions
      resetFilters: () =>
        set({
          filters: initialFilters,
          searchTerm: '',
          page: 0,
        }),

      clearCurrentEmployee: () => set({ currentEmployee: null }),
    }),
    {
      name: 'employees-store',
    }
  )
);
