import { useEffect, useState } from 'react'
import { createPortal } from 'react-dom'
import { X } from 'lucide-react'
import { ApiError } from '../lib/api'
import {
  updateStoreItemFestivalRewards,
  type StoreItem,
} from '../services/storeItemService'
import { createId } from '../utils/id'
import modalStyles from './VariationsModal.module.css'
import rowStyles from './CreateStoreItemsModal.module.css'

interface StoreItemFestivalModalProps {
  open: boolean
  productTitle: string
  items: StoreItem[]
  onClose: () => void
  onSaved?: (items: StoreItem[]) => void
}

interface FestivalDraftRow {
  id: string
  itemId: string
  label: string
  rewardPoints: string
}

const ANIMATION_MS = 220

export function StoreItemFestivalModal({
  open,
  productTitle,
  items,
  onClose,
  onSaved,
}: StoreItemFestivalModalProps) {
  const [mounted, setMounted] = useState(open)
  const [closing, setClosing] = useState(false)
  const [rows, setRows] = useState<FestivalDraftRow[]>([])
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [error, setError] = useState('')

  useEffect(() => {
    if (open) {
      setMounted(true)
      setClosing(false)
      setRows(
        items.map((item) => ({
          id: createId(),
          itemId: item.id,
          label: item.label,
          rewardPoints:
            item.rewardPoints !== null && item.rewardPoints !== undefined
              ? String(item.rewardPoints)
              : '',
        })),
      )
      setError('')
    } else if (mounted) {
      setClosing(true)
      const timer = setTimeout(() => {
        setMounted(false)
        setClosing(false)
      }, ANIMATION_MS)
      return () => clearTimeout(timer)
    }
  }, [open, mounted, items])

  useEffect(() => {
    if (!mounted || closing) return
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose()
    }
    document.addEventListener('keydown', onKey)
    return () => document.removeEventListener('keydown', onKey)
  }, [mounted, closing, onClose])

  if (!mounted || items.length === 0) return null

  const productId = items[0]?.productId ?? ''

  const canSubmit =
    !isSubmitting &&
    rows.every((row) => {
      if (!row.rewardPoints.trim()) return true
      const value = Number(row.rewardPoints)
      return !Number.isNaN(value) && value >= 0 && Number.isInteger(value)
    })

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    if (!canSubmit || !productId) return

    setIsSubmitting(true)
    setError('')

    try {
      const data = await updateStoreItemFestivalRewards({
        productId,
        items: rows.map((row) => ({
          id: row.itemId,
          rewardPoints: row.rewardPoints.trim() ? Number(row.rewardPoints) : null,
        })),
      })
      onSaved?.(data.items)
      onClose()
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError('Unable to save festival reward points.')
      }
    } finally {
      setIsSubmitting(false)
    }
  }

  return createPortal(
    <div
      className={`${modalStyles.overlay} ${closing ? modalStyles.overlayOut : modalStyles.overlayIn}`}
      onClick={onClose}
    >
      <div
        className={`${modalStyles.modal} ${rowStyles.modalCompact} ${closing ? modalStyles.modalOut : modalStyles.modalIn}`}
        onClick={(e) => e.stopPropagation()}
        role="dialog"
        aria-modal="true"
        aria-labelledby="store-festival-title"
      >
        <div className={`${modalStyles.header} ${modalStyles.headerWithHint}`}>
          <div>
            <h3 id="store-festival-title" className={modalStyles.title}>
              Festival Reward Points
            </h3>
            <p className={modalStyles.subtitle}>{productTitle}</p>
            <p className={modalStyles.modalHint}>
              Set how many reward points customers earn when buying each variant. Redemption comes
              later.
            </p>
          </div>
          <button className={modalStyles.closeBtn} onClick={onClose} aria-label="Close">
            <X size={20} />
          </button>
        </div>

        <form
          className={`${modalStyles.body} ${modalStyles.bodyCompactTop}`}
          onSubmit={(e) => void handleSubmit(e)}
        >
          <div className={rowStyles.discountHeaderFestival}>
            <span>Variant</span>
            <span>Reward points</span>
          </div>

          <div className={`${rowStyles.discountRows} ${rowStyles.discountRowsCompact}`}>
            {rows.map((row) => (
              <div key={row.id} className={rowStyles.discountRowFestival}>
                <span className={rowStyles.discountLabel}>{row.label}</span>
                <input
                  type="number"
                  min="0"
                  step="1"
                  className={rowStyles.compactInput}
                  value={row.rewardPoints}
                  onChange={(e) =>
                    setRows((prev) =>
                      prev.map((entry) =>
                        entry.id === row.id ? { ...entry, rewardPoints: e.target.value } : entry,
                      ),
                    )
                  }
                  placeholder="No points"
                  disabled={isSubmitting}
                />
              </div>
            ))}
          </div>

          {error && <p className={modalStyles.errorText}>{error}</p>}

          <div className={modalStyles.actions}>
            <button
              type="button"
              className={modalStyles.cancelBtn}
              onClick={onClose}
              disabled={isSubmitting}
            >
              Cancel
            </button>
            <button type="submit" className={modalStyles.submitBtn} disabled={!canSubmit}>
              {isSubmitting ? 'Saving…' : 'Save reward points'}
            </button>
          </div>
        </form>
      </div>
    </div>
  ,
  document.body,
  )
}
