import { createAsyncThunk, createSlice, PayloadAction } from "@reduxjs/toolkit";
import axiosInstanceClient from "@/utils/axiosClient";
import { Addresses } from "@/interfaces/types";

interface AddItemProps {
  id: any;
}

interface CrudState {
  mainLoader: boolean;
  allAddressesItems: Addresses[];
  singleItem: Addresses | null;
  itemId: AddItemProps | null;
  error: { status: number | null };
}

const initialState: CrudState = {
  mainLoader: true,
  allAddressesItems: [],
  itemId: null,
  singleItem: null,
  error: { status: null },
};

export const getAllAddressesItems = createAsyncThunk(
  "address/locations",
  async (_, { rejectWithValue }) => {
    try {
      const { data } = await axiosInstanceClient.get(`client/addresses`);
      return data?.data || [];
    } catch (error: any) {
      return rejectWithValue({ status: error.response?.status || 404 });
    }
  },
);

export const getAddressById = createAsyncThunk(
  "address/getAddressById",
  async ({ id }: AddItemProps, { rejectWithValue }) => {
    try {
      const { data } = await axiosInstanceClient.get(`client/addresses/${id}`);
      return data?.data || [];
    } catch (error: any) {
      return rejectWithValue({
        message: error.message,
        status: error.response?.status || 404,
      });
    }
  },
);

// Slice
const addressSlice = createSlice({
  name: "address",
  initialState,
  reducers: {
    CancelAddOrUpdateAddresses: (state) => {
      state.singleItem = null;
      state.mainLoader = false;
      state.error = { status: null };
    },
    AddAddress: (state, action: PayloadAction<{ address: any }>) => {
      const { address } = action.payload;
      if (address.is_default) {
        state.allAddressesItems = state.allAddressesItems.map((item: any) => ({
          ...item,
          is_default: false,
        }));
      }
      state.allAddressesItems.push(address);
    },
    EditAddress: (state, action: PayloadAction<{ address: any }>) => {
      const { address } = action.payload;
      if (address.is_default) {
        state.allAddressesItems = state.allAddressesItems.map((item: any) =>
          item.id != address.id ? { ...item, is_default: false } : item,
        );
      }
      state.allAddressesItems = state.allAddressesItems.map((item: any) =>
        item.id == address.id ? address : item,
      );
    },
    DeleteAddress: (state, action: PayloadAction<{ id: any }>) => {
      const { id } = action.payload;
      state.allAddressesItems = state.allAddressesItems.filter(
        (item: any) => item.id != id,
      );
    },
    ToggleDefaultAddress: (state, action: PayloadAction<{ id: any }>) => {
      const { id } = action.payload;
      state.allAddressesItems = state.allAddressesItems.map((item: any) =>
        item.id == id
          ? { ...item, is_default: true }
          : { ...item, is_default: false },
      );
    },
    setAddresses: (state, action: PayloadAction<{ data: any }>) => {
      state.allAddressesItems = action.payload.data;
      state.mainLoader = false;
    },
    setAddressesLoading: (
      state,
      action: PayloadAction<{ isLoading: boolean }>,
    ) => {
      state.mainLoader = action.payload.isLoading;
    },
    clearAddresses: (state) => {
      state.allAddressesItems = [];
    },
    setAllAddressesItems: (state, action: PayloadAction<any>) => {
      state.allAddressesItems = action.payload;
      state.mainLoader = false;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(getAllAddressesItems.pending, (state) => {
        state.mainLoader = true;
      })
      .addCase(getAllAddressesItems.fulfilled, (state, action) => {
        state.mainLoader = false;
        state.allAddressesItems = action.payload;
      })
      .addCase(getAllAddressesItems.rejected, (state: any, action) => {
        state.mainLoader = false;
        state.error = action.payload;
      })
      .addCase(getAddressById.pending, (state) => {
        // state.mainLoader = true;
      })
      .addCase(getAddressById.fulfilled, (state, action) => {
        state.mainLoader = false;
        state.singleItem = action.payload;
      })
      .addCase(getAddressById.rejected, (state: any, action) => {
        state.mainLoader = false;
        state.error = action.payload;
      });
  },
});

export const {
  CancelAddOrUpdateAddresses,
  DeleteAddress,
  AddAddress,
  EditAddress,
  ToggleDefaultAddress,
  clearAddresses,
  setAddresses,
  setAddressesLoading,
  setAllAddressesItems,
} = addressSlice.actions;
export default addressSlice.reducer;
