import { create } from 'zustand';
import axiosInstance from '@/utils/axios';
import { Establishment, EstablishmentPageFilterParams, EstablishmentNameAndId, EstablishmentRequest } from '@/shared/types/establishment';
import { establishmentEndpoints } from '../../endpoints/admin-service/establishment';

type EstablishmentStore = {
  loading: boolean;
  error: string | null;
  establishments: Establishment[];
  establishmentNamesAndIds: EstablishmentNameAndId[];
  totalElements: number;
  lastUsedEstablishmentParams: EstablishmentPageFilterParams | null;
  fetchEstablishmentsPage: (params?: EstablishmentPageFilterParams) => Promise<void>;
  toogleActivation: (id: string, isActive: boolean) => Promise<void>;
  establishmentById: Establishment | null;
  getEstablishmentById: (id: string) => Promise<Establishment>;
  getAllEstablishmentNamesAndIds: () => Promise<void>;
  createEstablishment: (establishment: EstablishmentRequest) => Promise<void>;
  updateEstablishment: (id: string, establishment: EstablishmentRequest) => Promise<void>;
  startExportFiltredEstablishments: (params?: EstablishmentPageFilterParams) => Promise<void>;
};

export const useEstablishmentStore = create<EstablishmentStore>((set, get) => ({
  loading: false,
  error: null,
  establishments: [],
  establishmentNamesAndIds: [],
  totalElements: 0,
  lastUsedEstablishmentParams: null,
  fetchEstablishmentsPage: async (params) => {
    set({ loading: true, error: null });
    set({ lastUsedEstablishmentParams: params });
    try {
      const response = await axiosInstance.get(establishmentEndpoints.getEstablishmentsPage, {
        params,
      });

      const { content, totalElements } = response.data;
      set({
        establishments: content,
        totalElements,
        loading: false,
      });
    } catch (error: any) {
      set({
        error: error.message || 'Failed to fetch establishments',
        loading: false,
      });
    }
  },
  toogleActivation: async (id: string, active: boolean) => {
    set({ loading: true, error: null });
    try {
      await axiosInstance.post<boolean>(establishmentEndpoints.toggleActivation(id, active));
      const { lastUsedEstablishmentParams, fetchEstablishmentsPage } = get();
      if (lastUsedEstablishmentParams) {
        await fetchEstablishmentsPage(lastUsedEstablishmentParams);
      }
      set({ loading: false });
    } catch (error: any) {
      set({
        error: error.message || 'Failed to toggle activation',
        loading: false,
      });
    }
  },
  establishmentById: null,
  getEstablishmentById: async (id: string) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get(establishmentEndpoints.getEstablishmentById(id));
      set({
        establishmentById: response.data,
        loading: false,
      });
      return response.data;
    } catch (error: any) {
      set({
        error: error.message || 'Failed to get establishment by id',
        loading: false,
      });
    }
  },
  getAllEstablishmentNamesAndIds: async () => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get(establishmentEndpoints.getAllEstablishmentNamesAndIds);
      set({ establishmentNamesAndIds: response.data, loading: false });
    } catch (error: any) {
      set({
        error: error.message || 'Failed to get establishment names and ids',
        loading: false,
      });
      throw error;
    }
  },
  createEstablishment: async (establishment: EstablishmentRequest) => {
    set({ loading: true, error: null });
    try {
      await axiosInstance.post(establishmentEndpoints.createEstablishment, establishment);
      const { lastUsedEstablishmentParams, fetchEstablishmentsPage } = get();
      if (lastUsedEstablishmentParams) {
        await fetchEstablishmentsPage(lastUsedEstablishmentParams);
      }
      set({ loading: false });
    } catch (error: any) {
      set({ error: error.message || 'Failed to create establishment', loading: false });
    }
  },
  updateEstablishment: async (id: string, establishment: EstablishmentRequest) => {
    set({ loading: true, error: null });
    try {
      await axiosInstance.post(establishmentEndpoints.updateEstablishment(id), establishment);
      const { lastUsedEstablishmentParams, fetchEstablishmentsPage } = get();
      if (lastUsedEstablishmentParams) {
        await fetchEstablishmentsPage(lastUsedEstablishmentParams);
      }
      set({ loading: false });
    } catch (error: any) {
      set({ error: error.message || 'Failed to update establishment', loading: false });
    }
  },
  startExportFiltredEstablishments: async (params?: EstablishmentPageFilterParams) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.post(establishmentEndpoints.startExportFiltredEstablishments, { params });
      return response.data;
    } catch (error: any) {
      set({
        error: error.message || 'Failed to start export filtred establishments',
        loading: false,
      });
    }
  },
}));