import { useState } from 'preact/hooks'
import { Img } from '../atoms/img.js'
import { Link } from '../atoms/link.js'
import { ValidationError } from '../routing/error-handler.js'
import h from '../shared/h.js'

const DEFAULT_UNIT = '100 g'

export function PromoProductCard ({ _model, ...props }) {
  const {
    title,
    links,
    image,
    brand,
    offerLabel,
    eta,
    price,
    oldPrice,
    currency = '\u20b9',
    initialQuantity,
    maxQuantity
  } = _model

  if (!title || !image?.src) {
    throw new ValidationError()
  }

  const productLink = links?.[0]?.value
  const units = getUnitOptions(_model)
  const [selectedUnit, setSelectedUnit] = useState(units[0]?.value || DEFAULT_UNIT)
  const [quantity, setQuantity] = useState(Math.max(0, Number.parseInt(initialQuantity ?? 0, 10) || 0))
  const maxQty = Number.parseInt(maxQuantity, 10)
  const unitId = `promo-product-unit-${slugify(title)}`

  const onDecrease = () => setQuantity(current => Math.max(0, current - 1))
  const onIncrease = () => {
    setQuantity(current => {
      if (Number.isFinite(maxQty) && current >= maxQty) {
        return current
      }

      return current + 1
    })
  }

  const etaLabel = eta || '12 mins'
  const addLabel = 'Add'

  return h('article', {
    ...props,
    className: 'w-full h-full min-w-0 bg-bga text-txa border border-txa/20 rounded-md p-1.5 shadow-sm space-y-1',
    _style: id => `
      @media (min-width: 1024px) {
        ${id} { padding: 10px; gap: 6px; }
        ${id} [data-ppc='offer'] { font-size: 12px; }
        ${id} [data-ppc='eta'] { font-size: 12px; padding: 3px 6px; }
        ${id} [data-ppc='brand'] { font-size: 12px; }
        ${id} [data-ppc='title'] { font-size: 14px; line-height: 1.25; }
        ${id} [data-ppc='unit'] { font-size: 13px; padding: 5px 8px; }
        ${id} [data-ppc='price'] { font-size: 16px; }
        ${id} [data-ppc='old-price'] { font-size: 12px; }
        ${id} [data-ppc='add'] { font-size: 12px; padding: 4px 8px; }
        ${id} [data-ppc='qty-btn'] { width: 28px; height: 28px; font-size: 18px; }
        ${id} [data-ppc='qty-val'] { font-size: 12px; min-width: 28px; }
      }
    `
  },
  h('div', { className: 'relative rounded-md border border-txa/15 overflow-hidden bg-bgb/10' },
    h(Link, {
      _model: { value: productLink, name: title },
      target: '_blank',
      className: 'block'
    },
    h(Img, {
      _model: image,
      _fit: 'contain',
      className: 'w-full bg-bga',
      style: 'aspect-ratio: 1 / 1;'
    })
    ),
    offerLabel && h('div', { className: 'absolute top-1 left-1 bg-bgb text-txb rounded-sm px-1 py-0.5 text-xs font-bold leading-none', 'data-ppc': 'offer' }, offerLabel)
  ),

  h('div', { className: 'inline-flex items-center rounded-sm bg-txa/10 text-txa/80 px-1 py-0.5 text-xs font-semibold uppercase leading-none', 'data-ppc': 'eta' }, etaLabel),

  h('div', { className: 'space-y-0.5 min-h-8' },
    brand && h('div', { className: 'text-xs font-bold uppercase opacity-80 leading-tight truncate', 'data-ppc': 'brand' }, brand),
    h(Link, {
      _model: { value: productLink, name: title },
      target: '_blank',
      className: 'block font-semibold leading-tight text-xs',
      'data-ppc': 'title'
    },
    title
    )
  ),

  h('div', { className: 'flex items-center gap-1' },
    h('label', { className: 'sr-only', for: unitId }, 'Unit selector'),
    h('select', {
      id: unitId,
      value: selectedUnit,
      onChange (event) {
        setSelectedUnit(event.currentTarget.value)
      },
      className: 'w-full rounded-sm border border-txa/30 bg-bga text-txa px-1.5 py-1 text-xs leading-tight',
      'data-ppc': 'unit'
    }, units.map(option => h('option', { value: option.value }, option.label)))
  ),

  h('div', { className: 'flex items-end justify-between gap-1' },
    h('div', { className: 'flex items-center gap-1 min-w-0' },
      h('span', { className: 'text-sm font-bold leading-none whitespace-nowrap', 'data-ppc': 'price' }, formatPrice(price, currency)),
      oldPrice && h('span', { className: 'text-xs line-through opacity-60 leading-none whitespace-nowrap', 'data-ppc': 'old-price' }, formatPrice(oldPrice, currency))
    ),

    quantity === 0
      ? h('button', {
        type: 'button',
        className: 'clickable inline-flex items-center gap-0.5 rounded-sm border border-bgb bg-bgb text-txb px-1.5 py-0.5 text-xs font-bold transition hover:bg-txb hover:text-bgb whitespace-nowrap',
        onClick: onIncrease,
        'aria-label': 'Add item',
        'data-ppc': 'add'
      },
      h('span', { 'aria-hidden': true }, '+'),
      addLabel
      )
      : h('div', {
        className: 'inline-flex items-center rounded-sm border border-bgb overflow-hidden',
        role: 'group',
        'aria-label': 'Quantity selector'
      },
      h('button', {
        type: 'button',
        className: 'clickable bg-bgb text-txb w-6 h-6 text-base leading-none font-bold',
        onClick: onDecrease,
        'aria-label': 'Decrease quantity',
        'data-ppc': 'qty-btn'
      }, '-'),
      h('span', { className: 'px-1.5 min-w-6 text-center text-xs font-semibold', 'data-ppc': 'qty-val' }, quantity),
      h('button', {
        type: 'button',
        className: 'clickable bg-bgb text-txb w-6 h-6 text-base leading-none font-bold',
        onClick: onIncrease,
        'aria-label': 'Increase quantity',
        'data-ppc': 'qty-btn'
      }, '+')
      )
  )
  )
}

function getUnitOptions (model) {
  const raw = model.units || model.sizes || model.options || model.tags?.map(tag => tag.value)

  if (!Array.isArray(raw) || raw.length === 0) {
    return [{ label: model.unit || DEFAULT_UNIT, value: model.unit || DEFAULT_UNIT }]
  }

  return raw.map((option, index) => {
    if (typeof option === 'string') {
      return { label: option, value: option }
    }

    const label = option?.name || option?.label || option?.value || `${DEFAULT_UNIT}-${index + 1}`
    const value = option?.value || label
    return { label, value }
  })
}

function formatPrice (value, currency) {
  if (typeof value === 'number') {
    return `${currency}${value.toFixed(2)}`
  }

  if (typeof value === 'string' && value.length > 0) {
    return value
  }

  return `${currency}0.00`
}

function slugify (value) {
  return String(value || 'item').toLowerCase().replaceAll(/[^a-z0-9]+/g, '-').replaceAll(/(^-|-$)/g, '')
}