import { createSlice, PayloadAction } from '@reduxjs/toolkit';

export interface CartItem {
  id: string;
  bookId: string;
  variantId?: string;
  format?: string;
  sku?: string;
  digitalFormat?: string;
  title: string;
  price: number;
  discountPrice?: number;
  coverImage?: string;
  quantity: number;
  stock: number;
  authorName?: string;
}

export interface AppliedCoupon {
  code: string;
  discountType: 'PERCENTAGE' | 'FIXED_AMOUNT';
  discountValue: number;
  discountAmount: number;
}

export type CurrencyCode = 'INR' | 'USD' | 'EUR' | 'GBP';

interface CartState {
  items: CartItem[];
  savedForLaterItems: CartItem[];
  coupon: AppliedCoupon | null;
  giftCardAmount: number;
  giftNote: string;
  subtotal: number;
  discountTotal: number;
  shippingFee: number;
  taxAmount: number;
  grandTotal: number;
  totalQuantity: number;
  currency: CurrencyCode;
}

const initialState: CartState = {
  items: [],
  savedForLaterItems: [],
  coupon: null,
  giftCardAmount: 0,
  giftNote: '',
  subtotal: 0,
  discountTotal: 0,
  shippingFee: 0,
  taxAmount: 0,
  grandTotal: 0,
  totalQuantity: 0,
  currency: 'INR',
};

const calculateCartTotals = (state: CartState) => {
  const totalQuantity = state.items.reduce((sum, item) => sum + item.quantity, 0);
  
  const subtotal = state.items.reduce((sum, item) => {
    const effectivePrice = item.discountPrice || item.price;
    return sum + effectivePrice * item.quantity;
  }, 0);

  // Calculate Coupon Discount
  let discountTotal = 0;
  if (state.coupon) {
    if (state.coupon.discountType === 'PERCENTAGE') {
      discountTotal = (subtotal * state.coupon.discountValue) / 100;
    } else {
      discountTotal = Math.min(state.coupon.discountValue, subtotal);
    }
    state.coupon.discountAmount = discountTotal;
  }

  // Calculate Shipping (Free above ₹2,999)
  const shippingFee = subtotal > 0 && subtotal < 2999 ? 250 : 0;

  // Calculate Tax (5% GST on books)
  const taxableAmount = Math.max(0, subtotal - discountTotal);
  const taxAmount = taxableAmount * 0.05;

  // Compute Grand Total
  const grandTotal = Math.max(0, taxableAmount + shippingFee + taxAmount - state.giftCardAmount);

  state.totalQuantity = totalQuantity;
  state.subtotal = Math.round(subtotal);
  state.discountTotal = Math.round(discountTotal);
  state.shippingFee = shippingFee;
  state.taxAmount = Math.round(taxAmount);
  state.grandTotal = Math.round(grandTotal);
};

export const cartSlice = createSlice({
  name: 'cart',
  initialState,
  reducers: {
    addToCart: (state, action: PayloadAction<Omit<CartItem, 'quantity'> & { quantity?: number }>) => {
      const quantityToAdd = action.payload.quantity || 1;
      const targetVariantId = action.payload.variantId || null;
      const existing = state.items.find(
        (item) => item.bookId === action.payload.bookId && (item.variantId || null) === targetVariantId
      );
      if (existing) {
        existing.quantity = Math.min(existing.quantity + quantityToAdd, existing.stock);
      } else {
        state.items.push({ ...action.payload, quantity: quantityToAdd });
      }
      calculateCartTotals(state);
      if (typeof window !== 'undefined') {
        localStorage.setItem('guest_cart', JSON.stringify(state.items));
      }
    },

    removeFromCart: (state, action: PayloadAction<{ bookId: string; variantId?: string } | string>) => {
      const matchBookId = typeof action.payload === 'string' ? action.payload : action.payload.bookId;
      const matchVariantId = typeof action.payload === 'string' ? undefined : action.payload.variantId;
      
      state.items = state.items.filter((item) => {
        if (matchVariantId !== undefined) {
          return !(item.bookId === matchBookId && item.variantId === matchVariantId);
        }
        return item.bookId !== matchBookId;
      });
      calculateCartTotals(state);
      if (typeof window !== 'undefined') {
        localStorage.setItem('guest_cart', JSON.stringify(state.items));
      }
    },

    updateQuantity: (state, action: PayloadAction<{ bookId: string; variantId?: string; quantity: number }>) => {
      const item = state.items.find(
        (i) => i.bookId === action.payload.bookId && (i.variantId || undefined) === (action.payload.variantId || undefined)
      );
      if (item) {
        item.quantity = Math.max(1, Math.min(action.payload.quantity, item.stock));
      }
      calculateCartTotals(state);
      if (typeof window !== 'undefined') {
        localStorage.setItem('guest_cart', JSON.stringify(state.items));
      }
    },

    saveForLater: (state, action: PayloadAction<string>) => {
      const itemToSave = state.items.find((i) => i.bookId === action.payload);
      if (itemToSave) {
        state.items = state.items.filter((i) => i.bookId !== action.payload);
        if (!state.savedForLaterItems.some((i) => i.bookId === action.payload)) {
          state.savedForLaterItems.push(itemToSave);
        }
      }
      calculateCartTotals(state);
    },

    moveToCartFromSaved: (state, action: PayloadAction<string>) => {
      const itemToMove = state.savedForLaterItems.find((i) => i.bookId === action.payload);
      if (itemToMove) {
        state.savedForLaterItems = state.savedForLaterItems.filter((i) => i.bookId !== action.payload);
        state.items.push(itemToMove);
      }
      calculateCartTotals(state);
    },

    applyCoupon: (state, action: PayloadAction<{ code: string; discountType: 'PERCENTAGE' | 'FIXED_AMOUNT'; discountValue: number }>) => {
      state.coupon = {
        code: action.payload.code.toUpperCase(),
        discountType: action.payload.discountType,
        discountValue: action.payload.discountValue,
        discountAmount: 0,
      };
      calculateCartTotals(state);
    },

    removeCoupon: (state) => {
      state.coupon = null;
      calculateCartTotals(state);
    },

    applyGiftCard: (state, action: PayloadAction<number>) => {
      state.giftCardAmount = action.payload;
      calculateCartTotals(state);
    },

    setGiftNote: (state, action: PayloadAction<string>) => {
      state.giftNote = action.payload;
    },

    setCurrency: (state, action: PayloadAction<CurrencyCode>) => {
      state.currency = action.payload;
    },

    clearCart: (state) => {
      state.items = [];
      state.savedForLaterItems = [];
      state.coupon = null;
      state.giftCardAmount = 0;
      state.giftNote = '';
      calculateCartTotals(state);
      if (typeof window !== 'undefined') {
        localStorage.removeItem('guest_cart');
      }
    },

    loadGuestCart: (state) => {
      if (typeof window !== 'undefined') {
        const stored = localStorage.getItem('guest_cart');
        if (stored) {
          try {
            state.items = JSON.parse(stored);
            calculateCartTotals(state);
          } catch {
            localStorage.removeItem('guest_cart');
          }
        }
      }
    },
  },
});

export const {
  addToCart,
  removeFromCart,
  updateQuantity,
  saveForLater,
  moveToCartFromSaved,
  applyCoupon,
  removeCoupon,
  applyGiftCard,
  setGiftNote,
  setCurrency,
  clearCart,
  loadGuestCart,
} = cartSlice.actions;

export default cartSlice.reducer;
