import { useEffect, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
import { Plus, X } from 'lucide-react'
import type { Variation, VariationType } from '../types/variation'
import { COLOR_OPTIONS, SIZE_OPTIONS } from '../types/variation'
import styles from './VariationsModal.module.css'

interface AddVariationModalProps {
  open: boolean
  onClose: () => void
  onSubmit: (variation: Omit<Variation, 'id'>) => void
}

const ANIMATION_MS = 220

export function AddVariationModal({ open, onClose, onSubmit }: AddVariationModalProps) {
  const [mounted, setMounted] = useState(open)
  const [closing, setClosing] = useState(false)
  const [type, setType] = useState<VariationType>('color')
  const [customName, setCustomName] = useState('')
  const [selectedColors, setSelectedColors] = useState<string[]>([])
  const [selectedSizes, setSelectedSizes] = useState<string[]>([])
  const [customValues, setCustomValues] = useState<string[]>([''])
  const valueInputRefs = useRef<(HTMLInputElement | null)[]>([])
  const pendingFocusIndex = useRef<number | null>(null)

  useEffect(() => {
    if (pendingFocusIndex.current === null) return
    valueInputRefs.current[pendingFocusIndex.current]?.focus()
    pendingFocusIndex.current = null
  }, [customValues.length])

  useEffect(() => {
    if (open) {
      setMounted(true)
      setClosing(false)
      setType('color')
      setCustomName('')
      setSelectedColors([])
      setSelectedSizes([])
      setCustomValues([''])
    } else if (mounted) {
      setClosing(true)
      const timer = setTimeout(() => {
        setMounted(false)
        setClosing(false)
      }, ANIMATION_MS)
      return () => clearTimeout(timer)
    }
  }, [open, mounted])

  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) return null

  function toggleOption(value: string, selected: string[], setSelected: (v: string[]) => void) {
    setSelected(
      selected.includes(value)
        ? selected.filter((v) => v !== value)
        : [...selected, value],
    )
  }

  function updateCustomValue(index: number, value: string) {
    setCustomValues((prev) => prev.map((v, i) => (i === index ? value : v)))
  }

  function addCustomRow() {
    setCustomValues((prev) => [...prev, ''])
  }

  function removeCustomRow(index: number) {
    setCustomValues((prev) => prev.filter((_, i) => i !== index))
  }

  function handleValueKeyDown(index: number, e: React.KeyboardEvent<HTMLInputElement>) {
    if (e.key !== 'Enter') return
    e.preventDefault()

    const nextIndex = index + 1
    if (nextIndex < customValues.length) {
      valueInputRefs.current[nextIndex]?.focus()
      return
    }

    pendingFocusIndex.current = nextIndex
    setCustomValues((prev) => [...prev, ''])
  }

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault()

    if (type === 'color') {
      onSubmit({ name: 'Color', type: 'color', values: selectedColors })
    } else if (type === 'size') {
      onSubmit({ name: 'Size', type: 'size', values: selectedSizes })
    } else {
      const name = customName.trim() || 'Custom'
      const values = customValues.map((v) => v.trim()).filter(Boolean)
      onSubmit({ name, type: 'custom', values })
    }
  }

  const canSubmit =
    type === 'color'
      ? selectedColors.length > 0
      : type === 'size'
        ? selectedSizes.length > 0
        : customValues.some((v) => v.trim())

  return createPortal(
    <div
      className={`${styles.overlay} ${styles.overlayNested} ${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="add-variation-title"
      >
        <div className={styles.header}>
          <h3 id="add-variation-title" className={styles.title}>
            Add Variation
          </h3>
          <button className={styles.closeBtn} onClick={onClose} aria-label="Close">
            <X size={20} />
          </button>
        </div>

        <form className={styles.body} onSubmit={handleSubmit}>
          <div className={styles.field}>
            <label htmlFor="variationType">Type</label>
            <select
              id="variationType"
              value={type}
              onChange={(e) => setType(e.target.value as VariationType)}
            >
              <option value="color">Color</option>
              <option value="size">Size</option>
              <option value="custom">Your own</option>
            </select>
          </div>

          {type === 'color' && (
            <div className={styles.field}>
              <label>Select colors</label>
              <div className={styles.chipGrid}>
                {COLOR_OPTIONS.map((color) => (
                  <button
                    key={color}
                    type="button"
                    className={`${styles.chip} ${selectedColors.includes(color) ? styles.chipSelected : ''}`}
                    onClick={() => toggleOption(color, selectedColors, setSelectedColors)}
                  >
                    {color}
                  </button>
                ))}
              </div>
            </div>
          )}

          {type === 'size' && (
            <div className={styles.field}>
              <label>Select sizes</label>
              <div className={styles.chipGrid}>
                {SIZE_OPTIONS.map((size) => (
                  <button
                    key={size}
                    type="button"
                    className={`${styles.chip} ${selectedSizes.includes(size) ? styles.chipSelected : ''}`}
                    onClick={() => toggleOption(size, selectedSizes, setSelectedSizes)}
                  >
                    {size}
                  </button>
                ))}
              </div>
            </div>
          )}

          {type === 'custom' && (
            <>
              <div className={styles.field}>
                <label htmlFor="customName">Variation name</label>
                <input
                  id="customName"
                  type="text"
                  placeholder="e.g. Guarantee, Material..."
                  value={customName}
                  onChange={(e) => setCustomName(e.target.value)}
                />
              </div>
              <div className={styles.field}>
                <label>Values</label>
                <div className={styles.customValues}>
                  {customValues.map((value, index) => (
                    <div key={index} className={styles.customRow}>
                      <input
                        ref={(el) => {
                          valueInputRefs.current[index] = el
                        }}
                        type="text"
                        placeholder={`Value ${index + 1}`}
                        value={value}
                        onChange={(e) => updateCustomValue(index, e.target.value)}
                        onKeyDown={(e) => handleValueKeyDown(index, e)}
                      />
                      {customValues.length > 1 && (
                        <button
                          type="button"
                          className={styles.removeValueBtn}
                          onClick={() => removeCustomRow(index)}
                          aria-label="Remove value"
                        >
                          <X size={16} />
                        </button>
                      )}
                    </div>
                  ))}
                  <button type="button" className={styles.addValueBtn} onClick={addCustomRow}>
                    <Plus size={14} />
                    Add value
                  </button>
                </div>
              </div>
            </>
          )}

          <div className={styles.actions}>
            <button type="button" className={styles.cancelBtn} onClick={onClose}>
              Cancel
            </button>
            <button type="submit" className={styles.submitBtn} disabled={!canSubmit}>
              Add
            </button>
          </div>
        </form>
      </div>
    </div>,
    document.body,
  )
}
