'use client';
import { useState, useEffect, useCallback, useRef } from 'react';
import { useRouter } from 'next/navigation';
import type { Product, Brand, Category } from '@/types';
import { productsApi, brandsApi, categoriesApi } from '@/lib/api-client';
import { ImagesSection } from './sections/ImagesSection';
import { PriceStockSection, type PriceStockHandle } from './sections/PriceStockSection';
import LexicalEditor from '@/features/cms/components/LexicalEditor';

interface ProductEditorProps {
  productId?: string;
}

const ATTRIBUTE_LABELS: Record<string, string> = {
  bio: '🌿 Bio',
  'comercio-justo': '⚖️ Comercio Justo',
  congelado: '❄️ Congelado',
  'cruelty-free': '🐰 Cruelty Free',
  'de-temporada': '🍂 De Temporada',
  demeter: '🌱 Demeter',
  'fruta-verdura': '🥕 Fruta y Verdura',
  keto: '🥑 Keto',
  kosher: '✡️ Kosher',
  'low-carb': '🍖 Low Carb',
  'raw-food': '🥗 Raw Food',
  'sin-azucar': '🚫 Sin Azúcar',
  'sin-gluten': '🌾 Sin Gluten',
  'sin-lactosa': '🥛 Sin Lactosa',
  vegano: '🌱 Vegano',
  'zero-waste': '♻️ Zero Waste',
};

const CHANNEL_OPTIONS = [
  { value: 'all', label: 'Todos los canales' },
  { value: 'online', label: 'Solo online' },
  { value: 'offline', label: 'Solo offline' },
] as const;

function slugify(text: string): string {
  return text.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
}

function hasMeaningfulContent(value: string): boolean {
  return value.replace(/<[^>]*>/g, '').replace(/&nbsp;|&#160;/gi, ' ').trim().length > 0;
}

export function ProductEditor({ productId: initialProductId }: ProductEditorProps) {
  const [productId, setProductId] = useState<string | undefined>(initialProductId);
  const router = useRouter();
  const isCreate = !productId;
  const [tab, setTab] = useState<'general' | 'images' | 'seo' | 'publish'>('general');
  const [saving, setSaving] = useState(false);
  const [generating, setGenerating] = useState(false);
  const [loading, setLoading] = useState(!isCreate);
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');

  const [name, setName] = useState('');
  const [slug, setSlug] = useState('');
  const [desc, setDesc] = useState('');
  const [brandId, setBrandId] = useState('');
  const [categoryIds, setCategoryIds] = useState<string[]>([]);
  const [channels, setChannels] = useState<'online' | 'offline' | 'all'>('all');
  const [featured, setFeatured] = useState(false);
  const [attributes, setAttributes] = useState<string[]>([]);
  const [state, setState] = useState('active');
  const [seoTitle, setSeoTitle] = useState('');
  const [seoTitleManual, setSeoTitleManual] = useState(false);
  const [seoDesc, setSeoDesc] = useState('');
  const [seoDescManual, setSeoDescManual] = useState(false);
  const [expirationDate, setExpirationDate] = useState('');
  const [brands, setBrands] = useState<Brand[]>([]);
  const [categories, setCategories] = useState<Category[]>([]);
  /** Imperative handle for PriceStockSection; called from handleSave so all
   *  price/stock/EAN/meta persistence flows through one click on the main
   *  "Guardar cambios" button (F-137). */
  const priceStockRef = useRef<PriceStockHandle>(null);

  useEffect(() => {
    brandsApi.list().then(({ items }) => setBrands(items ?? [])).catch(() => {});
    categoriesApi.list().then((data) => {
      const tree = (data as { items?: Category[] }).items ?? [];
      const flat = (cats: Category[]): Category[] => cats.flatMap(c => [c, ...flat(c.children ?? [])]);
      setCategories(flat(tree));
    }).catch(() => {});
  }, []);

  const snapRef = useRef('');
  const dirtyRef = useRef(false);

  /**
   * Returns a stable JSON snapshot of the form. The function is a `useCallback`
   * so the dirty-check effect can safely depend on its identity without
   * causing a feedback loop with the load effect. Previously `getSnap` was
   * also in the load effect's dependency list, which (combined with React
   * state updates inside the load handler) caused the load effect to re-fire
   * on every render — a fetch loop that broke checkbox selection.
   */
  const getSnap = useCallback(() => JSON.stringify({
    name, slug, desc, brandId, categoryIds, channels, featured, attributes, state, seoTitle, seoDesc, expirationDate,
  }), [name, slug, desc, brandId, categoryIds, channels, featured, attributes, state, seoTitle, seoDesc, expirationDate]);

  // Keep a ref to the latest getSnap so the load effect (which uses an empty
  // deps list to avoid the loop) can still compute the initial snapshot.
  const getSnapRef = useRef(getSnap);
  useEffect(() => { getSnapRef.current = getSnap; }, [getSnap]);

  useEffect(() => {
    if (!productId) { setLoading(false); return; }
    let cancelled = false;
    productsApi.get(productId).then((p: Product) => {
      if (cancelled) return;
      setName(p.name); setSlug(p.slug); setDesc(p.description ?? '');
      setBrandId(p.brandId ?? ''); setCategoryIds(p.categoryIds ?? []);
      setChannels((p as any).channels ?? 'all');
      setFeatured((p as any).featured ?? false);
      setAttributes((p as any).attributes ?? []);
      setState(p.state);
      setSeoTitle((p as any).seoTitle ?? ''); setSeoTitleManual(true);
      setSeoDesc((p as any).seoDescription ?? ''); setSeoDescManual(true);
      const rawExpirationDate = String((p as any).expirationDate ?? '');
      setExpirationDate(rawExpirationDate ? rawExpirationDate.slice(0, 10) : '');
      snapRef.current = getSnapRef.current();
      setLoading(false);
    }).catch(() => {
      if (cancelled) return;
      setError('No se pudo cargar el producto'); setLoading(false);
    });
    return () => { cancelled = true; };
    // eslint-disable-next-line react-hooks/exhaustive-deps -- load effect runs once per productId
  }, [productId]);

  useEffect(() => {
    if (loading) return;
    dirtyRef.current = getSnap() !== snapRef.current;
  }, [name, slug, desc, brandId, categoryIds, channels, featured, attributes, state, seoTitle, seoDesc, expirationDate, loading, getSnap]);

  useEffect(() => {
    const h = (e: BeforeUnloadEvent) => { if (dirtyRef.current) { e.preventDefault(); e.returnValue = ''; } };
    window.addEventListener('beforeunload', h);
    return () => window.removeEventListener('beforeunload', h);
  }, []);

  const handleNameChange = (v: string) => {
    setName(v);
    // El slug se auto-genera solo al crear; en edición se conserva el existente.
    if (isCreate) setSlug(slugify(v));
    if (!seoTitleManual) setSeoTitle(v);
    if (!seoDescManual) setSeoDesc(`${v} — Compra online en mercadodevida. Productos naturales y ecológicos.`);
  };

  const handleSave = async () => {
    setSaving(true); setError(''); setSuccess('');
    try {
      const payload = {
        name, slug,
        description: hasMeaningfulContent(desc) ? desc.trim() : null,
        brandId: brandId || undefined,
        categoryIds,
        channels,
        featured,
        attributes,
        state,
        seoTitle: seoTitle.trim() || null,
        seoDescription: seoDesc.trim() || null,
        expirationDate: expirationDate || undefined,
      };
      let saved: Product;
      if (isCreate) saved = await productsApi.create(payload);
      else saved = await productsApi.update(productId, payload);
      if (!hasMeaningfulContent(desc) || !seoTitle.trim() || !seoDesc.trim()) {
        setGenerating(true);
        setSuccess('✨ Generando contenido con IA… esto puede tardar unos segundos.');
        try {
          saved = await productsApi.generateSeo(saved.id);
          setDesc(saved.description ?? '');
          setSeoTitle(saved.seoTitle ?? '');
          setSeoDesc(saved.seoDescription ?? '');
        } catch (generationError) {
          setError(generationError instanceof Error ? generationError.message : 'No se pudieron generar los campos SEO');
        } finally {
          setGenerating(false);
        }
      }
      // Persist price/stock/EAN/meta through the section's saveAll handle
      // (F-137: single save point). Tolerates partial failures.
      try {
        const result = await priceStockRef.current?.saveAll();
        const failed = result
          ? Object.entries(result).filter(([, ok]) => !ok).map(([k]) => k)
          : [];
        if (failed.length > 0) {
          const labels: Record<string, string> = {
            price: 'precio',
            stock: 'stock',
            ean: 'EAN',
            meta: 'peso/compra mínima',
          };
          setSuccess(`Producto guardado. Revisa ${failed.map((k) => labels[k] ?? k).join(', ')}.`);
        } else if (!hasMeaningfulContent(desc) || !seoTitle.trim() || !seoDesc.trim()) {
          setSuccess(isCreate ? '¡Producto creado! Contenido generado con IA.' : 'Cambios guardados. Contenido generado con IA.');
        } else {
          setSuccess(isCreate ? '¡Producto creado!' : 'Cambios guardados');
        }
      } catch (saveErr) {
        setError(saveErr instanceof Error ? saveErr.message : 'Error al guardar precio/stock/EAN');
      }
      snapRef.current = getSnap();
      dirtyRef.current = false;
      if (isCreate) {
        // Stay on the same React component but unlock the price/stock/EAN
        // section by giving it a real productId. router.replace avoids a
        // full page reload so the dirty state is preserved (F-121).
        setProductId(saved.id);
        router.replace(`/products/${saved.id}`);
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Error al guardar');
    } finally {
      setSaving(false);
    }
  };

  const toggleAttr = (key: string) => {
    setAttributes(prev => prev.includes(key) ? prev.filter(a => a !== key) : [...prev, key]);
  };

  const saveState = async (s: string) => {
    setState(s);
    if (productId) {
      try {
        await productsApi.setState(productId, s as 'active' | 'archived');
        setSuccess(`Estado actualizado a: ${s}`);
      } catch {
        setError('Error al cambiar estado');
      }
    }
  };

  if (loading) return (
    <div className="p-8 flex justify-center">
      <div className="h-6 w-6 border-2 border-gray-300 border-t-[#2D6A4F] rounded-full animate-spin" />
    </div>
  );

  return (
    <div className="space-y-8">
      <div className="flex items-center justify-between">
        <div>
          <button onClick={() => router.push('/products')} className="text-sm text-gray-500 hover:text-gray-700 mb-1 flex items-center gap-1">← Productos</button>
          <h1 className="text-2xl font-bold text-gray-900">{isCreate ? 'Nuevo producto' : `Editar: ${name}`}</h1>
        </div>
        <button onClick={handleSave} disabled={saving || generating}
          className="px-5 py-2.5 bg-[#2D6A4F] hover:bg-[#1B4332] disabled:opacity-50 text-white text-sm font-semibold rounded-xl transition-colors">
          {generating ? '✨ Generando con IA...' : saving ? 'Guardando...' : isCreate ? 'Crear producto' : 'Guardar cambios'}
        </button>
      </div>

      {error && <div className="mb-4 p-4 bg-red-50 border border-red-200 rounded-xl text-sm text-red-700">{error}</div>}
      {generating ? (
        <div className="mb-4 p-4 bg-blue-50 border border-blue-200 rounded-xl text-sm text-blue-700 flex items-center gap-3">
          <span className="inline-block h-4 w-4 border-2 border-blue-300 border-t-blue-600 rounded-full animate-spin shrink-0" />
          ✨ Generando descripción y campos SEO con IA en segundo plano… no cierres esta página.
        </div>
      ) : success && <div className="mb-4 p-4 bg-green-50 border border-green-200 rounded-xl text-sm text-green-700">{success}</div>}

      {/* Tabs */}
      <div className="flex border-b border-gray-200 mb-8 overflow-x-auto">
        {(['general', 'images', 'seo', 'publish'] as const).map(t => (
          <button key={t} onClick={() => setTab(t)}
            className={`px-5 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${
              tab === t ? 'border-[#2D6A4F] text-[#2D6A4F]' : 'border-transparent text-gray-500 hover:text-gray-700'
            }`}>
            {t === 'general' ? 'General' : t === 'images' ? 'Imágenes' : t === 'seo' ? 'SEO' : 'Publicar'}
          </button>
        ))}
      </div>

      {/* ── GENERAL ── */}
      {tab === 'general' && (
        <section className="space-y-6">
          <div>
            <div className="flex items-center justify-between mb-1.5">
              <label className="text-sm font-semibold text-gray-900">Slug (URL)</label>
              <span className="text-xs text-[#2D6A4F] font-medium">auto-generado</span>
            </div>
            <input type="text" value={slug} disabled readOnly
              className="w-full px-4 py-2.5 border border-gray-200 rounded-xl text-sm font-mono bg-gray-50 text-gray-500 cursor-not-allowed outline-none" />
            <p className="mt-1 text-xs text-gray-400">Se genera automáticamente a partir del nombre y no se puede editar manualmente.</p>
          </div>
          <div className="grid grid-cols-1 sm:grid-cols-[1fr_auto] gap-5 items-start">
            <div>
              <label className="block text-sm font-semibold text-gray-900 mb-1.5">Nombre del producto *</label>
              <input type="text" value={name} onChange={e => handleNameChange(e.target.value)} required
                placeholder="Ej: Almendras Crudas Ecológicas"
                className="w-full px-4 py-2.5 border border-gray-300 rounded-xl text-sm focus:ring-2 focus:ring-[#2D6A4F] outline-none" />
            </div>
            <label className="flex items-center gap-2 sm:mt-[34px] cursor-pointer px-4 py-2.5 border border-gray-200 rounded-xl bg-gray-50">
              <input type="checkbox" checked={featured} onChange={e => setFeatured(e.target.checked)}
                className="rounded text-[#2D6A4F] focus:ring-[#2D6A4F]" />
              <span className="text-sm font-semibold text-gray-900 whitespace-nowrap">⭐ Producto destacado</span>
              <span className="text-xs text-gray-400 hidden sm:inline">(aparece en la home)</span>
            </label>
          </div>
          {/* Precio y stock por producto (entre nombre y metadatos) */}
          <PriceStockSection ref={priceStockRef} productId={productId} />
          {/* Marca / Canal / Caducidad — antes de descripción (F-123) */}
          <div className="grid grid-cols-1 sm:grid-cols-3 gap-5">
            <div>
              <label className="block text-sm font-semibold text-gray-900 mb-1.5">Marca</label>
              <select value={brandId} onChange={e => setBrandId(e.target.value)}
                className="w-full px-4 py-2.5 border border-gray-300 rounded-xl text-sm focus:ring-2 focus:ring-[#2D6A4F] outline-none bg-white">
                <option value="">Sin marca</option>
                {brands.map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            </div>
            <div>
              <label className="block text-sm font-semibold text-gray-900 mb-1.5">Canal de venta</label>
              <select value={channels} onChange={e => setChannels(e.target.value as typeof channels)}
                className="w-full px-4 py-2.5 border border-gray-300 rounded-xl text-sm focus:ring-2 focus:ring-[#2D6A4F] outline-none bg-white">
                {CHANNEL_OPTIONS.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
              </select>
            </div>
            <div>
              <label className="block text-sm font-semibold text-gray-900 mb-1.5">
                Fecha de caducidad <span className="text-xs text-gray-400 font-normal">(opcional)</span>
              </label>
              <input
                type="date"
                value={expirationDate}
                onChange={(e) => setExpirationDate(e.target.value)}
                className="w-full px-4 py-2.5 border border-gray-300 rounded-xl text-sm focus:ring-2 focus:ring-[#2D6A4F] outline-none"
              />
              <p className="mt-1 text-xs text-gray-400">Se mostrará en el listado de productos y en la tienda.</p>
            </div>
          </div>
          <div>
            <label className="block text-sm font-semibold text-gray-900 mb-1.5">Descripción</label>
            <LexicalEditor
              value={desc}
              onChange={(html) => setDesc(html)}
              placeholder="Descripción detallada del producto…"
            />
          </div>
          <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
            <div>
              <div className="flex items-center justify-between mb-3">
                <label className="text-sm font-semibold text-gray-900">Categorías</label>
              </div>
              <div className="border border-gray-200 rounded-xl p-3 space-y-2 max-h-52 overflow-y-auto">
                {categories.map(cat => (
                  <label key={cat.id} className="flex items-center gap-2 cursor-pointer">
                    <input type="checkbox" checked={categoryIds.includes(cat.id)}
                      onChange={e => {
                        if (e.target.checked) setCategoryIds(prev => [...prev, cat.id]);
                        else setCategoryIds(prev => prev.filter(id => id !== cat.id));
                      }}
                      className="rounded text-[#2D6A4F] focus:ring-[#2D6A4F]" />
                      <span className={`text-sm ${cat.parentId ? 'text-gray-500' : 'font-medium text-gray-700'}`}>
                        {cat.parentId ? `↳ ${cat.name}` : cat.name}
                      </span>
                  </label>
                ))}
              </div>
            </div>
            <div>
              <div className="flex items-center justify-between mb-3">
                <label className="text-sm font-semibold text-gray-900">Atributos</label>
                <span className="text-xs text-gray-400">{attributes.length} / 16</span>
              </div>
              <div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
                {Object.entries(ATTRIBUTE_LABELS).map(([key, label]) => (
                  <button key={key} type="button" onClick={() => toggleAttr(key)}
                    aria-pressed={attributes.includes(key)}
                    className={`flex items-center gap-2 px-3 py-2 border rounded-xl cursor-pointer transition-colors text-sm text-left ${
                      attributes.includes(key)
                        ? 'border-[#2D6A4F] bg-[#2D6A4F]/5 text-[#2D6A4F]'
                        : 'border-gray-200 hover:border-gray-300 text-gray-600'
                    }`}>
                    <span className={`inline-block w-1.5 h-1.5 rounded-full shrink-0 ${attributes.includes(key) ? 'bg-[#2D6A4F]' : 'bg-gray-300'}`} />
                    {label}
                  </button>
                ))}
              </div>
            </div>
          </div>
        </section>
      )}

      {/* ── IMAGES ── */}
      {tab === 'images' && (
        <section>
          <ImagesSection productId={productId} />
        </section>
      )}

      {/* ── SEO ── */}
      {tab === 'seo' && (
        <section className="space-y-6">
          <div className="p-4 bg-blue-50 border border-blue-100 rounded-xl text-xs text-blue-700 space-y-1">
            <p>El título y descripción SEO se usan en Google. Si están vacíos, se usan automáticamente.</p>
          </div>
          <div>
            <div className="flex items-center justify-between mb-1.5">
              <label className="text-sm font-semibold text-gray-900">Título SEO (Google)</label>
              <span className={`text-xs ${seoTitleManual ? 'text-gray-400' : 'text-[#2D6A4F] font-medium'}`}>
                {seoTitleManual ? 'editado manualmente' : 'copiado del nombre'}
              </span>
            </div>
            <input type="text" value={seoTitle}
              onChange={e => { setSeoTitleManual(true); setSeoTitle(e.target.value); }}
              maxLength={60}
              placeholder="Título para Google (max 60 caracteres)"
              className="w-full px-4 py-2.5 border border-gray-300 rounded-xl text-sm focus:ring-2 focus:ring-[#2D6A4F] outline-none" />
            <div className="mt-1 text-xs text-gray-400">{seoTitle.length}/60</div>
          </div>
          <div>
            <div className="flex items-center justify-between mb-1.5">
              <label className="text-sm font-semibold text-gray-900">Descripción SEO (Google)</label>
              <span className={`text-xs ${seoDescManual ? 'text-gray-400' : 'text-[#2D6A4F] font-medium'}`}>
                {seoDescManual ? 'editada manualmente' : 'auto-generada'}
              </span>
            </div>
            <textarea value={seoDesc}
              onChange={e => { setSeoDescManual(true); setSeoDesc(e.target.value); }}
              rows={3} maxLength={160}
              placeholder="Descripción para Google (max 160 caracteres)"
              className="w-full px-4 py-2.5 border border-gray-300 rounded-xl text-sm focus:ring-2 focus:ring-[#2D6A4F] outline-none resize-none" />
            <div className="mt-1 text-xs text-gray-400">{seoDesc.length}/160</div>
          </div>

        </section>
      )}

      {/* ── PUBLISH ── */}
      {tab === 'publish' && (
        <section className="space-y-5">
          <div>
            <label className="block text-sm font-semibold text-gray-900 mb-3">Estado del producto</label>
            <div className="grid grid-cols-3 gap-3">
              {[['draft', 'Borrador', 'gray'], ['active', 'Activo', 'green'], ['archived', 'Archivado', 'amber']].map(([s, label, color]) => (
                <button key={s} onClick={() => saveState(s as string)}
                  className={`px-4 py-3 rounded-xl border-2 text-sm font-medium transition-all ${
                    state === s
                      ? color === 'green' ? 'border-[#2D6A4F] bg-[#2D6A4F]/5 text-[#2D6A4F]' : color === 'amber' ? 'border-amber-400 bg-amber-50 text-amber-700' : 'border-gray-400 bg-gray-100 text-gray-700'
                      : 'border-gray-200 text-gray-500 hover:border-gray-300'
                  }`}>
                  {label}
                </button>
              ))}
            </div>
          </div>
          <div className="p-5 bg-gray-50 border border-gray-200 rounded-xl text-sm text-gray-600 space-y-2">
            <div className="flex justify-between"><span>Borrador</span><span>No visible en la tienda</span></div>
            <div className="flex justify-between"><span>Activo</span><span>Visible y comprable online</span></div>
            <div className="flex justify-between"><span>Archivado</span><span>Oculto pero conservado</span></div>
          </div>
        </section>
      )}
    </div>
  );
}
