import type { Product, ProductOptionValue, SellUnit } from './types'
import { formatPriceFa } from './types'

const CART_KEY = 'balout.cart'
export const CART_EVENT = 'balout:cart-change'
export const TOAST_EVENT = 'balout:toast'

export type CartOption = {
  id: string
  name: string
  price: number
}

export type CartItem = {
  key: string
  productId: string
  nameFa: string
  imageUrl: string | null
  sellUnit: SellUnit
  basePrice: number
  quantity: number
  options: CartOption[]
}

export type ToastPayload = {
  message: string
  detail?: string
}

function optionLabel(option: ProductOptionValue) {
  const flavor = option.flavor?.nameFa?.trim()
  if (flavor && option.amount) return `${flavor} — ${option.amount}`
  return flavor || option.amount || 'گزینه'
}

function itemKey(productId: string, optionIds: string[]) {
  const sorted = [...optionIds].sort().join(',')
  return sorted ? `${productId}::${sorted}` : productId
}

function readCart(): CartItem[] {
  try {
    const raw = localStorage.getItem(CART_KEY)
    if (!raw) return []
    const parsed = JSON.parse(raw) as unknown
    return Array.isArray(parsed) ? (parsed as CartItem[]) : []
  } catch {
    return []
  }
}

function writeCart(items: CartItem[]) {
  localStorage.setItem(CART_KEY, JSON.stringify(items))
  window.dispatchEvent(new CustomEvent(CART_EVENT))
}

export function getCartItems() {
  return readCart()
}

export function getCartSubtotal() {
  return readCart().reduce((sum, item) => sum + cartItemLineTotal(item), 0)
}

export function getCartCount() {
  return readCart().length
}

export function setCartItemQuantity(key: string, quantity: number) {
  const items = readCart()
  const item = items.find((row) => row.key === key)
  if (!item) return
  const min = item.sellUnit === 'kilo' ? 0.1 : 1
  if (quantity < min) {
    writeCart(items.filter((row) => row.key !== key))
    return
  }
  item.quantity = Number(quantity.toFixed(3))
  writeCart(items)
}

export function removeCartItem(key: string) {
  writeCart(readCart().filter((item) => item.key !== key))
}

export function clearCart() {
  writeCart([])
}

export const CART_OPEN_EVENT = 'balout:cart-open'

export type CartOpenDetail = {
  step?: 1 | 2 | 3
}

export function openCartDrawer(step: 1 | 2 | 3 = 1) {
  window.dispatchEvent(
    new CustomEvent<CartOpenDetail>(CART_OPEN_EVENT, { detail: { step } }),
  )
}

/** Login should send users back here to continue checkout. */
export function getCartCheckoutReturnUrl() {
  const url = new URL(window.location.origin)
  url.searchParams.set('cart', 'checkout')
  return url.toString()
}

export function cartItemUnitPrice(item: CartItem) {
  const optionsTotal = item.options.reduce((sum, option) => sum + option.price, 0)
  return item.basePrice + optionsTotal
}

export function cartItemLineTotal(item: CartItem) {
  return Math.round(cartItemUnitPrice(item) * item.quantity)
}

export function addToCart(input: {
  product: Product
  quantity: number
  options?: ProductOptionValue[]
}) {
  const options = (input.options ?? []).map((option) => ({
    id: option.id,
    name: optionLabel(option),
    price: option.price,
  }))
  const key = itemKey(
    input.product.id,
    options.map((option) => option.id),
  )
  const items = readCart()
  const existing = items.find((item) => item.key === key)
  if (existing) {
    existing.quantity = Number((existing.quantity + input.quantity).toFixed(3))
  } else {
    items.push({
      key,
      productId: input.product.id,
      nameFa: input.product.nameFa,
      imageUrl: input.product.mainImageUrl,
      sellUnit: input.product.sellUnit,
      basePrice: input.product.price,
      quantity: input.quantity,
      options,
    })
  }
  writeCart(items)

  const optionsHint =
    options.length > 0
      ? options.map((option) => option.name).join('، ')
      : undefined
  showToast({
    message: `${input.product.nameFa} به سبد خرید اضافه شد`,
    detail: optionsHint
      ? `${optionsHint} — ${formatPriceFa(input.quantity)} ${input.product.sellUnit === 'kilo' ? 'کیلو' : 'عدد'}`
      : `${formatPriceFa(input.quantity)} ${input.product.sellUnit === 'kilo' ? 'کیلو' : 'عدد'}`,
  })
}

export function showToast(payload: ToastPayload) {
  window.dispatchEvent(new CustomEvent(TOAST_EVENT, { detail: payload }))
}

export function subscribeCart(listener: () => void) {
  const handler = () => listener()
  window.addEventListener(CART_EVENT, handler)
  window.addEventListener('storage', handler)
  return () => {
    window.removeEventListener(CART_EVENT, handler)
    window.removeEventListener('storage', handler)
  }
}
