/* eslint-disable import/order */
/* eslint-disable @typescript-eslint/consistent-type-imports */
import { createSlice, type PayloadAction } from "@reduxjs/toolkit";
import { clientState } from "./type";
import { addClient, getClient, getClients, updateClient, updateStatus } from "./thunk";
import { Client, Contacts } from "@/types/clientType";
import { addContactClient, updateContactClient } from "../contact/thunk";

const initialState: clientState = {
    status: "idle",
    error: null,
    clients: [],
    clientSelected: null,
};

const clientSlice = createSlice({
  name: "client",
  initialState,
  reducers: {
    selectClient: (state, action: PayloadAction<Client>) => {
      state.clientSelected = action.payload;
    }
  },
  extraReducers: (builder) => {


  /**
   * get all clients
   */
    builder.addCase(getClients.fulfilled, (state, action) => {
      const data = action.payload;
      
      state.clients = data;
      state.error = null;
      state.status = "succeeded";
    });

    builder.addCase(getClients.pending, (state) => {
      state.status = "loading";
    });

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


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

    builder.addCase(getClient.fulfilled, (state, action) => {
      const payload = action.payload as Client;

      const idx = state.clients.findIndex((n) => n.numero === payload.numero);

      if (idx !== -1) {
        state.clients[idx] = payload;
      } else {
        state.clients.unshift(payload);
      }

      state.status = "succeeded";
      state.error = null;
    });

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


    
    /**
     * create contact client
     */
    builder.addCase(addContactClient.pending, (state) => {
      state.status = "loading";
    });

    builder.addCase(addContactClient.fulfilled, (state, action) => {
      const payload = action.payload as Contacts;
      const idx = state.clients.findIndex((n) => n.numero === payload.numero);
      if (idx !== -1) {
        state.clients[idx].contacts?.unshift(payload);
      } 

      if (state.clientSelected?.numero === payload.numero) {
        state.clientSelected.contacts?.unshift(payload)
      }

      state.status = "succeeded";
      state.error = null;
    });

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



    /**
     * update contact client
     */
    builder.addCase(updateContactClient.pending, (state) => {
      state.status = "loading";
    });

    builder.addCase(updateContactClient.fulfilled, (state, action) => {
      const payload = action.payload as Contacts;
      const idx = state.clients.findIndex((n) => n.numero === payload.numero);
      if (idx !== -1) {
        const idxContact = state.clients[idx].contacts?.findIndex((n) => n.contact_numero === payload.contact_numero);
        if (idxContact !== -1) {
           state.clients[idx].contacts![idxContact || 0] = payload
        }
      } 

      if (state.clientSelected?.numero === payload.numero) {
        const idxContact = state.clientSelected.contacts?.findIndex((n) => n.contact_numero === payload.contact_numero);
         if (idxContact !== -1) {
           state.clientSelected.contacts![idxContact || 0] = payload
        }
      }

      state.status = "succeeded";
      state.error = null;
    });

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




    /**
     * add client
     */
    builder.addCase(addClient.fulfilled, (state, action) => {
      state.status = "succeeded";
      state.error = null;
    });

    builder.addCase(addClient.pending, (state) => {
      state.status = "loading";
    });

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


    /**
     * update client
     */
    builder.addCase(updateClient.pending, (state) => {
      state.status = "loading";
    });

    builder.addCase(updateClient.fulfilled, (state, action) => {
      const { client, success } = action.payload as unknown as { success: boolean; client: Client };
      
      if (success && client?.numero) {
        const idx = state.clients.findIndex((p) => p.numero === client.numero);

         if (idx !== -1) {
          const oldItem = state.clients[idx];

          state.clients[idx] = {
            ...oldItem, 
            intitule: client.intitule,
            adresse: client.adresse,
            code_postal: client.code_postal,
            ville: client.ville,
            telephone: client.telephone,
            email: client.email,
            siret: client.siret,
            tva_intra: client.tva_intra,
            code_naf: client.code_naf,
            encours_autorise: client.encours_autorise,
            assurance_credit: client.assurance_credit,
            pays: client.pays,
            est_actif: client.est_actif,
            est_prospect: client.est_prospect,
            type_tiers: client.type_tiers
          };
        }

      }
      state.status = "succeeded";
      state.error = null;
    });

    builder.addCase(updateClient.rejected, (state, action) => {
      state.status = "failed";
      state.error = (action.payload as string) || action.error.message || "Failed to update";
    });

     /**
     * update status client
     */
    builder.addCase(updateStatus.pending, (state) => {
      state.status = "loading";
    });

    builder.addCase(updateStatus.fulfilled, (state, action) => {
      const { client, success } = action.payload as unknown as { success: boolean; client: Client };
      
      if (success && client?.numero) {
        const idx = state.clients.findIndex((p) => p.numero === client.numero);

         if (idx !== -1) {
          const oldItem = state.clients[idx];

          state.clients[idx] = {
            ...oldItem, 
            intitule: client.intitule,
            adresse: client.adresse,
            code_postal: client.code_postal,
            ville: client.ville,
            telephone: client.telephone,
            email: client.email,
            siret: client.siret,
            tva_intra: client.tva_intra,
            code_naf: client.code_naf,
            encours_autorise: client.encours_autorise,
            assurance_credit: client.assurance_credit,
            pays: client.pays,
            est_actif: client.est_actif,
            est_prospect: client.est_prospect,
            type_tiers: client.type_tiers
          };
        }

      }
      state.status = "succeeded";
      state.error = null;
    });

    builder.addCase(updateStatus.rejected, (state, action) => {
      state.status = "failed";
      state.error = (action.payload as string) || action.error.message || "Failed to update";
    });

  },
});


export const { selectClient } = clientSlice.actions
export default clientSlice.reducer;


