import type { WooAppliedCoupon, WooCart, WooCartItem } from '@/types'

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null
}

function toNumber(value: unknown): number | null {
  if (typeof value === 'number' && Number.isFinite(value)) {
    return value
  }

  if (typeof value === 'string') {
    const trimmed = value.trim()
    if (!trimmed) {
      return null
    }

    const parsed = Number(trimmed.replace(/,/g, ''))
    return Number.isFinite(parsed) ? parsed : null
  }

  return null
}

function toInteger(value: unknown): number | null {
  const parsed = toNumber(value)
  if (parsed === null) {
    return null
  }

  return Math.trunc(parsed)
}

function toStringValue(value: unknown, fallback = ''): string {
  return typeof value === 'string' ? value : fallback
}

function normalizeCartItem(raw: unknown): WooCartItem | null {
  if (!isRecord(raw)) {
    return null
  }

  const key = toStringValue(raw.key).trim()
  if (!key) {
    return null
  }

  const quantity = Math.max(0, toInteger(raw.quantity) ?? 0)
  if (quantity <= 0) {
    return null
  }

  return {
    key,
    id: Math.max(0, toInteger(raw.id) ?? 0),
    variation_id: Math.max(0, toInteger(raw.variation_id) ?? 0),
    name: toStringValue(raw.name),
    quantity,
    price: toStringValue(raw.price, '0'),
    price_display: toStringValue(raw.price_display, toStringValue(raw.price, '0')),
    subtotal: toStringValue(raw.subtotal, '0'),
    subtotal_display: toStringValue(raw.subtotal_display, toStringValue(raw.subtotal, '0')),
    image: typeof raw.image === 'string' || raw.image === null ? raw.image : null,
    product_url: toStringValue(raw.product_url),
  }
}

function normalizeAppliedCoupon(raw: unknown): WooAppliedCoupon | null {
  if (!isRecord(raw)) {
    return null
  }

  const code = toStringValue(raw.code).trim()
  if (!code) {
    return null
  }

  return {
    code,
    discount_total: typeof raw.discount_total === 'string' ? raw.discount_total : undefined,
    discount_total_display: typeof raw.discount_total_display === 'string' ? raw.discount_total_display : undefined,
    free_shipping: typeof raw.free_shipping === 'boolean' ? raw.free_shipping : undefined,
  }
}

export function getWooCartCount(cart: Pick<WooCart, 'count' | 'items'> | null | undefined): number {
  if (!cart) {
    return 0
  }

  const rawCount = typeof cart.count === 'number' && Number.isFinite(cart.count) ? cart.count : 0
  const quantityCount = Array.isArray(cart.items)
    ? cart.items.reduce((sum, item) => sum + (Number.isFinite(item.quantity) ? item.quantity : 0), 0)
    : 0

  return Math.max(rawCount, quantityCount)
}

export function normalizeWooCart(raw: unknown): WooCart | null {
  if (!isRecord(raw)) {
    return null
  }

  const items = Array.isArray(raw.items)
    ? raw.items.map(normalizeCartItem).filter((item): item is WooCartItem => item !== null)
    : []

  const appliedCoupons = Array.isArray(raw.applied_coupons)
    ? raw.applied_coupons
      .map(normalizeAppliedCoupon)
      .filter((coupon): coupon is WooAppliedCoupon => coupon !== null)
    : []

  const quantityCount = items.reduce((sum, item) => sum + item.quantity, 0)
  const rawCount = Math.max(0, toInteger(raw.count) ?? 0)
  const count = Math.max(rawCount, quantityCount)
  const isEmpty = items.length === 0 || count <= 0

  return {
    count,
    subtotal: toStringValue(raw.subtotal, '0'),
    subtotal_amount: typeof raw.subtotal_amount === 'string' ? raw.subtotal_amount : undefined,
    total: toStringValue(raw.total, '0'),
    total_amount: typeof raw.total_amount === 'string' ? raw.total_amount : undefined,
    discount_total: typeof raw.discount_total === 'string' ? raw.discount_total : undefined,
    discount_total_display: typeof raw.discount_total_display === 'string' ? raw.discount_total_display : undefined,
    currency_code: typeof raw.currency_code === 'string' ? raw.currency_code : undefined,
    currency_symbol: typeof raw.currency_symbol === 'string' ? raw.currency_symbol : undefined,
    applied_coupons: appliedCoupons,
    items,
    checkout_url: toStringValue(raw.checkout_url),
    cart_url: toStringValue(raw.cart_url),
    is_empty: isEmpty,
  }
}

export function cartDebugLog(message: string, payload?: unknown) {
  if (payload === undefined) {
    console.info(`[BoostBot][Cart] ${message}`)
    return
  }

  console.info(`[BoostBot][Cart] ${message}`, payload)
}
