import { useEffect, useMemo, useState } from 'react'
import { createPortal } from 'react-dom'
import { Sparkles, X } from 'lucide-react'
import { useToast } from '../context/ToastContext'
import { ApiError } from '../lib/api'
import { listProductCategories, mapProductCategoryToUi } from '../services/productCategoryService'
import { createProductByAi, type ProductAiLanguage } from '../services/productAiService'
import type { Category } from '../types/category'
import { flattenCategories } from '../utils/categories'
import { SearchableSelect } from './SearchableSelect'
import modalStyles from './CategoryModal.module.css'
import aiStyles from '../styles/ai.module.css'
import styles from './AddProductByAiModal.module.css'
import fieldStyles from '../pages/AddNewProductPage.module.css'

interface AddProductByAiModalProps {
  open: boolean
  onClose: () => void
  onCreated: (productId: string) => void
}

const ANIMATION_MS = 220

export function AddProductByAiModal({
  open,
  onClose,
  onCreated,
}: AddProductByAiModalProps) {
  const { showToast } = useToast()
  const [mounted, setMounted] = useState(open)
  const [closing, setClosing] = useState(false)
  const [categories, setCategories] = useState<Category[]>([])
  const [categoryId, setCategoryId] = useState('')
  const [name, setName] = useState('')
  const [language, setLanguage] = useState<ProductAiLanguage>('en')
  const [isLoadingCategories, setIsLoadingCategories] = useState(false)
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [error, setError] = useState('')

  const categoryOptions = useMemo(() => flattenCategories(categories), [categories])

  useEffect(() => {
    if (open) {
      setMounted(true)
      setClosing(false)
      setCategoryId('')
      setName('')
      setLanguage('en')
      setError('')
    } else if (mounted) {
      setClosing(true)
      const timer = setTimeout(() => {
        setMounted(false)
        setClosing(false)
      }, ANIMATION_MS)
      return () => clearTimeout(timer)
    }
  }, [open, mounted])

  useEffect(() => {
    if (!open) return

    const controller = new AbortController()
    void loadCategories(controller.signal)
    return () => controller.abort()
  }, [open])

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

  async function loadCategories(signal?: AbortSignal) {
    setIsLoadingCategories(true)
    setError('')

    try {
      const items = await listProductCategories(signal)
      setCategories(items.map(mapProductCategoryToUi))
    } catch (err) {
      if (err instanceof DOMException && err.name === 'AbortError') return
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError('Unable to load categories.')
      }
    } finally {
      setIsLoadingCategories(false)
    }
  }

  async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault()
    if (!categoryId || !name.trim()) return

    setIsSubmitting(true)
    setError('')

    try {
      const result = await createProductByAi({
        categoryId,
        name: name.trim(),
        language,
      })
      showToast(result.message, 'success')
      onCreated(result.product.id)
      onClose()
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else if (err instanceof Error) {
        setError(err.message)
      } else {
        setError('Unable to create product with AI.')
      }
    } finally {
      setIsSubmitting(false)
    }
  }

  if (!mounted) return null

  return createPortal(
    <div
      className={`${modalStyles.overlay} ${closing ? modalStyles.overlayOut : modalStyles.overlayIn}`}
      onClick={(e) => e.target === e.currentTarget && !isSubmitting && onClose()}
      role="presentation"
    >
      <div
        className={`${modalStyles.modal} ${closing ? modalStyles.modalOut : modalStyles.modalIn}`}
        role="dialog"
        aria-modal="true"
        aria-labelledby="add-product-ai-title"
      >
        <div className={`${modalStyles.header} ${styles.header}`}>
          <div className={styles.headerBlock}>
            <h2 id="add-product-ai-title" className={modalStyles.title}>
              Add Product by AI
            </h2>
            <p className={styles.subtitle}>
              AI will generate product content and technical data. You can add images and
              variations afterward.
            </p>
          </div>
          <button
            type="button"
            className={modalStyles.closeBtn}
            onClick={onClose}
            disabled={isSubmitting}
            aria-label="Close"
          >
            <X size={20} />
          </button>
        </div>

        <form className={modalStyles.form} onSubmit={(e) => void handleSubmit(e)}>
          <div className={modalStyles.field}>
            <label>Category</label>
            <SearchableSelect
              options={categoryOptions}
              value={categoryId}
              onChange={setCategoryId}
              placeholder="Search and select category..."
            />
          </div>

          <div className={modalStyles.field}>
            <label htmlFor="ai-product-name">Product name</label>
            <input
              id="ai-product-name"
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder={
                language === 'fa' ? 'نام محصول را وارد کنید' : 'Enter product name'
              }
              dir={language === 'fa' ? 'rtl' : 'ltr'}
              className={language === 'fa' ? 'faText' : undefined}
              disabled={isSubmitting}
              required
            />
          </div>

          <div className={`${modalStyles.field} ${fieldStyles.field}`}>
            <label htmlFor="ai-product-language">Language</label>
            <select
              id="ai-product-language"
              value={language}
              onChange={(e) => setLanguage(e.target.value as ProductAiLanguage)}
              disabled={isSubmitting}
            >
              <option value="en">English</option>
              <option value="fa">Persian (Farsi)</option>
            </select>
          </div>

          {error && <p className={styles.error}>{error}</p>}

          <div className={modalStyles.actions}>
            <button
              type="button"
              className={modalStyles.cancelBtn}
              onClick={onClose}
              disabled={isSubmitting}
            >
              Cancel
            </button>
            <button
              type="submit"
              className={aiStyles.aiBtn}
              disabled={
                isSubmitting || isLoadingCategories || !categoryId || !name.trim()
              }
            >
              {isSubmitting ? (
                <>
                  <Sparkles size={16} />
                  Creating...
                </>
              ) : (
                <>
                  <Sparkles size={16} />
                  Create product
                </>
              )}
            </button>
          </div>
        </form>
      </div>
    </div>
  ,
  document.body,
  )
}
