import { create } from "zustand";
import { persist, createJSONStorage } from "zustand/middleware";
import * as StoreApi from "./store-api";

export interface CartItemDisplay {
  key: string;
  id: number;
  name: string;
  price: string;
  priceRaw: number;
  quantity: number;
  image: string;
  subtotal: string;
  stockStatus: string;
}

export interface AppliedCoupon {
  code: string;
  discount: string;
}

interface CartState {
  token: string | null;
  items: CartItemDisplay[];
  itemCount: number;
  subtotal: string;
  discount: string;
  total: string;
  coupons: AppliedCoupon[];
  currency: string;
  currencySymbol: string;
  loading: boolean;
  error: string | null;
  initialized: boolean;

  init: () => Promise<void>;
  addItem: (id: number, qty?: number) => Promise<void>;
  updateQuantity: (itemKey: string, qty: number) => Promise<void>;
  removeItem: (itemKey: string) => Promise<void>;
  applyCoupon: (code: string) => Promise<void>;
  removeCoupon: (code: string) => Promise<void>;
  clearError: () => void;
  refreshCart: () => Promise<void>;
  resetCart: () => void;
}

function mapItem(item: StoreApi.CartItem): CartItemDisplay {
  const minor = item.prices.currency_minor_unit || 2;
  return {
    key: item.key,
    id: item.id,
    name: item.name,
    price: `${item.prices.currency_symbol}${item.prices.price}`,
    priceRaw: parseInt(item.prices.price, 10) / Math.pow(10, minor),
    quantity: item.quantity,
    image: item.images?.[0]?.src || "",
    subtotal: `${item.totals.line_total}`,
    stockStatus: "instock",
  };
}

function formatPrice(raw: string, minorUnit = 2): string {
  const val = parseInt(raw, 10) / Math.pow(10, minorUnit);
  return val.toFixed(minorUnit);
}

function cartToState(cart: StoreApi.CartResponse) {
  return {
    items: cart.items.map(mapItem),
    itemCount: cart.items_count,
    subtotal: formatPrice(cart.totals.total_items),
    discount: formatPrice(cart.totals.total_discount),
    total: formatPrice(cart.totals.total_price),
    coupons: cart.coupons.map((c) => ({ code: c.code, discount: formatPrice(c.totals.total_discount) })),
    currency: cart.totals.currency_code,
    currencySymbol: cart.totals.currency_symbol,
  };
}

export const useCartStore = create<CartState>()(
  persist(
    (set, get) => ({
  token: null,
  items: [],
  itemCount: 0,
  subtotal: "0.00",
  discount: "0.00",
  total: "0.00",
  coupons: [],
  currency: "USD",
  currencySymbol: "$",
  loading: false,
  error: null,
  initialized: false,

      init: async () => {
        if (get().initialized) return;
        try {
          const cart = await StoreApi.getCart();
          set({ ...cartToState(cart), initialized: true });
        } catch {
          set({ initialized: true, items: [], itemCount: 0 });
        }
      },

      refreshCart: async () => {
        set({ loading: true, error: null });
        try {
          const cart = await StoreApi.getCart();
          set({ ...cartToState(cart), loading: false });
        } catch (e: unknown) {
          set({
            loading: false,
            error: e instanceof Error ? e.message : "Failed to load cart",
          });
        }
      },

      addItem: async (id, qty = 1) => {
        set({ loading: true, error: null });
        try {
          const cart = await StoreApi.addItem(id, qty);
          set({ ...cartToState(cart), loading: false });
        } catch (e: unknown) {
          set({
            loading: false,
            error: e instanceof Error ? e.message : "Failed to add item",
          });
        }
      },

      updateQuantity: async (itemKey, qty) => {
        set({ loading: true, error: null });
        try {
          const cart = await StoreApi.updateQuantity(itemKey, qty);
          set({ ...cartToState(cart), loading: false });
        } catch (e: unknown) {
          set({
            loading: false,
            error:
              e instanceof Error ? e.message : "Failed to update quantity",
          });
        }
      },

      removeItem: async (itemKey) => {
        set({ loading: true, error: null });
        try {
          const cart = await StoreApi.removeItem(itemKey);
          set({ ...cartToState(cart), loading: false });
        } catch (e: unknown) {
          const msg = e instanceof Error ? e.message : "Failed to remove item";
          console.error("removeItem error:", msg);
          set({ loading: false, error: msg });
        }
      },

      applyCoupon: async (code) => {
        set({ loading: true, error: null });
        try {
          const cart = await StoreApi.applyCoupon(code);
          set({ ...cartToState(cart), loading: false });
        } catch (e: unknown) {
          set({
            loading: false,
            error: e instanceof Error ? e.message : "Invalid coupon",
          });
        }
      },

      removeCoupon: async (code) => {
        set({ loading: true, error: null });
        try {
          const cart = await StoreApi.removeCoupon(code);
          set({ ...cartToState(cart), loading: false });
        } catch (e: unknown) {
          set({
            loading: false,
            error: e instanceof Error ? e.message : "Failed to remove coupon",
          });
        }
      },

      clearError: () => set({ error: null }),

      resetCart: () => {
        set({
          token: null,
          items: [],
          itemCount: 0,
          subtotal: "0.00",
          discount: "0.00",
          total: "0.00",
          coupons: [],
          currency: "USD",
          currencySymbol: "$",
          error: null,
        });
      },
    }),
    {
      name: "sigma-cart",
      storage: createJSONStorage(() => localStorage),
      partialize: (state) => ({
        token: state.token,
        items: state.items,
        itemCount: state.itemCount,
        subtotal: state.subtotal,
        discount: state.discount,
        total: state.total,
        coupons: state.coupons,
        currency: state.currency,
        currencySymbol: state.currencySymbol,
      }),
    },
  ),
);
