import { create } from 'zustand';
import axiosInstance from '@/utils/axios';
import { circuitEndpoints } from '@/shared/api/endpoints/circuit';
import {
  AmendmentPassengerList,
  AmendmentPassengerDetails,
  SearchPassengerAmendmentParams,
  AmendmentTripDTO,
  InitialAmendmentPassengerDTO,
} from '@/shared/types/ammendment-passenger';
import { Pageable } from '@/shared/types/client';
import {
  convertAmendmentPayload,
  convertAmendmentPayloadInverse,
} from '@/shared/sections/usager/components/usager-form/avenants-horaires/utils/converters';

interface AmendmentPassengerStore {
  amendments: AmendmentPassengerList[];
  activeOrFutureAmendments: AmendmentPassengerList[];
  totalElements: number;
  amendmentDetails: AmendmentPassengerDetails | null;
  loading: boolean;
  error: string | null;
  lastPassengerAmendmentParams: SearchPassengerAmendmentParams | null;
  fetchAmendments: (params: SearchPassengerAmendmentParams) => Promise<void>;
  getAmendmentById: (id: string) => Promise<AmendmentPassengerDetails | null>;
  addAmendment: (data: Partial<AmendmentPassengerDetails>) => Promise<AmendmentPassengerDetails>;
  updateAmendment: (id: string, data: Partial<AmendmentPassengerDetails>) => Promise<void>;
  getActiveOrFutureAmendmentsByPassengerId: (
    params: SearchPassengerAmendmentParams
  ) => Promise<void>;
  getAmendmentByPassengerId: (passengerId: number) => Promise<AmendmentTripDTO | null>;
  getInitialAmendmentByPassengerId: (
    passengerId: number
  ) => Promise<InitialAmendmentPassengerDTO | null>;
  isPassengerAttachedToACertainAmendment: (passengerId: string) => Promise<string>;
  areTripsAlreadyGeneratedForAmendment: (passengerId: string) => Promise<boolean>;
}

export const useAmendmentPassengerStore = create<AmendmentPassengerStore>((set, get) => ({
  amendments: [],
  totalElements: 0,
  amendmentDetails: null,
  loading: false,
  error: null,
  lastPassengerAmendmentParams: null,
  activeOrFutureAmendments: [],
  fetchAmendments: async (params) => {
    set({ loading: true, error: null, lastPassengerAmendmentParams: params });
    try {
      const { data } = await axiosInstance.get<Pageable<AmendmentPassengerList>>(
        circuitEndpoints.circuit.amendmentPassenger.getAllAmendmentsPassenger,
        { params }
      );
      set({ amendments: data.content, totalElements: data.totalElements, loading: false });
    } catch (error: any) {
      set({
        error: error.message || 'Erreur lors de la récupération des amendements',
        loading: false,
      });
    }
  },

  getAmendmentById: async (id) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get(
        circuitEndpoints.circuit.amendmentPassenger.getAmendmentPassengerById(id)
      );
      const amendmentDetails = convertAmendmentPayloadInverse(response.data);
      set({ loading: false });
      return amendmentDetails as AmendmentPassengerDetails;
    } catch (error: any) {
      set({ error: error.message || 'Erreur lors de la récupération du détail', loading: false });
      throw error;
      return null;
    }
  },
  addAmendment: async (payload) => {
    set({ loading: true, error: null });
    try {
      const convertedPayload = convertAmendmentPayload(payload, false);
      const response = await axiosInstance.post(
        circuitEndpoints.circuit.amendmentPassenger.addAmendmentPassenger,
        convertedPayload
      );
      const amendment = convertAmendmentPayloadInverse(response.data);
      const { lastPassengerAmendmentParams, fetchAmendments } = get();
      if (lastPassengerAmendmentParams) {
        await fetchAmendments(lastPassengerAmendmentParams);
      }
      set({ loading: false });
      return amendment as AmendmentPassengerDetails;
    } catch (error: any) {
      set({ error: error.message || "Erreur lors de l'ajout de l'amendement", loading: false });
      throw error;
    }
  },

  updateAmendment: async (id: string, payload) => {
    set({ loading: true, error: null });
    try {
      const convertedPayload = convertAmendmentPayload(payload, true);
      await axiosInstance.put(
        circuitEndpoints.circuit.amendmentPassenger.updateAmendmentPassenger(id),
        convertedPayload
      );
      set({ loading: false });
    } catch (error: any) {
      set({
        error: error.message || "Erreur lors de la mise à jour de l'amendement",
        loading: false,
      });
      throw error;
    }
  },

  getActiveOrFutureAmendmentsByPassengerId: async (params) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get(
        circuitEndpoints.circuit.amendmentPassenger.getActiveOrFutureAmendmentsByPassengerId,
        { params }
      );
      set({ activeOrFutureAmendments: response.data.content, loading: false });
    } catch (error: any) {
      set({
        error: error.message || 'Erreur lors de la récupération des amendements',
        loading: false,
      });
      throw error;
    }
  },

  getAmendmentByPassengerId: async (passengerId) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get(
        circuitEndpoints.circuit.amendmentPassenger.getAmendmentByPassengerId(
          passengerId.toString()
        )
      );
      set({ loading: false });
      return response.data;
    } catch (error: any) {
      set({
        error: error.message || "Erreur lors de la récupération de l'amendement par passager",
        loading: false,
      });
      throw error;
    }
  },
  getInitialAmendmentByPassengerId: async (passengerId) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get<InitialAmendmentPassengerDTO>(
        circuitEndpoints.circuit.amendmentPassenger.getInitialAmendmentByPassengerId(
          passengerId.toString()
        )
      );
      set({ loading: false });
      const amendmentDetails = convertAmendmentPayloadInverse(response.data);
      return amendmentDetails as InitialAmendmentPassengerDTO;
    } catch (error: any) {
      set({
        error:
          error.message || "Erreur lors de la récupération de l'amendement initial par passager",
        loading: false,
      });
      throw error;
    }
  },
  isPassengerAttachedToACertainAmendment: async (passengerId: string) => {
    try {
      const resp = await axiosInstance.get<boolean>(
        circuitEndpoints.circuit.amendmentPassenger.isPassengerAttachedToAmendment(passengerId)
      );
      if (resp.data) {
        return 'attached';
      }
      return 'unattached';
    } catch (error: any) {
      return (
        error.response?.data?.message ||
        error.message ||
        'Fetching passenger attachment to a certain amendment failed'
      );
    }
  },

  areTripsAlreadyGeneratedForAmendment: async (passengerId: string) => {
    try {
      const response = await axiosInstance.get<boolean>(
        circuitEndpoints.circuit.amendmentPassenger.areTripsAlreadyGeneratedForAmendment(passengerId)
      );
      return response.data;
    } catch (error: any) {
      set({
        error: error.message || 'Erreur lors de la vérification de la génération des trajets',
        loading: false,
      });
      throw error;
    }
  },
}));
