import { create } from 'zustand';
import { devtools } from 'zustand/middleware';
import {
  IRHAbsence,
  TREATED_STATES,
  NON_TREATED_STATES,
  UserOption,
  DriverShort,
  CollaboratorShort,
} from '@/shared/types/absence-rh';
import {
  absenceEndpoints,
  AbsenceFilters,
  CreateAbsenceDto,
} from '@/shared/api/endpoints/hr/absence/absence';
import { Pageable } from '@/shared/types/client';

interface BackendPage<T> {
  content: T[];
  pageable: {
    sort: {
      empty: boolean;
      unsorted: boolean;
      sorted: boolean;
    };
    offset: number;
    pageNumber: number;
    pageSize: number;
    paged: boolean;
    unpaged: boolean;
  };
  last: boolean;
  totalElements: number;
  totalPages: number;
  first: boolean;
  size: number;
  number: number;
  sort: {
    empty: boolean;
    unsorted: boolean;
    sorted: boolean;
  };
  numberOfElements: number;
  empty: boolean;
}

interface RHAbsenceState {
  // State
  loading: boolean;
  error: string | null;
  absences: {
    traited: Pageable<IRHAbsence>;
    nonTraited: Pageable<IRHAbsence>;
  };
  selectedAbsence: IRHAbsence | null;
  filters: AbsenceFilters;

  // User data state
  allUsers: UserOption[];
  drivers: DriverShort[];
  collaborators: CollaboratorShort[];
  usersLoading: boolean;
  usersError: string | null;

  // Export state
  exportLoading: boolean;
  exportError: string | null;

  // Actions
  setLoading: (loading: boolean) => void;
  setError: (error: string | null) => void;
  setFilters: (filters: Partial<AbsenceFilters>) => void;
  resetFilters: () => void;
  setSelectedAbsence: (absence: IRHAbsence | null) => void;

  // User management actions
  setUsersLoading: (loading: boolean) => void;
  setUsersError: (error: string | null) => void;
  fetchAllUsers: () => Promise<void>;
  fetchDrivers: () => Promise<DriverShort[]>;
  fetchCollaborators: () => Promise<CollaboratorShort[]>;
  getUserById: (id: string) => UserOption | undefined;
  getUsersByType: (type: 'CHAUFFEUR' | 'SEDENTAIRE') => UserOption[];
  getCollaboratorsForAuthorization: () => UserOption[];

  // API Actions
  fetchTraitedAbsences: (filters?: AbsenceFilters) => Promise<void>;
  fetchNonTraitedAbsences: (filters?: AbsenceFilters) => Promise<void>;
  createAbsence: (absence: CreateAbsenceDto, file?: File | null) => Promise<void>;
  updateAbsence: (id: number, absence: CreateAbsenceDto) => Promise<void>;
  getAbsenceById: (id: number) => Promise<IRHAbsence>;
  updateAbsenceStatus: (id: number | string, status: string, comment?: string) => Promise<void>;

  // Export actions
  setExportLoading: (loading: boolean) => void;
  setExportError: (error: string | null) => void;
  startExport: (
    filters?: Partial<AbsenceFilters>
  ) => Promise<{ success: boolean; message: string; exportPath?: string }>;
  downloadExport: (filePath: string) => Promise<{ success: boolean; message: string }>;
}

const INITIAL_FILTERS: AbsenceFilters = {
  page: 0,
  size: 20,
};

const EMPTY_PAGE: Pageable<IRHAbsence> = {
  content: [],
  totalElements: 0,
  totalPages: 0,
  size: 20,
  number: 0,
  first: true,
  last: true,
  empty: true,
  sort: {
    empty: true,
    sorted: false,
    unsorted: true,
  },
  offset: 0,
  pageNumber: 0,
  pageSize: 20,
  paged: true,
  unpaged: false,
  numberOfElements: 0,
};

export const useRHAbsenceStore = create<RHAbsenceState>()(
  devtools(
    (set, get) => ({
      // Initial state
      loading: false,
      error: null,
      absences: {
        traited: EMPTY_PAGE,
        nonTraited: EMPTY_PAGE,
      },
      selectedAbsence: null,
      filters: INITIAL_FILTERS,

      // User data initial state
      allUsers: [],
      drivers: [],
      collaborators: [],
      usersLoading: false,
      usersError: null,

      // Export initial state
      exportLoading: false,
      exportError: null,

      // State actions
      setLoading: (loading: boolean) => set({ loading }),
      setError: (error: string | null) => set({ error }),
      setFilters: (filters: Partial<AbsenceFilters>) =>
        set((state) => ({ filters: { ...state.filters, ...filters } })),
      resetFilters: () => set({ filters: INITIAL_FILTERS }),
      setSelectedAbsence: (absence: IRHAbsence | null) => set({ selectedAbsence: absence }),

      // User management actions
      setUsersLoading: (loading: boolean) => set({ usersLoading: loading }),
      setUsersError: (error: string | null) => set({ usersError: error }),

      fetchDrivers: async (): Promise<DriverShort[]> => {
        try {
          const response = await absenceEndpoints.getAllDrivers();
          return response.data || [];
        } catch (error) {
          console.error('Error fetching drivers:', error);
          return [];
        }
      },

      fetchCollaborators: async (): Promise<CollaboratorShort[]> => {
        try {
          const response = await absenceEndpoints.getAllCollaborators();
          return response.data || [];
        } catch (error) {
          console.error('Error fetching collaborators:', error);
          return [];
        }
      },

      fetchAllUsers: async () => {
        set({ usersLoading: true, usersError: null });
        try {
          const [driversData, collaboratorsData] = await Promise.all([
            get().fetchDrivers(),
            get().fetchCollaborators(),
          ]);

          // Combine and format data for dropdown
          const combinedUsers: UserOption[] = [
            ...driversData.map((driver: DriverShort) => ({
              id: driver.id,
              label: `${driver.firstName} ${driver.lastName}`,
              firstName: driver.firstName,
              lastName: driver.lastName,
              email: driver.email,
              phoneNumber: driver.phoneNumber,
              departmentName: driver.departmentName,
              type: 'CHAUFFEUR' as const,
            })),
            ...collaboratorsData.map((collaborator: CollaboratorShort) => ({
              id: collaborator.id,
              label: `${collaborator.firstName} ${collaborator.lastName}`,
              firstName: collaborator.firstName,
              lastName: collaborator.lastName,
              email: collaborator.email,
              phoneNumber: collaborator.phoneNumber,
              departmentName: collaborator.departmentName,
              type: 'SEDENTAIRE' as const,
            })),
          ];

          set({
            drivers: driversData,
            collaborators: collaboratorsData,
            allUsers: combinedUsers,
            usersLoading: false,
          });
        } catch (error: any) {
          set({
            usersError: error.message || 'Error fetching users',
            usersLoading: false,
          });
        }
      },

      getUserById: (id: string): UserOption | undefined => {
        return get().allUsers.find((user) => user.id === id);
      },

      getUsersByType: (type: 'CHAUFFEUR' | 'SEDENTAIRE'): UserOption[] => {
        return get().allUsers.filter((user) => user.type === type);
      },

      getCollaboratorsForAuthorization: (): UserOption[] => {
        return get().getUsersByType('SEDENTAIRE');
      },

      // API actions
      fetchTraitedAbsences: async (filters?: AbsenceFilters) => {
        set({ loading: true, error: null });
        try {
          const currentFilters = { ...get().filters, ...filters };

          // Ensure we use states instead of state
          if (currentFilters.state && !currentFilters.states) {
            currentFilters.states = currentFilters.state;
            delete currentFilters.state;
          }

          // Update store filters state
          if (filters) {
            set((state) => ({ filters: { ...state.filters, ...filters } }));
          }

          const response = await absenceEndpoints.getTraitedAbsences(currentFilters);

          set((state) => ({
            absences: {
              ...state.absences,
              traited: response.data,
            },
            loading: false,
          }));
        } catch (error: any) {
          set({
            error: error.message || 'Failed to fetch treated absences',
            loading: false,
          });
          throw error;
        }
      },

      fetchNonTraitedAbsences: async (filters?: AbsenceFilters) => {
        set({ loading: true, error: null });
        try {
          const currentFilters = { ...get().filters, ...filters };

          // Ensure we use states instead of state
          if (currentFilters.state && !currentFilters.states) {
            currentFilters.states = currentFilters.state;
            delete currentFilters.state;
          }

          // Update store filters state
          if (filters) {
            set((state) => ({ filters: { ...state.filters, ...filters } }));
          }

          const response = await absenceEndpoints.getNonTraitedAbsences(currentFilters);

          set((state) => ({
            absences: {
              ...state.absences,
              nonTraited: response.data,
            },
            loading: false,
          }));
        } catch (error: any) {
          set({
            error: error.message || 'Failed to fetch non-treated absences',
            loading: false,
          });
          throw error;
        }
      },

      createAbsence: async (absence: CreateAbsenceDto, file?: File | null) => {
        set({ loading: true, error: null });
        try {
          await absenceEndpoints.createAbsence(absence, file);
          // Refresh both lists after creation
          await get().fetchNonTraitedAbsences();
          await get().fetchTraitedAbsences();
          set({ loading: false });
        } catch (error: any) {
          console.error('Store: Create absence error:', error);
          set({
            error: error.message || 'Failed to create absence',
            loading: false,
          });
          throw error;
        }
      },

      updateAbsence: async (id: number, absence: CreateAbsenceDto) => {
        set({ loading: true, error: null });
        try {
          await absenceEndpoints.updateAbsence(id, absence);
          // Refresh both lists after update
          await get().fetchNonTraitedAbsences();
          await get().fetchTraitedAbsences();
          set({ loading: false });
        } catch (error: any) {
          console.error('Store: Update absence error:', error);
          set({
            error: error.message || 'Failed to update absence',
            loading: false,
          });
          throw error;
        }
      },

      getAbsenceById: async (id: number) => {
        set({ loading: true, error: null });
        try {
          const response = await absenceEndpoints.getAbsenceById(id);

          set({ selectedAbsence: response.data, loading: false });
          return response.data;
        } catch (error: any) {
          set({
            error: error.message || 'Failed to fetch absence details',
            loading: false,
          });
          throw error;
        }
      },

      updateAbsenceStatus: async (id: number | string, status: string, comment?: string) => {
        set({ loading: true, error: null });
        try {
          await absenceEndpoints.updateAbsenceStatus(id, status, comment);
          // Refresh both lists after status update
          await get().fetchNonTraitedAbsences();
          await get().fetchTraitedAbsences();
          set({ loading: false });
        } catch (error: any) {
          console.error('Store: Update absence status error:', error);
          set({
            error: error.message || 'Failed to update absence status',
            loading: false,
          });
          throw error;
        }
      },

      // Export actions
      setExportLoading: (loading: boolean) => set({ exportLoading: loading }),
      setExportError: (error: string | null) => set({ exportError: error }),

      startExport: async (filters?: Partial<AbsenceFilters>) => {
        set({ exportLoading: true, exportError: null });
        try {
          // Combine current filters with provided filters
          const currentFilters = get().filters;
          const exportFilters = { ...currentFilters, ...filters };

          const response = await absenceEndpoints.startExport(exportFilters);

          set({ exportLoading: false });
          return {
            success: true,
            message: 'Export des absences démarré avec succès',
            exportPath: response.data.exportPath,
          };
        } catch (error: any) {
          console.error('Store: Export start error:', error);
          const errorMessage =
            error.response?.data?.message || error.message || "Échec du démarrage de l'export";
          set({
            exportError: errorMessage,
            exportLoading: false,
          });
          return {
            success: false,
            message: errorMessage,
          };
        }
      },

      downloadExport: async (filePath: string) => {
        set({ exportLoading: true, exportError: null });
        try {
          const response = await absenceEndpoints.downloadExport(filePath);

          // Create download link
          const blob = new Blob([response.data], {
            type: response.headers['content-type'] || 'application/octet-stream',
          });
          const url = window.URL.createObjectURL(blob);
          const link = document.createElement('a');
          link.href = url;

          // Extract filename from filePath or use default
          const fileName =
            filePath.substring(filePath.lastIndexOf('/') + 1) || 'export_absences.xlsx';
          link.setAttribute('download', fileName);

          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
          window.URL.revokeObjectURL(url);

          set({ exportLoading: false });

          return {
            success: true,
            message: 'Fichier téléchargé avec succès',
          };
        } catch (error: any) {
          const errorMessage =
            error.response?.data?.message || error.message || 'Échec du téléchargement';
          set({
            exportError: errorMessage,
            exportLoading: false,
          });
          return {
            success: false,
            message: errorMessage,
          };
        }
      },
    }),
    {
      name: 'rh-absence-store',
    }
  )
);

// Initialize users data when store is imported
const initializeUsers = () => {
  const store = useRHAbsenceStore.getState();
  if (store.allUsers.length === 0 && !store.usersLoading) {
    store.fetchAllUsers();
  }
};

// Call initialization when store is created
setTimeout(initializeUsers, 0);
