import { create } from 'zustand';
import axiosInstance from '@/utils/axios';
import { ChangePasswordRequest, CollaboratorExportFilterRequest, CollaboratorStatus, IAgent, SendingEmailRequest, UpdatePasswordRequest, UserConfirmationRequestOtp, UserPasswordCreationRequest, UserStatus } from '@/shared/types/client';
import { OtpResponseDTO } from '@/shared/types/auth';
import { userEndpoints } from '../endpoints/user';
import { enqueueSnackbar } from 'notistack';

type SearchCollaboratorsParams = {
  firstName?: string;
  lastName?: string;
  email?: string;
  phoneNumber?: string;
  address?: string;
  status?: CollaboratorStatus;
  role?: string;
  page?: number;
  size?: number;
  sortBy?: string;
  sortDirection?: 'asc' | 'desc';
};

export interface ICollaboratorPageable {
  content: IAgent[];
  totalElements: number;
  totalPages: number;
  number: number;
  size: number;
}

type CollaboratorStore = {
  collaborator: IAgent | null;
  collaborators: ICollaboratorPageable | null;
  loading: boolean;
  error: string | null;

  addCollaborator: (data: IAgent) => Promise<void>;
  updateCollaborator: (data: IAgent) => Promise<void>;
  updateCollaboratorSkype: (id: string | number, skype: string) => Promise<IAgent | null>;
  updateCollaboratorContact: (id: string | number, type: string, value: string | null) => Promise<IAgent | null>;
  toggleActiveStatus: (id: number | string) => Promise<void>;
  searchCollaborators: (params?: SearchCollaboratorsParams) => Promise<void>;
  changeStatus: (id: string | number, status: CollaboratorStatus) => Promise<void>;
  exportCollaborators: (
    filters: CollaboratorExportFilterRequest
  ) => Promise<string | null>;
  downloadExportFile: (filePath: string) => Promise<Blob | null>;
  updateCollaboratorPassword: (data: UpdatePasswordRequest) => Promise<void>;
  changeCollaboratorPassword: (data: ChangePasswordRequest) => Promise<void>;
  sendResetPassword: (data: SendingEmailRequest) => Promise<any>;
  confirmOtp: (data: UserConfirmationRequestOtp) => Promise<boolean>;
  confirmUserPassword: (data: UserPasswordCreationRequest) => Promise<boolean>;
  getOtpByUsername: (username: string) => Promise<OtpResponseDTO | null>;
  getCollaboratorById: (id: string | number) => Promise<IAgent | null>;
  autocompleteCollaborator: (keyword?: string) => Promise<Array<{ id: number; firstName: string; lastName: string }>>;
  getCollaboratorsByDepartment: (departmentId: string | number) => Promise<Array<{ id: number; firstName: string; lastName: string }>>;
};

export const useCollaboratorStore = create<CollaboratorStore>((set) => ({
  collaborator: null,
  collaborators: null,
  loading: false,
  error: null,

  addCollaborator: async (data) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.post<IAgent>(
        userEndpoints.user.collaborator.add,
        data
      );
      const created = response.data;
      set((state) => ({
        collaborator: created,
        collaborators: state.collaborators
          ? {
            ...state.collaborators,
            content: [created, ...state.collaborators.content],
          }
          : null,
        loading: false,
        error: null,
      }));
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors de l’ajout', loading: false });
      throw error;
    }
  },

  updateCollaborator: async (data) => {
    set({ loading: true});
    try {
      const response = await axiosInstance.put<IAgent>(
        userEndpoints.user.collaborator.update,
        data
      );
      const updated = response.data;
      set((state) => ({
        collaborator: updated,
        collaborators: state.collaborators
          ? {
            ...state.collaborators,
            content: state.collaborators.content.map((c) => (c.id === updated.id ? updated : c)),
          }
          : null,
        loading: false,
        error: null,
      }));
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors de la mise à jour', loading: false });
      throw error;
    }
  },

  updateCollaboratorSkype: async (id, skype) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.put<IAgent>(
        userEndpoints.user.collaborator.updateSkype(id),
        { skype }
      );
      const updated = response.data;
      set((state) => ({
        collaborator: updated,
        collaborators: state.collaborators
          ? {
            ...state.collaborators,
            content: state.collaborators.content.map((c) => (c.id === updated.id ? updated : c)),
          }
          : null,
        loading: false,
        error: null,
      }));
      return updated;
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors de la mise à jour du Skype', loading: false });
      return null;
    }
  },

  updateCollaboratorContact: async (id, type, value) => {
    set({ loading: true, error: null });
    try {
      const url = `${userEndpoints.user.collaborator.updateContact(id)}?type=${encodeURIComponent(type)}${value !== undefined && value !== null ? `&value=${encodeURIComponent(value)}` : ''}`;
      const response = await axiosInstance.put<IAgent>(url);
      const updated = response.data;
      set((state) => ({
        collaborator: updated,
        collaborators: state.collaborators
          ? {
              ...state.collaborators,
              content: state.collaborators.content.map((c) => (c.id === updated.id ? updated : c)),
            }
          : null,
        loading: false,
        error: null,
      }));
      return updated;
    } catch (error: any) {
      set({ error: error.message || "Erreur lors de la mise à jour du contact", loading: false });
      return null;
    }
  },

  toggleActiveStatus: async (id) => {
    set({ loading: true, error: null });
    try {
      await axiosInstance.post(userEndpoints.user.collaborator.toggleActive(id));
      set((state) => ({
        collaborators: state.collaborators
          ? {
            ...state.collaborators,
            content: state.collaborators.content.map((col) =>
              col.id === id
                ? {
                  ...col,
                  userStatus:
                    col.userStatus === UserStatus.ACTIF ? UserStatus.INACTIF : UserStatus.ACTIF,
                }
                : col
            ),
          }
          : null,
        loading: false,
      }));
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors du changement de statut', loading: false });
    }
  },

  searchCollaborators: async (params = {}) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get<ICollaboratorPageable>(
        userEndpoints.user.collaborator.search,
        { params }
      );
      set({ collaborators: response.data,error: null, loading: false });
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors de la recherche', loading: false });
    }
  },
  changeStatus: async (id, status) => {
    set({ loading: true, error: null });
    try {
      await axiosInstance.get(userEndpoints.user.collaborator.changeStatus(id, status));
      set((state) => ({
        collaborators: state.collaborators
          ? {
            ...state.collaborators,
            content: state.collaborators.content.map((col) =>
              col.id === id ? { ...col, collaboratorStatus: status } : col
            ),
          }
          : null,
        loading: false,
      }));
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors du changement de statut', loading: false });
    }
  },

  exportCollaborators: async (params) => {
    set({ loading: true, error: null });
    try {
      const userId = localStorage.getItem('userId');
      if (userId) {
        const response = await axiosInstance.post(
          userEndpoints.user.collaborator.exportFiltered,
          null,
          { params: { ...params, userId } }
        );
        set({ loading: false });
        return response.data.ExportPath;
      }
      set({ loading: false, error: "Utilisateur non connecté" });
      return null;
    } catch (error: any) {
      set({ error: error.message || "Erreur lors de l’exportation", loading: false });
      return null;
    }
  },

  downloadExportFile: async (filePath) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get<Blob>(
        userEndpoints.user.collaborator.downloadExport(filePath),
        { responseType: 'blob' }
      );
      set({ loading: false });
      return response.data;
    } catch (error: any) {
      set({ error: error.message || "Erreur lors du téléchargement", loading: false });
      return null;
    }
  },

  updateCollaboratorPassword: async (data) => {
    set({ loading: true, error: null });
    try {
      await axiosInstance.put(userEndpoints.user.collaborator.updatePassword, data);
      set({ loading: false, error: null });
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors de la mise à jour du mot de passe', loading: false });
    }
  },

  changeCollaboratorPassword: async (data) => {
    set({ loading: true, error: null });
    try {
      await axiosInstance.put(userEndpoints.user.collaborator.changePassword, data);
      set({ loading: false, error: null });
      enqueueSnackbar("Mot de passe modifié avec succès", { variant: 'success' });

    } catch (error: any) {
      const backendMessage = error?.response?.data?.message || error.message;
      if (backendMessage?.toLowerCase().includes('bad credentials')) {
        set({ loading: false, error: "L'ancien mot de passe est incorrect" });
        enqueueSnackbar("L'ancien mot de passe est incorrect", { variant: 'error' });
      } else {
        set({ loading: false, error: backendMessage || 'Erreur lors du changement de mot de passe' });
        enqueueSnackbar(backendMessage || 'Erreur lors du changement de mot de passe', { variant: 'error' });
      }
      throw error;
    }
  },

  sendResetPassword: async (data) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.post(userEndpoints.user.collaborator.sendResetPassword, data);
      set({ loading: false, error: null });
      return response.data; 
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors de l\'envoi de l\'email de réinitialisation', loading: false });
      return null;
    }
  },

  confirmOtp: async (data) => {
    set({ loading: true, error: null });
    try {
      const isValid = await axiosInstance.post(userEndpoints.user.collaborator.confirmOtp, data);
      set({ loading: false, error: null });
      return isValid.data; 
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors de la confirmation de l\'OTP', loading: false });
      return false;
    }
  },

 
  confirmUserPassword: async (data) => {
    set({ loading: true, error: null });
    try {
      const passwordCreated = await axiosInstance.put(userEndpoints.user.collaborator.confirmPassword, data);
      set({ loading: false, error: null });
      return passwordCreated.data; 
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors de la confirmation du mot de passe', loading: false });
      return false;
    }
  },

  getOtpByUsername: async (username) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get<OtpResponseDTO>(
        userEndpoints.user.collaborator.getOtpByUsername(username)
      );
      set({ loading: false, error: null });
      return response.data;
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors de la récupération de l\'OTP', loading: false });
      return null;
    }
  },

  getCollaboratorById: async (id) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get<IAgent>(
        userEndpoints.user.collaborator.getCollaboratorById(id)
      );
      set({ loading: false, error: null });
      return response.data;
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors de la récupération du collaborateur', loading: false });
      return null;
    }
  },
  autocompleteCollaborator: async (keyword) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get<Array<{ id: number; firstName: string; lastName: string }>>(
        userEndpoints.user.collaborator.autocomplete,
        { params: { keyword } }
      );
      set({ loading: false, error: null });
      return response.data;
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors de l\'autocomplete', loading: false });
      return [];
    }
  },
  getCollaboratorsByDepartment: async (departmentId) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get<Array<{ id: number; firstName: string; lastName: string }>>(
        userEndpoints.user.collaborator.getByDepartment(departmentId)
      );
      set({ loading: false, error: null });
      return response.data;
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors de la récupération des collaborateurs par département', loading: false });
      return [];
    }
  },
}));
