/* eslint-disable import/order */
/* eslint-disable @typescript-eslint/consistent-type-imports */
import { createSlice, isFulfilled, isPending, isRejected, type PayloadAction } from "@reduxjs/toolkit";
import { reglementState } from "./type";
import { Comptes, ComptesResponse, Devise, DeviseResponse, Encaissement, EncaissementResponse, FacturesReglement, Mode, ModeResponse, ReglementsIdResponse, reglementsResponse, Statistique, Taux, TauxResponse, Tresorerie, TresorerieResponse } from "@/types/reglementType";
import { getCompteGeneraux, getDevises, getMode, getTaux, getTresorerie, getEncaissement, loadAllReglementData, getReglement, reglerFacture, getReglementId } from "./thunk";

const initialState: reglementState = {
  status: "idle",
  error: null,

  reglements: [],
  reglementSelected: null,

  statistiques: null, 

  modes: [],
  modeSelected: null,

  devises: [],
  deviseSelected: null,

  tresoreries: [],
  tresorerieSelected: null,

  CompteGeneraux: [],
  CompteGenerauxSelected: null,

  taux: [],
  tauxSelected: null,

  encaissements: null,
};

const reglementSlice = createSlice({
  name: "reglement",
  initialState,

  reducers: {
    selectReglement: (state, action: PayloadAction<FacturesReglement>) => {
      state.reglementSelected = action.payload;
    },

    selectMode: (state, action: PayloadAction<Mode>) => {
      state.modeSelected = action.payload;
    },

    selectDevise: (state, action: PayloadAction<Devise>) => {
      state.deviseSelected = action.payload;
    },

    selectTresorerie: (state, action: PayloadAction<Tresorerie>) => {
      state.tresorerieSelected = action.payload;
    },

    selectCompteGeneraux: (state, action: PayloadAction<Comptes>) => {
      state.CompteGenerauxSelected = action.payload;
    },

    selectTaux: (state, action: PayloadAction<Taux>) => {
      state.tauxSelected = action.payload;
    },

    selectEncaissement: (state, action: PayloadAction<Encaissement>) => {
      state.encaissements = action.payload;
    },
  },

  extraReducers: (builder) => {

  /**
   * regler facture
   */
    builder.addCase(reglerFacture.pending, (state) => {
      state.status = "loading";
    });

    builder.addCase(reglerFacture.fulfilled, (state) => {
      state.status = "succeeded";
      state.error = null;
    });

    builder.addCase(reglerFacture.rejected, (state, action) => {
      state.status = "failed";
      state.error = (action.payload as string) || action.error.message || "An error occurred";
    });



    /**
     * get reglement by id
     */
    builder.addCase(getReglementId.pending, (state) => {
      state.status = "loading";
    });

    builder.addCase(getReglementId.fulfilled, (state, action) => {
      const { success, data } = action.payload as ReglementsIdResponse;
      
      if(success) {
        const idx = state.reglements.findIndex((n) => n.numero === data.numero);
        if (idx !== -1) {
          state.reglements[idx] = data;
        } else {
          state.reglements.unshift(data);
        }
      }
      state.status = "succeeded";
      state.error = null;
    });

    builder.addCase(getReglementId.rejected, (state, action) => {
      state.status = "failed";
      state.error = (action.payload as string) || action.error.message || "An error occurred";
    });
    
    /**
     * ✅ LOAD ALL DATA - Handler unifié pour charger toutes les données
     */
    builder.addCase(loadAllReglementData.fulfilled, (state, action) => {
      const { reglements, modes, devises, tresoreries, comptes, taux } = action.payload;

      if (reglements){
        state.reglements = reglements.factures;
        state.statistiques = reglements.statistiques;
      }
      if (modes) state.modes = modes;
      if (devises) state.devises = devises;
      if (tresoreries) state.tresoreries = tresoreries;
      if (comptes) state.CompteGeneraux = comptes;
      if (taux) state.taux = taux;
    });

    /**
     * SUCCESS HANDLERS - Handlers individuels (optionnels, pour les appels individuels)
     */
    builder
      .addCase(getReglement.fulfilled, (state, action) => {
        const { data, success } = action.payload as reglementsResponse;
        if (success) {
          state.reglements = data.factures;
          state.statistiques = data.statistiques;
        }
      })
      .addCase(getMode.fulfilled, (state, action) => {
        const { data, success } = action.payload as ModeResponse;
        if (success) state.modes = data.modes;
      })
      .addCase(getDevises.fulfilled, (state, action) => {
        const { data, success } = action.payload as DeviseResponse;
        if (success) state.devises = data.devises;
      })
      .addCase(getTresorerie.fulfilled, (state, action) => {
        const { data, success } = action.payload as TresorerieResponse;
        if (success) state.tresoreries = data.journaux;
      })
      .addCase(getCompteGeneraux.fulfilled, (state, action) => {
        const { data, success } = action.payload as ComptesResponse;
        if (success) state.CompteGeneraux = data.comptes;
      })
      .addCase(getTaux.fulfilled, (state, action) => {
        const { data, success } = action.payload as TauxResponse;
        if (success) state.taux = data.taux;
      })
      .addCase(getEncaissement.fulfilled, (state, action) => {
        const { data, success } = action.payload as EncaissementResponse;
        if (success) state.encaissements = data;
      });

    /**
     * GLOBAL MATCHERS
     */
    builder
      .addMatcher(
        isPending(
          loadAllReglementData,
          getReglement,
          getMode,
          getDevises,
          getTresorerie,
          getCompteGeneraux,
          getTaux,
          getEncaissement
        ),
        (state) => {
          state.status = "loading";
          state.error = null;
        }
      )
      .addMatcher(
        isFulfilled(
          loadAllReglementData,
          getReglement,
          getMode,
          getDevises,
          getTresorerie,
          getCompteGeneraux,
          getTaux,
          getEncaissement
        ),
        (state) => {
          state.status = "succeeded";
          state.error = null;
        }
      )
      .addMatcher(
        isRejected(
          loadAllReglementData,
          getReglement,
          getMode,
          getDevises,
          getTresorerie,
          getCompteGeneraux,
          getTaux,
          getEncaissement
        ),
        (state, action) => {
          state.status = "failed";
          state.error = action.error.message ?? "An error occurred";
        }
      );
  },
});

export const { selectReglement, selectMode, selectDevise, selectTresorerie, selectCompteGeneraux, selectTaux, selectEncaissement } = reglementSlice.actions;
export default reglementSlice.reducer;