'use client'
import { useState, useEffect, useRef, useCallback } from 'react'
import { COLOR_SCHEMES, renderBanner } from '@/lib/client/bannerRenderer'
import type { BannerConfig, ColorScheme } from '@/lib/client/bannerRenderer'
import type { BannerProductData } from '@/app/api/theme/product-banner-data/route'

interface Props {
  onApply: (shopifyRef: string) => void
  onClose: () => void
}

interface SearchSuggestion {
  shopifyId: string
  title: string
  sku: string
}

function formatPrice(price: string): string {
  if (!price) return ''
  const n = parseFloat(price)
  return isNaN(n) ? price : `${Math.round(n)} €`
}

function blobToBase64(blob: Blob): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = () => resolve((reader.result as string).split(',')[1])
    reader.onerror = reject
    reader.readAsDataURL(blob)
  })
}

export function BannerBuilder({ onApply, onClose }: Props) {
  // Combobox produit
  const [inputValue, setInputValue] = useState('')
  const [suggestions, setSuggestions] = useState<SearchSuggestion[]>([])
  const [showSuggestions, setShowSuggestions] = useState(false)
  const [loadingSuggestions, setLoadingSuggestions] = useState(false)
  const [loadingProduct, setLoadingProduct] = useState(false)
  const [product, setProduct] = useState<BannerProductData | null>(null)
  const [searchError, setSearchError] = useState<string | null>(null)
  const comboRef = useRef<HTMLDivElement>(null)

  // Banner config
  const [scheme, setScheme] = useState<ColorScheme>('dark-blue')
  const [promoLabel, setPromoLabel] = useState('Destockage - Durée limitée')
  const [title, setTitle] = useState('')
  const [price, setPrice] = useState('')
  const [comparePrice, setComparePrice] = useState('')
  const [selectedImageUrl, setSelectedImageUrl] = useState<string | null>(null)
  const [backgroundBlob, setBackgroundBlob] = useState<Blob | null>(null)
  const [backgroundPreview, setBackgroundPreview] = useState<string | null>(null)
  const bgFileRef = useRef<HTMLInputElement>(null)

  // Generation
  const [rendering, setRendering] = useState(false)
  const [previewUrl, setPreviewUrl] = useState<string | null>(null)
  const [uploading, setUploading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const previewRef = useRef<string | null>(null)

  // Ferme les suggestions si clic extérieur
  useEffect(() => {
    const handler = (e: MouseEvent) => {
      if (comboRef.current && !comboRef.current.contains(e.target as Node)) {
        setShowSuggestions(false)
      }
    }
    document.addEventListener('mousedown', handler)
    return () => document.removeEventListener('mousedown', handler)
  }, [])

  // Recherche des suggestions (debounce 300ms)
  useEffect(() => {
    const q = inputValue.trim()
    if (q.length < 2) { setSuggestions([]); setShowSuggestions(false); return }
    const t = setTimeout(async () => {
      setLoadingSuggestions(true)
      try {
        const res = await fetch(`/api/products/search-list?q=${encodeURIComponent(q)}`)
        if (!res.ok) return
        const data = await res.json() as SearchSuggestion[]
        setSuggestions(data)
        setShowSuggestions(data.length > 0)
      } catch { /* silencieux */ } finally {
        setLoadingSuggestions(false)
      }
    }, 300)
    return () => clearTimeout(t)
  }, [inputValue])

  const selectSuggestion = async (s: SearchSuggestion) => {
    setInputValue(s.title)
    setShowSuggestions(false)
    setSuggestions([])
    setLoadingProduct(true)
    setSearchError(null)
    setProduct(null)
    setPreviewUrl(null)
    try {
      const res = await fetch(`/api/theme/product-banner-data?id=${s.shopifyId}`)
      const data = await res.json()
      if (!res.ok) throw new Error(data.error)
      const p = data as BannerProductData
      setProduct(p)
      setTitle(p.title.toUpperCase())
      setPrice(formatPrice(p.price))
      setComparePrice(p.compareAtPrice ? formatPrice(p.compareAtPrice) : '')
      setSelectedImageUrl(p.imageUrl)
    } catch (e) {
      setSearchError((e as Error).message)
    } finally {
      setLoadingProduct(false)
    }
  }

  const handleBgFile = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (!file) return
    setBackgroundBlob(file)
    const url = URL.createObjectURL(file)
    if (backgroundPreview) URL.revokeObjectURL(backgroundPreview)
    setBackgroundPreview(url)
    e.target.value = ''
  }

  const removeBg = () => {
    if (backgroundPreview) URL.revokeObjectURL(backgroundPreview)
    setBackgroundBlob(null)
    setBackgroundPreview(null)
  }

  const getConfig = useCallback((): BannerConfig => ({
    scheme,
    promoLabel,
    title,
    price,
    comparePrice,
    productImageUrl: selectedImageUrl,
    backgroundImageBlob: backgroundBlob,
  }), [scheme, promoLabel, title, price, comparePrice, selectedImageUrl, backgroundBlob])

  const generate = useCallback(async () => {
    setRendering(true)
    setError(null)
    try {
      const blob = await renderBanner(getConfig())
      const url = URL.createObjectURL(blob)
      if (previewRef.current) URL.revokeObjectURL(previewRef.current)
      previewRef.current = url
      setPreviewUrl(url)
    } catch (e) {
      setError((e as Error).message)
    } finally {
      setRendering(false)
    }
  }, [getConfig])

  // Régénère automatiquement quand les paramètres changent (debounce 600ms)
  useEffect(() => {
    if (!title && !product) return
    const t = setTimeout(() => { generate() }, 600)
    return () => clearTimeout(t)
  }, [scheme, promoLabel, title, price, comparePrice, selectedImageUrl, backgroundBlob]) // eslint-disable-line react-hooks/exhaustive-deps

  const applyToSlide = async () => {
    if (!previewRef.current) return
    setUploading(true)
    setError(null)
    try {
      // Convertit l'objectURL en blob
      const res = await fetch(previewRef.current)
      const blob = await res.blob()
      const base64 = await blobToBase64(blob)
      const filename = `banniere-${(product?.sku ?? 'custom').toLowerCase().replace(/[^a-z0-9]/g, '-')}-${Date.now()}.jpg`

      const uploadRes = await fetch('/api/theme/upload-file', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ imageBase64: base64, filename }),
      })
      const uploadData = await uploadRes.json()
      if (!uploadRes.ok) throw new Error(uploadData.error)
      onApply(uploadData.shopifyRef)
    } catch (e) {
      setError((e as Error).message)
    } finally {
      setUploading(false)
    }
  }

  const schemeEntries = Object.entries(COLOR_SCHEMES) as [ColorScheme, typeof COLOR_SCHEMES[ColorScheme]][]

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 p-4"
      onClick={e => { if (e.target === e.currentTarget) onClose() }}
    >
      <div className="bg-slate-800 border border-slate-700 rounded-xl w-full max-w-5xl max-h-[95vh] flex flex-col">

        {/* Header */}
        <div className="flex items-center justify-between p-4 border-b border-slate-700">
          <h2 className="text-white font-semibold text-sm">Créer une bannière</h2>
          <button type="button" onClick={onClose} className="text-gray-400 hover:text-white text-lg leading-none">✕</button>
        </div>

        <div className="flex flex-1 overflow-hidden">
          {/* ── Panneau gauche : configuration ─────────────────────────────── */}
          <div className="w-80 flex-shrink-0 overflow-y-auto border-r border-slate-700 p-4 space-y-5">

            {/* Recherche produit — combobox */}
            <section>
              <h3 className="text-xs font-semibold text-gray-300 uppercase tracking-wide mb-2">Produit</h3>
              <div className="relative" ref={comboRef}>
                <div className="relative">
                  <input
                    type="text"
                    value={inputValue}
                    onChange={e => { setInputValue(e.target.value); setProduct(null) }}
                    onFocus={() => suggestions.length > 0 && setShowSuggestions(true)}
                    placeholder="Rechercher par nom ou référence…"
                    className="w-full bg-slate-700 border border-slate-600 rounded px-2 py-1.5 pr-7 text-xs text-white focus:outline-none focus:ring-1 focus:ring-indigo-500"
                  />
                  <span className="absolute right-2 top-1/2 -translate-y-1/2 text-slate-400 text-xs pointer-events-none">
                    {loadingSuggestions || loadingProduct ? '⏳' : '🔍'}
                  </span>
                </div>
                {showSuggestions && suggestions.length > 0 && (
                  <div className="absolute z-20 w-full mt-1 bg-slate-700 border border-slate-600 rounded shadow-xl max-h-52 overflow-y-auto">
                    {suggestions.map(s => (
                      <button
                        key={s.shopifyId}
                        type="button"
                        onMouseDown={e => { e.preventDefault(); selectSuggestion(s) }}
                        className="w-full text-left px-3 py-2 hover:bg-slate-600 border-b border-slate-600 last:border-0"
                      >
                        <p className="text-xs text-white truncate">{s.title}</p>
                        <p className="text-xs text-slate-400 font-mono">{s.sku}</p>
                      </button>
                    ))}
                  </div>
                )}
              </div>
              {searchError && <p className="text-xs text-red-400 mt-1">{searchError}</p>}
              {product && (
                <div className="mt-2 p-2 bg-slate-700 rounded text-xs">
                  <p className="text-white font-medium truncate">{product.title}</p>
                  <p className="text-slate-400">{product.sku} · {formatPrice(product.price)}</p>
                  {product.allImages.length > 1 && (
                    <div className="mt-2">
                      <p className="text-slate-400 mb-1">Choisir l&apos;image :</p>
                      <div className="flex gap-1 flex-wrap">
                        {product.allImages.map((url, i) => (
                          <button
                            key={i}
                            type="button"
                            onClick={() => setSelectedImageUrl(url)}
                            className={`rounded overflow-hidden border-2 transition-all ${selectedImageUrl === url ? 'border-indigo-500' : 'border-slate-600'}`}
                          >
                            <img src={url} alt={`img ${i}`} className="w-12 h-12 object-cover" />
                          </button>
                        ))}
                      </div>
                    </div>
                  )}
                </div>
              )}
            </section>

            {/* Image de fond */}
            <section>
              <h3 className="text-xs font-semibold text-gray-300 uppercase tracking-wide mb-2">Image de fond</h3>
              {backgroundPreview ? (
                <div className="relative rounded overflow-hidden border border-slate-600">
                  <img src={backgroundPreview} alt="Fond" className="w-full h-24 object-cover" />
                  <button
                    type="button"
                    onClick={removeBg}
                    className="absolute top-1 right-1 bg-black/70 hover:bg-red-900 text-white text-xs px-1.5 py-0.5 rounded"
                  >
                    ✕ Retirer
                  </button>
                </div>
              ) : (
                <button
                  type="button"
                  onClick={() => bgFileRef.current?.click()}
                  className="w-full py-3 border-2 border-dashed border-slate-600 hover:border-indigo-500 rounded text-xs text-slate-400 hover:text-indigo-400 transition-colors"
                >
                  + Uploader une image de fond
                </button>
              )}
              <input ref={bgFileRef} type="file" accept="image/*" className="hidden" onChange={handleBgFile} />
              {backgroundPreview && (
                <p className="text-xs text-slate-500 mt-1">Un overlay sombre est appliqué automatiquement pour la lisibilité du texte.</p>
              )}
            </section>

            {/* Thème couleur */}
            <section>
              <h3 className="text-xs font-semibold text-gray-300 uppercase tracking-wide mb-2">
                {backgroundPreview ? 'Couleur du texte' : 'Thème couleur'}
              </h3>
              <div className="grid grid-cols-2 gap-1.5">
                {schemeEntries.map(([key, s]) => (
                  <button
                    key={key}
                    type="button"
                    onClick={() => setScheme(key)}
                    style={{ background: s.bg, borderColor: scheme === key ? '#6366f1' : '#475569' }}
                    className={`px-3 py-2 rounded text-xs border-2 font-medium transition-all`}
                  >
                    <span style={{ color: s.titleColor }}>{s.label}</span>
                  </button>
                ))}
              </div>
            </section>

            {/* Textes */}
            <section>
              <h3 className="text-xs font-semibold text-gray-300 uppercase tracking-wide mb-2">Textes</h3>
              <div className="space-y-2">
                <div>
                  <label className="block text-xs text-slate-400 mb-0.5">Badge promotionnel</label>
                  <input
                    type="text"
                    value={promoLabel}
                    onChange={e => setPromoLabel(e.target.value)}
                    className="w-full bg-slate-700 border border-slate-600 rounded px-2 py-1.5 text-xs text-white focus:outline-none focus:ring-1 focus:ring-indigo-500"
                  />
                </div>
                <div>
                  <label className="block text-xs text-slate-400 mb-0.5">Titre produit</label>
                  <textarea
                    value={title}
                    onChange={e => setTitle(e.target.value)}
                    rows={3}
                    className="w-full bg-slate-700 border border-slate-600 rounded px-2 py-1.5 text-xs text-white focus:outline-none focus:ring-1 focus:ring-indigo-500 resize-none"
                  />
                </div>
                <div className="flex gap-2">
                  <div className="flex-1">
                    <label className="block text-xs text-slate-400 mb-0.5">Prix affiché</label>
                    <input
                      type="text"
                      value={price}
                      onChange={e => setPrice(e.target.value)}
                      className="w-full bg-slate-700 border border-slate-600 rounded px-2 py-1.5 text-xs text-white focus:outline-none focus:ring-1 focus:ring-indigo-500"
                    />
                  </div>
                  <div className="flex-1">
                    <label className="block text-xs text-slate-400 mb-0.5">Prix barré</label>
                    <input
                      type="text"
                      value={comparePrice}
                      onChange={e => setComparePrice(e.target.value)}
                      placeholder="optionnel"
                      className="w-full bg-slate-700 border border-slate-600 rounded px-2 py-1.5 text-xs text-white focus:outline-none focus:ring-1 focus:ring-indigo-500"
                    />
                  </div>
                </div>
              </div>
            </section>
          </div>

          {/* ── Panneau droit : aperçu ──────────────────────────────────────── */}
          <div className="flex-1 flex flex-col overflow-hidden">
            <div className="flex-1 flex items-center justify-center bg-slate-900 p-4 overflow-auto">
              {rendering && (
                <p className="text-slate-500 text-sm">Génération en cours…</p>
              )}
              {!rendering && previewUrl && (
                <img
                  src={previewUrl}
                  alt="Aperçu bannière"
                  className="max-w-full rounded shadow-lg"
                  style={{ maxHeight: '60vh' }}
                />
              )}
              {!rendering && !previewUrl && (
                <div className="text-center text-slate-600">
                  <p className="text-4xl mb-2">🎨</p>
                  <p className="text-sm">Recherchez un produit pour commencer</p>
                </div>
              )}
            </div>

            {/* Footer actions */}
            <div className="p-4 border-t border-slate-700 flex items-center justify-between gap-3">
              <div className="flex items-center gap-3">
                {error && <p className="text-xs text-red-400">{error}</p>}
                <span className="text-xs text-slate-500">Format : 1500 × 500 px</span>
              </div>
              <div className="flex gap-2">
                <button
                  onClick={generate}
                  disabled={rendering || (!title && !product)}
                  className="px-4 py-2 text-xs bg-slate-700 hover:bg-slate-600 text-white rounded font-medium disabled:opacity-40"
                >
                  {rendering ? '⏳ Rendu…' : '↺ Régénérer'}
                </button>
                <button
                  onClick={applyToSlide}
                  disabled={!previewUrl || uploading || rendering}
                  className="px-4 py-2 text-xs bg-green-700 hover:bg-green-600 text-white rounded font-medium disabled:opacity-40"
                >
                  {uploading ? '⬆️ Upload…' : '✓ Appliquer à la slide'}
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}
