"use client";
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { getStoredLocale } from "@/lib/getLocale";
import {
  fetchAddresses,
  addAddress,
  updateAddress,
  deleteAddress,
} from "@/lib/actions/addressActions";

// Define types for address data
interface Address {
  _id: string;
  name: string;
  address: string;
  phone: string;
  short_address?: string;
  building_name?: string;
  street?: string;
  secondary_number?: string;
  district?: string;
  address_line_1?: string;
  address_line_2?: string;
  city?: string;
  state?: string;
  postal_code?: string;
  country?: string;
  address_type?: string;
  isPrimary?: boolean;
}

interface AddressState {
  addresses: Address[];
  isLoading: boolean;
  error: string | null;
  successMessage: string | null;
  selectedAddress: string | null;
}

const initialState: AddressState = {
  addresses: [],
  isLoading: false,
  error: null,
  successMessage: null,
  selectedAddress: null,
};

// Async thunk for fetching addresses
export const fetchAddressesThunk = createAsyncThunk<
  Address[],
  string,
  { rejectValue: string }
>("address/fetchAddresses", async (token, { rejectWithValue }) => {
  const response = await fetchAddresses(token);
  if (response.success) {
    return response.data || [];
  } else {
    return rejectWithValue(response.message || "Failed to fetch addresses");
  }
});

// Async thunk for adding a new address
export const addAddressThunk = createAsyncThunk<
  Address,
  { addressData: any; token: string },
  { rejectValue: string }
>("address/addAddress", async ({ addressData, token }, { rejectWithValue }) => {
  const response = await addAddress(addressData, token);
  if (response.success) {
    return {
      _id: response.data?._id || response.data?.id,
      name: addressData.address_line_1 || "My Place",
      address: `${
        addressData.short_address ? addressData.short_address + ", " : ""
      }${addressData.building_name ? addressData.building_name + ", " : ""}${
        addressData.street ? addressData.street + ", " : ""
      }${
        addressData.secondary_number ? addressData.secondary_number + ", " : ""
      }${addressData.district ? addressData.district + ", " : ""}${
        addressData.address_line_1
      }${
        addressData.address_line_2 ? ", " + addressData.address_line_2 : ""
      }, ${addressData.city}, ${addressData.state}`,
      phone: addressData.alternate_address_contact_number,
      short_address: addressData.short_address,
      building_name: addressData.building_name,
      street: addressData.street,
      secondary_number: addressData.secondary_number,
      district: addressData.district,
      address_line_1: addressData.address_line_1,
      address_line_2: addressData.address_line_2,
      city: addressData.city,
      state: addressData.state,
      postal_code: addressData.postal_code,
      country: addressData.country,
      address_type: addressData.address_type,
      isPrimary: addressData.isPrimary, // New addresses are not primary by default
    };
  } else {
    return rejectWithValue(response.message || "Failed to add address");
  }
});

// Async thunk for updating an address
export const updateAddressThunk = createAsyncThunk<
  Address,
  {
    addressId: string;
    addressData: any;
    token: string;
    existingAddress?: Address;
  },
  { rejectValue: string }
>(
  "address/updateAddress",
  async (
    { addressId, addressData, token, existingAddress },
    { rejectWithValue }
  ) => {
    const response = await updateAddress(addressId, addressData, token);
    if (response.success) {
      return {
        _id: response.data?._id || addressId,
        name: addressData.address_line_1 || "My Place",
        address: `${
          addressData.short_address ? addressData.short_address + ", " : ""
        }${addressData.building_name ? addressData.building_name + ", " : ""}${
          addressData.street ? addressData.street + ", " : ""
        }${
          addressData.secondary_number
            ? addressData.secondary_number + ", "
            : ""
        }${addressData.district ? addressData.district + ", " : ""}${
          addressData.address_line_1
        }${
          addressData.address_line_2 ? ", " + addressData.address_line_2 : ""
        }, ${addressData.city}, ${addressData.state}`,
        phone: addressData.alternate_address_contact_number,
        short_address: addressData.short_address,
        building_name: addressData.building_name,
        street: addressData.street,
        secondary_number: addressData.secondary_number,
        district: addressData.district,
        address_line_1: addressData.address_line_1,
        address_line_2: addressData.address_line_2,
        city: addressData.city,
        state: addressData.state,
        postal_code: addressData.postal_code,
        country: addressData.country,
        address_type: addressData.address_type,
        isPrimary: existingAddress?.isPrimary ?? false, // Preserve existing primary status
      };
    } else {
      return rejectWithValue(response.message || "Failed to update address");
    }
  }
);

// Async thunk for deleting an address
export const deleteAddressThunk = createAsyncThunk<
  string,
  { addressId: string; token: string },
  { rejectValue: string }
>(
  "address/deleteAddress",
  async ({ addressId, token }, { rejectWithValue }) => {
    const response = await deleteAddress(addressId, token);
    if (response.success) {
      return addressId;
    }
    return rejectWithValue(response.message || "Failed to delete address");
  }
);

const addressSlice = createSlice({
  name: "address",
  initialState,
  reducers: {
    clearMessages: (state) => {
      state.error = null;
      state.successMessage = null;
    },
    clearAddresses: (state) => {
      state.addresses = [];
    },
    setSelectedAddress: (state, action) => {
      state.selectedAddress = action.payload;
    },
    setPrimaryAddress: (state, action) => {
      const addressId = action.payload;
      state.addresses = state.addresses.map((addr) => ({
        ...addr,
        isPrimary: addr._id === addressId,
      }));
      state.selectedAddress = addressId;
    },
    addLocalAddress: (state, action) => {
      state.addresses.push(action.payload);
    },
    updateLocalAddress: (state, action) => {
      const index = state.addresses.findIndex(
        (addr) => addr._id === action.payload._id
      );
      if (index !== -1) {
        state.addresses[index] = action.payload;
      }
    },
    deleteLocalAddress: (state, action) => {
      state.addresses = state.addresses.filter(
        (addr) => addr._id !== action.payload
      );
      if (state.selectedAddress === action.payload) {
        state.selectedAddress =
          state.addresses.length > 0 ? state.addresses[0]._id : null;
      }
    },
  },
  extraReducers: (builder) => {
    builder
      // Fetch addresses
      .addCase(fetchAddressesThunk.pending, (state) => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(fetchAddressesThunk.fulfilled, (state, action) => {
        state.isLoading = false;
        state.addresses = action.payload.map((addr) => ({
          ...addr,
          _id: addr._id,
        }));
        if (state.addresses.length > 0 && !state.selectedAddress) {
          state.selectedAddress = state.addresses[0]._id;
        }
      })
      .addCase(fetchAddressesThunk.rejected, (state, action) => {
        state.isLoading = false;
        state.error = action.payload || "Failed to fetch addresses";
      })
      // Add address
      .addCase(addAddressThunk.pending, (state) => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(addAddressThunk.fulfilled, (state, action) => {
        state.isLoading = false;
        state.addresses.push(action.payload);
        state.successMessage = "Address added successfully";
      })
      .addCase(addAddressThunk.rejected, (state, action) => {
        state.isLoading = false;
        state.error = action.payload || "Failed to add address";
      })
      // Update address
      .addCase(updateAddressThunk.pending, (state) => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(updateAddressThunk.fulfilled, (state, action) => {
        state.isLoading = false;
        const index = state.addresses.findIndex(
          (addr) => addr._id === action.payload._id
        );
        if (index !== -1) {
          state.addresses[index] = action.payload;
        }
        state.successMessage = "Address updated successfully";
      })
      .addCase(updateAddressThunk.rejected, (state, action) => {
        state.isLoading = false;
        state.error = action.payload || "Failed to update address";
      })
      // Delete address
      .addCase(deleteAddressThunk.pending, (state) => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(deleteAddressThunk.fulfilled, (state, action) => {
        state.isLoading = false;
        state.addresses = state.addresses.filter(
          (addr) => addr._id !== action.payload
        );
        if (state.selectedAddress === action.payload) {
          state.selectedAddress =
            state.addresses.length > 0 ? state.addresses[0]._id : null;
        }
        state.successMessage = "Address deleted successfully";
      })
      .addCase(deleteAddressThunk.rejected, (state, action) => {
        state.isLoading = false;
        state.error = action.payload || "Failed to delete address";
      });
  },
});

export const {
  clearMessages,
  clearAddresses,
  setSelectedAddress,
  addLocalAddress,
  updateLocalAddress,
  deleteLocalAddress,
} = addressSlice.actions;

export default addressSlice.reducer;
