import { useEffect, useMemo, useState } from 'react'
import { Link, useParams, useNavigate } from 'react-router-dom'
import { Sparkles } from 'lucide-react'
import { SearchableSelect } from '../components/SearchableSelect'
import { ImageCropper } from '../components/ImageCropper'
import { ImageUploader } from '../components/ImageUploader'
import { TagInput } from '../components/TagInput'
import { RichTextEditor } from '../components/RichTextEditor'
import { Breadcrumbs } from '../components/Breadcrumbs'
import { ProductFieldAiPromptModal } from '../components/ProductFieldAiPromptModal'
import { Tooltip } from '../components/Tooltip'
import { useToast } from '../context/ToastContext'
import { ApiError } from '../lib/api'
import { listProductCategories, mapProductCategoryToUi } from '../services/productCategoryService'
import { listAllBrands, mapBrandToSelectOption } from '../services/brandService'
import {
  resolveDataUrlToMediaId,
  resolveDataUrlsToMediaIds,
} from '../services/mediaService'
import {
  createProduct,
  getProduct,
  mapProductApiToFormState,
  updateProduct,
} from '../services/productService'
import {
  fillProductFieldByAi,
  type ProductAiFillField,
} from '../services/productAiService'
import type { Category, FlatCategory } from '../types/category'
import { flattenCategories } from '../utils/categories'
import pageStyles from '../components/PageContent.module.css'
import aiStyles from '../styles/ai.module.css'
import styles from './AddNewProductPage.module.css'
import { useT } from '../i18n/useT'

export function AddNewProductPage() {
  const { id } = useParams()
  const navigate = useNavigate()
  const t = useT()
  const { showToast } = useToast()
  const isEdit = Boolean(id)

  const [categories, setCategories] = useState<Category[]>([])
  const [brandOptions, setBrandOptions] = useState<FlatCategory[]>([])
  const [categoryId, setCategoryId] = useState('')
  const [brandId, setBrandId] = useState('')
  const [nameFa, setNameFa] = useState('')
  const [nameEn, setNameEn] = useState('')
  const [summary, setSummary] = useState('')
  const [description, setDescription] = useState('')
  const [thumbnail, setThumbnail] = useState<string | null>(null)
  const [images, setImages] = useState<string[]>([])
  const [tags, setTags] = useState<string[]>([])
  const [thumbnailMediaId, setThumbnailMediaId] = useState<string | null>(null)
  const [galleryMediaIds, setGalleryMediaIds] = useState<string[]>([])
  const [loaded, setLoaded] = useState(!isEdit)
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [error, setError] = useState('')
  const [aiField, setAiField] = useState<ProductAiFillField | null>(null)
  const [isAiRunning, setIsAiRunning] = useState(false)

  const categoryOptions = flattenCategories(categories)
  const selectedCategoryName = useMemo(() => {
    const match = categoryOptions.find((item) => item.id === categoryId)
    if (!match) return ''
    return match.nameFa?.trim() || match.nameEn || ''
  }, [categoryOptions, categoryId])

  const canUseAiFill = Boolean(nameFa.trim() || nameEn.trim()) && !isSubmitting

  function openAiFill(field: ProductAiFillField) {
    if (!nameFa.trim() && !nameEn.trim()) {
      setError(t('products.form.aiFillNeedName'))
      return
    }
    setError('')
    setAiField(field)
  }

  async function runAiFill(prompt: string) {
    if (!aiField) return
    setIsAiRunning(true)
    try {
      const result = await fillProductFieldByAi({
        field: aiField,
        prompt,
        title: nameEn.trim() || undefined,
        nameFa: nameFa.trim() || undefined,
        categoryId: categoryId || undefined,
      })
      if (result.field === 'summary') {
        setSummary(result.text)
        showToast(t('products.form.aiSummaryFilled'), 'success')
      } else {
        setDescription(result.html)
        showToast(t('products.form.aiDescriptionFilled'), 'success')
      }
      setAiField(null)
    } finally {
      setIsAiRunning(false)
    }
  }

  useEffect(() => {
    const controller = new AbortController()

    async function loadFormOptions() {
      try {
        const [categoryItems, brandItems] = await Promise.all([
          listProductCategories(controller.signal),
          listAllBrands(controller.signal),
        ])
        setCategories(categoryItems.map(mapProductCategoryToUi))
        setBrandOptions(brandItems.map(mapBrandToSelectOption))
      } catch (err) {
        if (err instanceof DOMException && err.name === 'AbortError') return
        if (err instanceof ApiError) {
          setError(err.message)
        } else {
          setError(t('products.form.errorOptions'))
        }
      }
    }

    void loadFormOptions()
    return () => controller.abort()
  }, [t])

  useEffect(() => {
    if (!isEdit || !id) return

    const controller = new AbortController()

    async function loadProduct() {
      setError('')
      try {
        const product = await getProduct(id!, controller.signal)
        const form = mapProductApiToFormState(product)
        setCategoryId(form.categoryId)
        setBrandId(form.brandId)
        setNameFa(form.nameFa)
        setNameEn(form.nameEn)
        setSummary(form.summary)
        setDescription(form.description)
        setThumbnail(form.thumbnail)
        setImages(form.images)
        setTags(form.tags)
        setThumbnailMediaId(form.thumbnailMediaId)
        setGalleryMediaIds(form.galleryMediaIds)
        setLoaded(true)
      } catch (err) {
        if (err instanceof DOMException && err.name === 'AbortError') return
        navigate('/products/list', { replace: true })
      }
    }

    void loadProduct()
    return () => controller.abort()
  }, [isEdit, id, navigate])

  if (!loaded) return null

  async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault()
    setIsSubmitting(true)
    setError('')

    try {
      const featuredMediaId = await resolveDataUrlToMediaId(
        thumbnail,
        'product-thumbnail.jpg',
        thumbnailMediaId,
      )

      const nextGalleryMediaIds = await resolveDataUrlsToMediaIds(
        images,
        galleryMediaIds,
      )

      const payload = {
        title: nameEn.trim(),
        nameFa: nameFa.trim(),
        summary: summary.trim(),
        descriptionHtml: description,
        categoryId: categoryId || undefined,
        brandId: brandId || undefined,
        featuredMediaId: featuredMediaId ?? undefined,
        galleryMediaIds: nextGalleryMediaIds,
        tags,
        status: 'published' as const,
      }

      if (isEdit && id) {
        await updateProduct(id, {
          ...payload,
          categoryId: categoryId || null,
          brandId: brandId || null,
          featuredMediaId,
        })
      } else {
        await createProduct(payload)
      }

      navigate('/products/list')
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else if (err instanceof Error) {
        setError(err.message)
      } else {
        setError(t('products.form.errorSave'))
      }
    } finally {
      setIsSubmitting(false)
    }
  }

  return (
    <main className={pageStyles.content}>
      <Breadcrumbs
        items={
          isEdit
            ? [
                { label: 'Dashboard', href: '/' },
                { label: 'Products', href: '/products' },
                { label: 'My Products', href: '/products/list' },
                { label: 'Edit Product' },
              ]
            : [
                { label: 'Dashboard', href: '/' },
                { label: 'Products', href: '/products' },
                { label: 'Add a New Product' },
              ]
        }
      />
      <div className={pageStyles.pageHeader}>
        <div>
          <h2 className={pageStyles.pageTitle}>
            {isEdit ? t('title.editProduct') : t('products.card.new.title')}
          </h2>
          <p className={pageStyles.pageSubtitle}>
            {isEdit ? t('products.form.edit.subtitle') : t('products.card.new.desc')}
          </p>
        </div>
      </div>

      {error && (
        <div className={styles.error} role="alert">
          {error}
        </div>
      )}

      <form className={styles.form} onSubmit={handleSubmit}>
        <div className={styles.formGrid}>
          <div className={`${styles.field} ${styles.col2} ${styles.thumbnailField}`}>
            <label>{t('products.form.thumbnail')}</label>
            <ImageCropper value={thumbnail} onChange={setThumbnail} />
          </div>

          <div className={styles.col10}>
            <div className={styles.topFields}>
              <div className={`${styles.field} ${styles.fieldCategory}`}>
                <label>{t('products.form.category')}</label>
                <SearchableSelect
                  options={categoryOptions}
                  value={categoryId}
                  onChange={setCategoryId}
                  placeholder={t('products.form.categoryPlaceholder')}
                />
              </div>

              <div className={`${styles.field} ${styles.fieldBrand}`}>
                <label>
                  {t('products.form.brand')}{' '}
                  <span className={styles.optional}>{t('products.form.optional')}</span>
                </label>
                <SearchableSelect
                  options={brandOptions}
                  value={brandId}
                  onChange={setBrandId}
                  placeholder={t('products.form.brandPlaceholder')}
                />
              </div>

              <div className={`${styles.field} ${styles.fieldHalf}`}>
                <label htmlFor="nameFa">{t('products.form.nameFa')}</label>
                <input
                  id="nameFa"
                  name="nameFa"
                  type="text"
                  dir="rtl"
                  className="faText"
                  placeholder={t('products.form.nameFaPlaceholder')}
                  value={nameFa}
                  onChange={(e) => setNameFa(e.target.value)}
                  required
                  disabled={isSubmitting}
                />
              </div>

              <div className={`${styles.field} ${styles.fieldHalf}`}>
                <label htmlFor="nameEn">{t('products.form.nameEn')}</label>
                <input
                  id="nameEn"
                  name="nameEn"
                  type="text"
                  dir="ltr"
                  placeholder={t('products.form.nameEnPlaceholder')}
                  value={nameEn}
                  onChange={(e) => setNameEn(e.target.value)}
                  required
                  disabled={isSubmitting}
                />
              </div>

              <div className={`${styles.field} ${styles.fieldFull} ${styles.summaryField}`}>
                <label htmlFor="summary">{t('products.form.summary')}</label>
                <div className={styles.fieldWithAi}>
                  <textarea
                    id="summary"
                    name="summary"
                    rows={4}
                    placeholder={t('products.form.summaryPlaceholder')}
                    value={summary}
                    onChange={(e) => setSummary(e.target.value)}
                    required
                    disabled={isSubmitting}
                  />
                  <span className={styles.aiFillAnchor}>
                    <Tooltip label={t('products.form.aiFill')}>
                      <button
                        type="button"
                        className={`${aiStyles.aiBtn} ${styles.aiFillBtn}`}
                        onClick={() => openAiFill('summary')}
                        disabled={!canUseAiFill || isAiRunning}
                        aria-label={t('products.form.aiFill')}
                      >
                        <Sparkles size={14} />
                      </button>
                    </Tooltip>
                  </span>
                </div>
              </div>
            </div>
          </div>

          <div className={`${styles.field} ${styles.col12}`}>
            <label>{t('products.form.description')}</label>
            <div className={styles.fieldWithAi}>
              <RichTextEditor
                value={description}
                onChange={setDescription}
                placeholder={t('products.form.descriptionPlaceholder')}
                editorMinHeight={180}
              />
              <span className={styles.aiFillAnchor}>
                <Tooltip label={t('products.form.aiFill')}>
                  <button
                    type="button"
                    className={`${aiStyles.aiBtn} ${styles.aiFillBtn}`}
                    onClick={() => openAiFill('description')}
                    disabled={!canUseAiFill || isAiRunning}
                    aria-label={t('products.form.aiFill')}
                  >
                    <Sparkles size={14} />
                  </button>
                </Tooltip>
              </span>
            </div>
          </div>

          <div className={`${styles.field} ${styles.col12}`}>
            <label>{t('products.form.images')}</label>
            <ImageUploader images={images} onChange={setImages} />
          </div>

          <div className={`${styles.field} ${styles.col12}`}>
            <label>{t('products.form.tags')}</label>
            <TagInput
              tags={tags}
              onChange={setTags}
              placeholder={t('products.form.tagsPlaceholder')}
            />
          </div>
        </div>

        <div className={styles.actions}>
          <Link to="/products/list" className={styles.cancelBtn}>
            {t('products.form.cancel')}
          </Link>
          <button type="submit" className={styles.submitBtn} disabled={isSubmitting}>
            {isSubmitting
              ? t('products.form.saving')
              : isEdit
                ? t('products.form.update')
                : t('products.form.save')}
          </button>
        </div>
      </form>

      <ProductFieldAiPromptModal
        open={aiField !== null}
        field={aiField ?? 'summary'}
        nameFa={nameFa}
        nameEn={nameEn}
        categoryName={selectedCategoryName}
        isRunning={isAiRunning}
        onClose={() => {
          if (!isAiRunning) setAiField(null)
        }}
        onRun={runAiFill}
      />
    </main>
  )
}
