import { useEffect, useState } from 'react'
import { createPortal } from 'react-dom'
import { Plus, X } from 'lucide-react'
import type { Variation, VariationType } from '../types/variation'
import { createId } from '../utils/id'
import { textLocaleAttrs } from '../utils/textLocale'
import { AddVariationModal } from './AddVariationModal'
import styles from './VariationsModal.module.css'

interface VariationsModalProps {
  open: boolean
  categoryName: string
  variations: Variation[]
  isSaving?: boolean
  onClose: () => void
  onChange: (variations: Variation[]) => void
  onSave: () => void
}

const ANIMATION_MS = 220

export function VariationsModal({
  open,
  categoryName,
  variations,
  isSaving = false,
  onClose,
  onChange,
  onSave,
}: VariationsModalProps) {
  const [mounted, setMounted] = useState(open)
  const [closing, setClosing] = useState(false)
  const [addOpen, setAddOpen] = useState(false)

  useEffect(() => {
    if (open) {
      setMounted(true)
      setClosing(false)
    } else if (mounted) {
      setClosing(true)
      const timer = setTimeout(() => {
        setMounted(false)
        setClosing(false)
        setAddOpen(false)
      }, ANIMATION_MS)
      return () => clearTimeout(timer)
    }
  }, [open, mounted])

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

  if (!mounted) return null

  const list = variations
  const categoryLocale = textLocaleAttrs(categoryName)

  function handleAdd(variation: Omit<Variation, 'id'>) {
    onChange([
      ...list,
      { ...variation, id: createId() },
    ])
    setAddOpen(false)
  }

  function handleRemove(id: string) {
    onChange(list.filter((variation) => variation.id !== id))
  }

  function typeLabel(type: VariationType) {
    if (type === 'color') return 'Color'
    if (type === 'size') return 'Size'
    return 'Custom'
  }

  return createPortal(
    <>
      <div
        className={`${styles.overlay} ${closing ? styles.overlayOut : styles.overlayIn}`}
        onClick={onClose}
      >
        <div
          className={`${styles.modal} ${closing ? styles.modalOut : styles.modalIn}`}
          onClick={(e) => e.stopPropagation()}
          role="dialog"
          aria-modal="true"
          aria-labelledby="variations-modal-title"
        >
          <div className={styles.header}>
            <div>
              <h3 id="variations-modal-title" className={styles.title}>
                Variations
              </h3>
              {categoryName && (
                <p
                  className={[styles.subtitle, categoryLocale.className].filter(Boolean).join(' ')}
                  lang={categoryLocale.lang}
                  dir={categoryLocale.dir}
                >
                  {categoryName}
                </p>
              )}
            </div>
            <button className={styles.closeBtn} onClick={onClose} aria-label="Close">
              <X size={20} />
            </button>
          </div>

          <div className={styles.body}>
            <div className={styles.list}>
              {list.map((variation) => {
                const nameLocale = textLocaleAttrs(variation.name)
                const valuesText = variation.values.join(' · ') || 'No values'
                const valuesLocale = textLocaleAttrs(valuesText)
                return (
                <div key={variation.id} className={styles.listItem}>
                  <div className={styles.listItemInfo}>
                    <div
                      className={[styles.listItemName, nameLocale.className].filter(Boolean).join(' ')}
                      lang={nameLocale.lang}
                      dir={nameLocale.dir}
                    >
                      {variation.name}
                    </div>
                    <div
                      className={[styles.listItemValues, valuesLocale.className].filter(Boolean).join(' ')}
                      lang={valuesLocale.lang}
                      dir={valuesLocale.dir}
                    >
                      {valuesText}
                    </div>
                  </div>
                  <div className={styles.listItemEnd}>
                    <span className={styles.listItemType}>{typeLabel(variation.type)}</span>
                    <button
                      type="button"
                      className={styles.removeRowBtn}
                      onClick={() => handleRemove(variation.id)}
                      aria-label={`Remove ${variation.name}`}
                    >
                      <X size={16} />
                    </button>
                  </div>
                </div>
                )
              })}
              {!list.length && (
                <p className={styles.emptyText}>No variations yet. Add color, size, or custom options.</p>
              )}
            </div>

            <button type="button" className={styles.addBtn} onClick={() => setAddOpen(true)}>
              <Plus size={18} />
              Add Variation
            </button>

            <div className={styles.actions}>
              <button type="button" className={styles.cancelBtn} onClick={onClose} disabled={isSaving}>
                Cancel
              </button>
              <button type="button" className={styles.submitBtn} onClick={onSave} disabled={isSaving}>
                {isSaving ? 'Saving…' : 'Save variations'}
              </button>
            </div>
          </div>
        </div>
      </div>

      <AddVariationModal
        open={addOpen}
        onClose={() => setAddOpen(false)}
        onSubmit={handleAdd}
      />
    </>,
    document.body,
  )
}
