// SAVAAR — Catálogo dashboard app (Supabase, multi-sección)
const { useState, useEffect, useMemo, useRef } = React;

const supabaseClient = window.supabase.createClient(
  window.SAVAAR_SUPABASE_URL,
  window.SAVAAR_SUPABASE_KEY
);

const FX_USD_TO_MXN = 18.5;
const FMT = (n, cur = "MXN") => {
  const v = (Number(n) || 0).toLocaleString("en-US");
  return cur === "USD" ? "US$" + v : "$" + v + " MXN";
};
const FMT_SHORT = (n, cur = "MXN") => {
  const v = (Number(n) || 0).toLocaleString("en-US");
  return cur === "USD" ? "US$" + v : "$" + v;
};
const toMXN = w => (w.currency === "USD" ? (Number(w.price) || 0) * FX_USD_TO_MXN : (Number(w.price) || 0));

const getImages = (item) => {
  if (item?.images && Array.isArray(item.images) && item.images.length > 0) return item.images;
  if (item?.img) return [item.img];
  return [];
};
const getCover = (item) => getImages(item)[0] || "";

const PRICE_BUCKETS = [
  { label: "Cualquier precio", min: 0, max: Infinity },
  { label: "Hasta $50K MXN", min: 0, max: 50000 },
  { label: "$50K – $200K MXN", min: 50000, max: 200000 },
  { label: "$200K – $600K MXN", min: 200000, max: 600000 },
  { label: "$600K – $1M MXN", min: 600000, max: 1000000 },
  { label: "+ $1M MXN", min: 1000000, max: Infinity },
];

const JEWELRY_TYPES = ["Anillo", "Aretes", "Collar", "Dije", "Pulsera"];
const JEWELRY_MATERIALS = [
  "Oro Amarillo 14k", "Oro Amarillo 18k",
  "Oro Blanco 14k", "Oro Blanco 18k",
  "Oro Rosa 14k", "Oro Rosa 18k",
  "Plata 925", "Platino"
];
const JEWELRY_STONES = ["Sin piedra", "Diamante", "Esmeralda", "Rubí", "Zafiro", "Perla", "Tanzanita", "Otra"];

const Icon = ({ name, size = 16 }) => {
  if (name === "wa") {
    return (
      <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
        <path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51l-.57-.01c-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413" />
      </svg>
    );
  }
  const p = {
    search: "M21 21l-4.35-4.35M11 19a8 8 0 1 1 0-16 8 8 0 0 1 0 16z",
    grid: "M3 3h7v7H3zM14 3h7v7h-7zM14 14h7v7h-7zM3 14h7v7H3z",
    list: "M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01",
    close: "M18 6L6 18M6 6l12 12",
    plus: "M12 5v14M5 12h14",
    edit: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5z",
    trash: "M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",
    share: "M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8M16 6l-4-4-4 4M12 2v13",
    copy: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1M9 9a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-9a2 2 0 0 1-2-2z",
    check: "M20 6L9 17l-5-5",
    upload: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12",
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d={p[name]} />
    </svg>
  );
};

async function uploadImageTo(file, bucket, idPrefix) {
  const ext = (file.name.split('.').pop() || 'jpg').toLowerCase();
  const path = `${idPrefix}-${Date.now()}.${ext}`;
  const { error } = await supabaseClient.storage
    .from(bucket)
    .upload(path, file, { upsert: true, contentType: file.type });
  if (error) throw error;
  const { data } = supabaseClient.storage.from(bucket).getPublicUrl(path);
  return data.publicUrl;
}

const SECTIONS = {
  relojes: {
    label: "Relojes",
    singular: "reloj",
    table: "watches",
    bucket: "watch-images",
    idPrefix: "w",
  },
  joyeria: {
    label: "Joyería fina",
    singular: "pieza",
    table: "jewelry",
    bucket: "jewelry-images",
    idPrefix: "j",
  },
};

const parseHash = () => {
  const h = window.location.hash.toLowerCase();
  if (h === '#joyeria') return { section: 'joyeria', openId: null };
  if (h === '#relojes') return { section: 'relojes', openId: null };
  const m = h.match(/^#([wj]\w+)$/);
  if (m) return { section: m[1].startsWith('j') ? 'joyeria' : 'relojes', openId: m[1] };
  return { section: 'relojes', openId: null };
};

function App() {
  const initial = useRef(parseHash()).current;
  const [section, setSection] = useState(initial.section);

  const [watches, setWatches] = useState([]);
  const [jewelry, setJewelry] = useState([]);
  const [loadingWatches, setLoadingWatches] = useState(true);
  const [loadingJewelry, setLoadingJewelry] = useState(true);

  const [search, setSearch] = useState("");
  // Watch-specific filters
  const [brand, setBrand] = useState("Todas");
  const [family, setFamily] = useState("Todas");
  const [material, setMaterial] = useState("Todos");
  // Jewelry-specific filters
  const [jType, setJType] = useState("Todos");
  const [jMaterial, setJMaterial] = useState("Todos");
  const [jStone, setJStone] = useState("Todas");
  // Shared
  const [status, setStatus] = useState("Todos");
  const [priceIdx, setPriceIdx] = useState(0);

  const [view, setView] = useState("grid");
  const [openId, setOpenId] = useState(initial.openId);
  const [editId, setEditId] = useState(null);
  const [shareId, setShareId] = useState(null);
  const [adding, setAdding] = useState(false);
  const [isAdmin, setIsAdmin] = useState(false);
  const [showLogin, setShowLogin] = useState(false);
  const [loginEmail, setLoginEmail] = useState("");
  const [loginPwd, setLoginPwd] = useState("");

  const cfg = SECTIONS[section];
  const inv = section === 'relojes' ? watches : jewelry;
  const setInv = section === 'relojes' ? setWatches : setJewelry;
  const loading = section === 'relojes' ? loadingWatches : loadingJewelry;

  // Initial load both
  useEffect(() => {
    (async () => {
      const { data, error } = await supabaseClient.from('watches').select('*').order('created_at', { ascending: false });
      if (!error) setWatches(data || []);
      setLoadingWatches(false);
    })();
    (async () => {
      const { data, error } = await supabaseClient.from('jewelry').select('*').order('created_at', { ascending: false });
      if (!error) setJewelry(data || []);
      setLoadingJewelry(false);
    })();
  }, []);

  // Auth
  useEffect(() => {
    supabaseClient.auth.getSession().then(({ data: { session } }) => setIsAdmin(!!session));
    const { data: { subscription } } = supabaseClient.auth.onAuthStateChange((_event, session) => setIsAdmin(!!session));
    return () => subscription.unsubscribe();
  }, []);

  // Realtime both
  useEffect(() => {
    const wc = supabaseClient.channel('watches-changes')
      .on('postgres_changes', { event: '*', schema: 'public', table: 'watches' }, (payload) => {
        if (payload.eventType === 'INSERT') setWatches(c => c.some(w => w.id === payload.new.id) ? c : [payload.new, ...c]);
        else if (payload.eventType === 'UPDATE') setWatches(c => c.map(w => w.id === payload.new.id ? payload.new : w));
        else if (payload.eventType === 'DELETE') setWatches(c => c.filter(w => w.id !== payload.old.id));
      }).subscribe();
    const jc = supabaseClient.channel('jewelry-changes')
      .on('postgres_changes', { event: '*', schema: 'public', table: 'jewelry' }, (payload) => {
        if (payload.eventType === 'INSERT') setJewelry(c => c.some(w => w.id === payload.new.id) ? c : [payload.new, ...c]);
        else if (payload.eventType === 'UPDATE') setJewelry(c => c.map(w => w.id === payload.new.id ? payload.new : w));
        else if (payload.eventType === 'DELETE') setJewelry(c => c.filter(w => w.id !== payload.old.id));
      }).subscribe();
    return () => { supabaseClient.removeChannel(wc); supabaseClient.removeChannel(jc); };
  }, []);

  const tryLogin = async () => {
    const { error } = await supabaseClient.auth.signInWithPassword({ email: loginEmail.trim(), password: loginPwd });
    if (error) alert("Email o contraseña incorrectos");
    else { setShowLogin(false); setLoginEmail(""); setLoginPwd(""); }
  };
  const logout = async () => { await supabaseClient.auth.signOut(); };

  // URL hash sync — outgoing
  useEffect(() => {
    if (openId) {
      window.history.replaceState(null, "", "#" + openId);
    } else if (section === 'joyeria') {
      window.history.replaceState(null, "", "#joyeria");
    } else if (window.location.hash && window.location.hash !== "#admin") {
      window.history.replaceState(null, "", window.location.pathname);
    }
  }, [openId, section]);

  // Reset filters when switching section
  useEffect(() => {
    setSearch("");
    setStatus("Todos");
    setPriceIdx(0);
  }, [section]);

  const brands = useMemo(() => ["Todas", ...Array.from(new Set(watches.map(w => w.brand).filter(Boolean))).sort()], [watches]);
  const families = useMemo(() => {
    const list = watches.filter(w => brand === "Todas" || w.brand === brand).map(w => w.family).filter(Boolean);
    return ["Todas", ...Array.from(new Set(list)).sort()];
  }, [watches, brand]);
  const materials = useMemo(() => ["Todos", ...Array.from(new Set(watches.map(w => w.material).filter(Boolean))).sort()], [watches]);

  const types = useMemo(() => ["Todos", ...Array.from(new Set(jewelry.map(w => w.type).filter(Boolean))).sort()], [jewelry]);
  const jMaterials = useMemo(() => ["Todos", ...Array.from(new Set(jewelry.map(w => w.material).filter(Boolean))).sort()], [jewelry]);
  const stones = useMemo(() => ["Todas", ...Array.from(new Set(jewelry.map(w => w.stone).filter(Boolean))).sort()], [jewelry]);

  const filtered = useMemo(() => {
    return inv.filter(w => {
      if (search) {
        const s = search.toLowerCase();
        const haystack = section === 'relojes'
          ? `${w.brand || ""} ${w.model || ""} ${w.ref || ""} ${w.family || ""}`
          : `${w.type || ""} ${w.model || ""} ${w.material || ""} ${w.stone || ""}`;
        if (!haystack.toLowerCase().includes(s)) return false;
      }
      if (section === 'relojes') {
        if (brand !== "Todas" && w.brand !== brand) return false;
        if (family !== "Todas" && w.family !== family) return false;
        if (material !== "Todos" && w.material !== material) return false;
      } else {
        if (jType !== "Todos" && w.type !== jType) return false;
        if (jMaterial !== "Todos" && w.material !== jMaterial) return false;
        if (jStone !== "Todas" && w.stone !== jStone) return false;
      }
      if (status !== "Todos" && w.status !== status) return false;
      const range = PRICE_BUCKETS[priceIdx];
      const priceMXN = toMXN(w);
      if (priceMXN < range.min || priceMXN > range.max) return false;
      return true;
    });
  }, [inv, section, search, brand, family, material, jType, jMaterial, jStone, status, priceIdx]);

  const totals = useMemo(() => {
    const disp = inv.filter(w => w.status === "Disponible");
    const res = inv.filter(w => w.status === "Reservado");
    const value = disp.reduce((s, w) => s + toMXN(w), 0);
    return { total: inv.length, disp: disp.length, res: res.length, value };
  }, [inv]);

  const updateItem = async (id, patch) => {
    setInv(curr => curr.map(w => w.id === id ? { ...w, ...patch } : w));
    const { id: _i, created_at, updated_at, ...clean } = patch;
    const { error } = await supabaseClient.from(cfg.table).update(clean).eq('id', id);
    if (error) { console.error(error); alert("Error guardando: " + error.message); }
  };
  const deleteItem = async (id) => {
    setInv(curr => curr.filter(w => w.id !== id));
    setEditId(null); setOpenId(null);
    const { error } = await supabaseClient.from(cfg.table).delete().eq('id', id);
    if (error) alert("Error eliminando: " + error.message);
  };
  const addItem = async (w) => {
    const id = cfg.idPrefix + Date.now().toString(36);
    const row = { ...w, id };
    setInv(curr => [row, ...curr]);
    setAdding(false);
    setEditId(id);
    const { error } = await supabaseClient.from(cfg.table).insert(row);
    if (error) {
      setInv(curr => curr.filter(x => x.id !== id));
      setEditId(null);
      alert("Error añadiendo: " + error.message);
    }
  };

  const clearFilters = () => {
    setSearch(""); setStatus("Todos"); setPriceIdx(0);
    if (section === 'relojes') { setBrand("Todas"); setFamily("Todas"); setMaterial("Todos"); }
    else { setJType("Todos"); setJMaterial("Todos"); setJStone("Todas"); }
  };

  return (
    <>
      <header className="header">
        <div className="header-inner">
          <img className="logo-img" src="assets/savaar-logo-black.png" alt="SAVAAR" />
          <div className="header-stats">
            <div className="stat"><span className="stat-num">{totals.total}</span><span className="stat-label">En {cfg.label.toLowerCase()}</span></div>
            <div className="stat"><span className="stat-num" style={{ color: "var(--green)" }}>{totals.disp}</span><span className="stat-label">Disponibles</span></div>
            {isAdmin && <div className="stat"><span className="stat-num" style={{ color: "var(--amber)" }}>{totals.res}</span><span className="stat-label">Reservados</span></div>}
            {isAdmin && <div className="stat"><span className="stat-num">{FMT_SHORT(Math.round(totals.value), "MXN")}</span><span className="stat-label">Valor disponible (MXN)</span></div>}
          </div>
          <div className="header-actions">
            <button className="btn btn-ghost btn-sm" onClick={() => window.print()} title="Descargar PDF">⤓ PDF</button>
            {isAdmin && <button className="btn btn-primary btn-sm" onClick={() => setAdding(true)}><Icon name="plus" size={14} /> Añadir {cfg.singular}</button>}
            {isAdmin
              ? <button className="btn btn-ghost btn-sm" onClick={logout} title="Cerrar sesión admin">Salir</button>
              : <button className="btn btn-ghost btn-sm" onClick={() => setShowLogin(true)} title="Acceso administrador">Login</button>}
          </div>
        </div>
      </header>

      <nav className="section-tabs-wrap">
        <div className="section-tabs">
          <button className={`tab ${section === 'relojes' ? 'active' : ''}`} onClick={() => setSection('relojes')}>Relojes</button>
          <button className={`tab ${section === 'joyeria' ? 'active' : ''}`} onClick={() => setSection('joyeria')}>Joyería fina</button>
        </div>
      </nav>

      <div className="toolbar">
        <div className="toolbar-inner">
          <div className="search">
            <span className="search-icon"><Icon name="search" size={14} /></span>
            <input placeholder={section === 'relojes' ? "Buscar marca, modelo o referencia…" : "Buscar tipo, modelo, material…"} value={search} onChange={e => setSearch(e.target.value)} />
          </div>
          {section === 'relojes' ? (
            <>
              <div className="filter-group">
                <label className="filter-label">Marca</label>
                <select className="select" value={brand} onChange={e => { setBrand(e.target.value); setFamily("Todas"); }}>
                  {brands.map(b => <option key={b}>{b}</option>)}
                </select>
              </div>
              <div className="filter-group">
                <label className="filter-label">Modelo</label>
                <select className="select" value={family} onChange={e => setFamily(e.target.value)}>
                  {families.map(f => <option key={f}>{f}</option>)}
                </select>
              </div>
              <div className="filter-group">
                <label className="filter-label">Metal</label>
                <select className="select" value={material} onChange={e => setMaterial(e.target.value)}>
                  {materials.map(m => <option key={m}>{m}</option>)}
                </select>
              </div>
            </>
          ) : (
            <>
              <div className="filter-group">
                <label className="filter-label">Tipo</label>
                <select className="select" value={jType} onChange={e => setJType(e.target.value)}>
                  {types.map(t => <option key={t}>{t}</option>)}
                </select>
              </div>
              <div className="filter-group">
                <label className="filter-label">Material</label>
                <select className="select" value={jMaterial} onChange={e => setJMaterial(e.target.value)}>
                  {jMaterials.map(m => <option key={m}>{m}</option>)}
                </select>
              </div>
              <div className="filter-group">
                <label className="filter-label">Piedra</label>
                <select className="select" value={jStone} onChange={e => setJStone(e.target.value)}>
                  {stones.map(s => <option key={s}>{s}</option>)}
                </select>
              </div>
            </>
          )}
          <div className="filter-group">
            <label className="filter-label">Precio</label>
            <select className="select" value={priceIdx} onChange={e => setPriceIdx(Number(e.target.value))}>
              {PRICE_BUCKETS.map((b, i) => <option key={i} value={i}>{b.label}</option>)}
            </select>
          </div>
          <div className="filter-group">
            <label className="filter-label">Disponibilidad</label>
            <select className="select" value={status} onChange={e => setStatus(e.target.value)}>
              {["Todos", "Disponible", "Reservado", "Vendido"].map(s => <option key={s}>{s}</option>)}
            </select>
          </div>
          <button className="btn btn-ghost btn-sm filter-clear" onClick={clearFilters}>Limpiar</button>
          <div className="toolbar-divider" />
          <div className="view-toggle">
            <button className={view === "grid" ? "active" : ""} onClick={() => setView("grid")} title="Cuadrícula"><Icon name="grid" size={14} /></button>
            <button className={view === "list" ? "active" : ""} onClick={() => setView("list")} title="Lista"><Icon name="list" size={14} /></button>
          </div>
          <span className="toolbar-result">{filtered.length} {filtered.length === 1 ? "pieza" : "piezas"}</span>
        </div>
      </div>

      <main className="main">
        {loading ? (
          <div className="empty"><h3>Cargando…</h3></div>
        ) : filtered.length === 0 ? (
          <div className="empty">
            <h3>{inv.length === 0 ? "Aún no hay piezas en esta sección" : "Sin resultados"}</h3>
            <p>{inv.length === 0 && isAdmin ? `Añade tu primera pieza con el botón "Añadir ${cfg.singular}"` : "Ajusta los filtros o limpia la búsqueda."}</p>
          </div>
        ) : view === "grid" ? (
          <div className="grid">
            {filtered.map(w => (
              <Card key={w.id} item={w} section={section}
                isAdmin={isAdmin}
                onOpen={() => setOpenId(w.id)}
                onEdit={() => setEditId(w.id)}
              />
            ))}
          </div>
        ) : (
          <ListView items={filtered} section={section} onOpen={setOpenId} onEdit={setEditId} onShare={setShareId} />
        )}
      </main>

      {openId && <Detail item={inv.find(w => w.id === openId)} section={section}
        isAdmin={isAdmin}
        onClose={() => setOpenId(null)}
        onEdit={() => { setEditId(openId); setOpenId(null); }}
        onShare={() => setShareId(openId)}
        onUpdate={(patch) => updateItem(openId, patch)}
        bucket={cfg.bucket}
      />}
      {isAdmin && editId && <Editor item={inv.find(w => w.id === editId)} section={section}
        onClose={() => setEditId(null)}
        onSave={(patch) => { updateItem(editId, patch); setEditId(null); }}
        onDelete={() => deleteItem(editId)}
        onImageUploaded={(url) => updateItem(editId, { img: url })}
        bucket={cfg.bucket}
      />}
      {isAdmin && adding && <Editor item={null} section={section}
        onClose={() => setAdding(false)}
        onSave={addItem}
        bucket={cfg.bucket}
      />}
      {shareId && <ShareModal item={inv.find(w => w.id === shareId)} section={section} onClose={() => setShareId(null)} />}
      {showLogin && <LoginModal
        email={loginEmail}
        pwd={loginPwd}
        onEmailChange={setLoginEmail}
        onPwdChange={setLoginPwd}
        onSubmit={tryLogin}
        onClose={() => { setShowLogin(false); setLoginEmail(""); setLoginPwd(""); }}
      />}

      {isAdmin && (
        <button className="fab" onClick={() => setAdding(true)} title={`Añadir ${cfg.singular}`}>
          <Icon name="plus" size={22} />
        </button>
      )}
    </>
  );
}

const Card = ({ item, section, isAdmin, onOpen, onEdit }) => {
  const [activeIdx, setActiveIdx] = useState(0);
  const wa = window.SAVAAR_WHATSAPP;
  const isJewelry = section === 'joyeria';
  const title = isJewelry
    ? (item.type ? `${item.type}${item.model ? ' · ' + item.model : ''}` : (item.model || 'Sin título'))
    : item.model;
  const msg = encodeURIComponent(
    isJewelry
      ? `Hola SAVAAR, me interesa cotizar la pieza ${item.type || ''} ${item.model || ''}.`
      : `Hola SAVAAR, me interesa cotizar el ${item.brand} ${item.model} (Ref. ${item.ref}).`
  );
  const waUrl = `https://wa.me/${wa}?text=${msg}`;
  const sCls = (item.status || "").toLowerCase();
  const brandLabel = isJewelry ? "SAVAAR" : item.brand;
  const images = getImages(item);
  const cover = images[activeIdx] || images[0] || "";
  const prev = (e) => { e.stopPropagation(); setActiveIdx(i => (i - 1 + images.length) % images.length); };
  const next = (e) => { e.stopPropagation(); setActiveIdx(i => (i + 1) % images.length); };
  return (
    <article className="card" onClick={onOpen}>
      <div className="card-img-wrap">
        {cover ? <img src={cover} alt={title} loading="lazy" /> : <div className="card-img-empty">Sin foto</div>}
        <img className="card-watermark" src="assets/savaar-logo-white.png" alt="" aria-hidden="true" />
        <span className={`status-pill ${sCls}`}><span className="dot" />{item.status}</span>
        {images.length > 1 && (
          <>
            <button className="card-nav prev" onClick={prev} aria-label="Anterior">‹</button>
            <button className="card-nav next" onClick={next} aria-label="Siguiente">›</button>
            <span className="card-counter">{activeIdx + 1} / {images.length}</span>
          </>
        )}
        {isAdmin && <button className="card-edit-handle" onClick={e => { e.stopPropagation(); onEdit(); }} title="Editar"><Icon name="edit" size={13} /></button>}
      </div>
      <div className="card-body">
        <div className="card-brand">{brandLabel}</div>
        <h3 className="card-model">{title}</h3>
        <div className="card-meta">
          {isJewelry ? (
            <>
              <span>{item.material || ""}</span>
              <span>{item.stone && item.stone !== 'Sin piedra' ? `${item.stone}${item.carats ? ' ' + item.carats + 'ct' : ''}` : ''}</span>
            </>
          ) : (
            <>
              <span className="card-ref">{item.ref}</span>
              <span>{item.year} · {item.size}mm</span>
            </>
          )}
        </div>
        <div className="card-price-row">
          <div className="card-price">{FMT_SHORT(item.price, item.currency)}<span className="card-price-usd">{item.currency || "MXN"}</span></div>
        </div>
        <div className="card-actions">
          <a className="wa-btn" href={waUrl} target="_blank" rel="noreferrer" onClick={e => e.stopPropagation()}>
            <Icon name="wa" size={13} /> Cotizar
          </a>
        </div>
      </div>
    </article>
  );
};

const ListView = ({ items, section, onOpen, onEdit, onShare }) => {
  const isJewelry = section === 'joyeria';
  return (
    <div className="list">
      <div className="list-row list-head">
        <div></div>
        <div>Modelo</div>
        <div>{isJewelry ? "Tipo / Material" : "Marca / Familia"}</div>
        <div>{isJewelry ? "Piedra" : "Referencia"}</div>
        <div>{isJewelry ? "Quilates" : "Año"}</div>
        <div>Estado</div>
        <div>Precio</div>
        <div></div>
      </div>
      {items.map(w => {
        const wa = window.SAVAAR_WHATSAPP;
        const msg = encodeURIComponent(
          isJewelry
            ? `Hola SAVAAR, me interesa cotizar la pieza ${w.type || ''} ${w.model || ''}.`
            : `Hola SAVAAR, me interesa cotizar el ${w.brand} ${w.model} (Ref. ${w.ref}).`
        );
        return (
          <div key={w.id} className="list-row" onClick={() => onOpen(w.id)}>
            <img src={w.img} alt="" />
            <div className="list-cell-model">{isJewelry ? (w.type + (w.model ? ' · ' + w.model : '')) : w.model}</div>
            <div>
              <div className="list-cell-brand">{isJewelry ? "SAVAAR" : w.brand}</div>
              <div style={{ fontSize: 12 }}>{isJewelry ? w.material : w.family}</div>
            </div>
            <div className="list-cell-ref">{isJewelry ? (w.stone && w.stone !== 'Sin piedra' ? w.stone : '—') : w.ref}</div>
            <div>{isJewelry ? (w.carats ? w.carats + 'ct' : '—') : w.year}</div>
            <div><span className={`status-pill ${(w.status || "").toLowerCase()}`}><span className="dot" />{w.status}</span></div>
            <div className="list-cell-price">{FMT_SHORT(w.price, w.currency)} <span style={{ fontSize: 10, opacity: 0.55 }}>{w.currency || "MXN"}</span></div>
            <div className="list-actions">
              <a className="share-btn" href={`https://wa.me/${wa}?text=${msg}`} target="_blank" rel="noreferrer" onClick={e => e.stopPropagation()} title="WhatsApp" style={{ background: "#25d366", color: "white", border: "none" }}>
                <Icon name="wa" size={14} />
              </a>
            </div>
          </div>
        );
      })}
    </div>
  );
};

const Detail = ({ item, section, isAdmin, onClose, onEdit, onShare, onUpdate, bucket }) => {
  const [uploading, setUploading] = useState(false);
  const [activeImg, setActiveImg] = useState(0);
  useEffect(() => {
    const onEsc = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onEsc);
    document.body.style.overflow = "hidden";
    return () => { window.removeEventListener("keydown", onEsc); document.body.style.overflow = ""; };
  }, []);
  useEffect(() => { setActiveImg(0); }, [item?.id]);
  if (!item) return null;
  const isJewelry = section === 'joyeria';
  const wa = window.SAVAAR_WHATSAPP;
  const title = isJewelry ? (item.type + (item.model ? ' · ' + item.model : '')) : item.model;
  const images = getImages(item);
  const msg = encodeURIComponent(
    isJewelry
      ? `Hola SAVAAR, me interesa cotizar la pieza ${item.type || ''} ${item.model || ''} — ${FMT(item.price, item.currency)}.`
      : `Hola SAVAAR, me interesa cotizar el ${item.brand} ${item.model} (Ref. ${item.ref}) — ${FMT(item.price, item.currency)}.`
  );

  const onUpload = async (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setUploading(true);
    try {
      const url = await uploadImageTo(file, bucket, item.id);
      const newImages = [...images, url];
      onUpdate({ images: newImages, img: newImages[0] });
      setActiveImg(newImages.length - 1);
    } catch (err) {
      alert("Error subiendo foto: " + err.message);
    } finally { setUploading(false); }
  };

  const specs = isJewelry
    ? [
        ["Tipo", item.type],
        ["Material", item.material],
        ["Piedra", item.stone],
        ["Quilates", item.carats ? item.carats + " ct" : "—"],
        ["Marca", "SAVAAR"],
      ]
    : [
        ["Marca", item.brand],
        ["Familia", item.family],
        ["Referencia", item.ref],
        ["Año", item.year],
        ["Tamaño", (item.size || "—") + " mm"],
        ["Material", item.material],
        ["Movimiento", item.movement],
        ["Reserva", item.reserve > 0 ? item.reserve + " hrs" : "—"],
        ["Condición", item.condition],
        ["Set", item.set],
      ];

  return (
    <>
      <div className="detail-bg" onClick={onClose} />
      <aside className="detail-panel">
        <div className="detail-header">
          <button className="btn btn-ghost btn-icon btn-sm" onClick={onClose}><Icon name="close" size={16} /></button>
          <h2>Detalle de pieza</h2>
          <button className="btn btn-ghost btn-sm" onClick={onShare}><Icon name="share" size={13} /> Compartir</button>
          {isAdmin && <button className="btn btn-ghost btn-sm" onClick={onEdit}><Icon name="edit" size={13} /> Editar</button>}
        </div>
        <div className="detail-img-wrap">
          {images.length > 0 ? <img src={images[activeImg]} alt={title} /> : <div className="card-img-empty">Sin foto</div>}
          {images.length > 1 && (
            <>
              <button className="gallery-nav prev" onClick={() => setActiveImg(i => (i - 1 + images.length) % images.length)} aria-label="Anterior">‹</button>
              <button className="gallery-nav next" onClick={() => setActiveImg(i => (i + 1) % images.length)} aria-label="Siguiente">›</button>
              <span className="gallery-counter">{activeImg + 1} / {images.length}</span>
              <div className="detail-thumbs">
                {images.map((url, i) => (
                  <button key={i} className={`detail-thumb ${i === activeImg ? 'active' : ''}`} onClick={() => setActiveImg(i)}>
                    <img src={url} alt="" />
                  </button>
                ))}
              </div>
            </>
          )}
          {isAdmin && (
            <label className="detail-img-upload">
              <Icon name="upload" size={13} /> {uploading ? "Subiendo…" : (images.length > 0 ? "Añadir foto" : "Subir foto")}
              <input type="file" accept="image/*" onChange={onUpload} hidden disabled={uploading} />
            </label>
          )}
        </div>
        <div className="detail-body">
          <div className="detail-brand">{isJewelry ? "SAVAAR" + (item.type ? " · " + item.type : "") : (item.brand + " · " + (item.family || ""))}</div>
          <h1 className="detail-model">{isJewelry ? (item.model || item.type) : item.model}</h1>
          {!isJewelry && <div className="detail-ref">REF. {item.ref}</div>}

          <div className="detail-price-row">
            <div className="detail-price">{FMT_SHORT(item.price, item.currency)}<span className="detail-price-usd">{item.currency || "MXN"}</span></div>
            {isAdmin ? (
              <div className="detail-status-select">
                {["Disponible", "Reservado", "Vendido"].map(s => (
                  <button key={s}
                    className={`status-chip ${item.status === s ? "active " + s.toLowerCase() : ""}`}
                    onClick={() => onUpdate({ status: s })}>
                    {s}
                  </button>
                ))}
              </div>
            ) : (
              <span className={`status-pill ${(item.status || "").toLowerCase()}`}><span className="dot" />{item.status}</span>
            )}
          </div>

          <div className="detail-specs">
            {specs.map(([k, v], i) => (
              <div className="spec" key={i}>
                <div className="spec-key">{k}</div>
                <div className="spec-val">{v || "—"}</div>
              </div>
            ))}
          </div>
        </div>
        <div className="detail-actions">
          <a className="wa-btn" href={`https://wa.me/${wa}?text=${msg}`} target="_blank" rel="noreferrer" style={{ flex: 1 }}>
            <Icon name="wa" size={16} /> Cotizar por WhatsApp
          </a>
          <button className="btn btn-ghost" onClick={onShare} style={{ height: 44 }}><Icon name="share" size={14} /></button>
        </div>
      </aside>
    </>
  );
};

const Editor = ({ item, section, onClose, onSave, onDelete, onImageUploaded, bucket }) => {
  const isNew = !item;
  const isJewelry = section === 'joyeria';
  const defaultForm = isJewelry
    ? { type: "Anillo", brand: "SAVAAR", model: "", material: "Oro Amarillo 18k", stone: "Diamante", carats: 0, price: 0, currency: "MXN", status: "Disponible", img: "", images: [] }
    : { brand: "", family: "", model: "", ref: "", year: new Date().getFullYear(), size: 40, material: "Acero", movement: "", reserve: 70, condition: "Como nuevo", set: "Full set", price: 0, currency: "MXN", status: "Disponible", img: "", images: [] };
  const [form, setForm] = useState(() => {
    const base = item || defaultForm;
    const imgs = (base.images && base.images.length > 0) ? base.images : (base.img ? [base.img] : []);
    return { ...base, images: imgs, img: imgs[0] || "" };
  });
  const [uploading, setUploading] = useState(false);

  useEffect(() => { document.body.style.overflow = "hidden"; return () => { document.body.style.overflow = ""; }; }, []);

  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const persistImages = (arr) => {
    if (!isNew && onImageUploaded) onImageUploaded({ images: arr, img: arr[0] || "" });
  };
  const onUpload = async (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setUploading(true);
    try {
      const tempId = form.id || (isJewelry ? 'j' : 'w') + Date.now().toString(36);
      const url = await uploadImageTo(file, bucket, tempId);
      const newImages = [...(form.images || []), url];
      setForm(f => ({ ...f, images: newImages, img: newImages[0] }));
      persistImages(newImages);
    } catch (err) {
      alert("Error subiendo foto: " + err.message);
    } finally { setUploading(false); }
  };
  const removePhoto = (i) => {
    const arr = (form.images || []).filter((_, idx) => idx !== i);
    setForm(f => ({ ...f, images: arr, img: arr[0] || "" }));
    persistImages(arr);
  };
  const setCover = (i) => {
    const arr = [...(form.images || [])];
    const [chosen] = arr.splice(i, 1);
    arr.unshift(chosen);
    setForm(f => ({ ...f, images: arr, img: arr[0] || "" }));
    persistImages(arr);
  };

  const fields = isJewelry
    ? [
        ["type", "Tipo", "select", JEWELRY_TYPES],
        ["model", "Modelo / descripción", "text"],
        ["material", "Material", "select", JEWELRY_MATERIALS],
        ["stone", "Piedra principal", "select", JEWELRY_STONES],
        ["carats", "Quilates (ct)", "number"],
        ["price", "Precio", "money"],
        ["currency", "Moneda", "select", ["MXN", "USD"]],
        ["status", "Estado", "select", ["Disponible", "Reservado", "Vendido"]],
      ]
    : [
        ["brand", "Marca", "text"],
        ["family", "Familia", "text"],
        ["model", "Modelo", "text"],
        ["ref", "Referencia", "text"],
        ["year", "Año", "number"],
        ["size", "Tamaño (mm)", "number"],
        ["material", "Material", "text"],
        ["movement", "Movimiento", "text"],
        ["reserve", "Reserva (hrs)", "number"],
        ["condition", "Condición", "select", ["Nuevo", "Como nuevo", "Usado"]],
        ["set", "Set", "select", ["Full set", "Solo reloj", "Reloj + caja", "Reloj + papeles", "Caja y papeles"]],
        ["price", "Precio", "money"],
        ["currency", "Moneda", "select", ["MXN", "USD"]],
        ["status", "Estado", "select", ["Disponible", "Reservado", "Vendido"]],
      ];

  return (
    <>
      <div className="detail-bg" onClick={onClose} />
      <aside className="detail-panel">
        <div className="detail-header">
          <button className="btn btn-ghost btn-icon btn-sm" onClick={onClose}><Icon name="close" size={16} /></button>
          <h2>{isNew ? `Añadir ${isJewelry ? 'pieza' : 'reloj'}` : `Editar ${isJewelry ? 'pieza' : 'reloj'}`}</h2>
        </div>
        <div className="detail-img-wrap">
          {form.images?.[0] ? <img src={form.images[0]} alt="" /> : <div className="card-img-empty">Sin foto — sube una</div>}
          <label className="detail-img-upload">
            <Icon name="upload" size={13} /> {uploading ? "Subiendo…" : (form.images?.length > 0 ? "Añadir foto" : "Subir foto")}
            <input type="file" accept="image/*" onChange={onUpload} hidden disabled={uploading} />
          </label>
        </div>
        {form.images?.length > 0 && (
          <div className="editor-thumbs">
            {form.images.map((url, i) => (
              <div key={i} className="editor-thumb">
                <img src={url} alt="" />
                {i === 0 && <span className="editor-thumb-cover">Portada</span>}
                {i !== 0 && <button className="editor-thumb-action" onClick={() => setCover(i)} title="Hacer portada">★</button>}
                <button className="editor-thumb-remove" onClick={() => removePhoto(i)} title="Quitar foto">×</button>
              </div>
            ))}
          </div>
        )}
        <div className="detail-body">
          {fields.map(([k, label, type, opts]) => (
            <div className="edit-row" key={k}>
              <label>{label}</label>
              {type === "select" ? (
                <select value={form[k] || ""} onChange={e => set(k, e.target.value)}>
                  {opts.map(o => <option key={o}>{o}</option>)}
                </select>
              ) : type === "money" ? (
                <input
                  type="text"
                  inputMode="numeric"
                  value={form[k] ? Number(form[k]).toLocaleString("en-US") : ""}
                  onChange={e => {
                    const digits = e.target.value.replace(/\D/g, "");
                    set(k, digits === "" ? 0 : parseInt(digits, 10));
                  }}
                  placeholder="0"
                />
              ) : (
                <input
                  type={type}
                  value={form[k] ?? ""}
                  onChange={e => set(k, type === "number" ? Number(e.target.value) : e.target.value)}
                />
              )}
            </div>
          ))}
          {!isNew && (
            <div className="danger-zone">
              <span className="label">Eliminar permanentemente</span>
              <button className="btn-danger" onClick={() => { if (confirm("¿Eliminar esta pieza del inventario?")) onDelete(); }}>
                <Icon name="trash" size={12} /> Eliminar
              </button>
            </div>
          )}
        </div>
        <div className="detail-actions">
          <button className="btn btn-ghost" onClick={onClose} style={{ flex: 1, height: 44, justifyContent: "center" }}>Cancelar</button>
          <button className="btn btn-primary" onClick={() => onSave(form)} style={{ flex: 2, height: 44, justifyContent: "center" }} disabled={uploading}>
            <Icon name="check" size={14} /> {isNew ? "Añadir al inventario" : "Guardar cambios"}
          </button>
        </div>
      </aside>
    </>
  );
};

const ShareModal = ({ item, section, onClose }) => {
  const isJewelry = section === 'joyeria';
  const wa = window.SAVAAR_WHATSAPP;
  const url = window.location.origin + window.location.pathname + "#" + item.id;
  const msg = isJewelry
    ? `*SAVAAR · ${item.type || 'Joyería'}*\n${item.model || ''}\n${item.material || ''}${item.stone && item.stone !== 'Sin piedra' ? ' · ' + item.stone : ''}${item.carats ? ' ' + item.carats + 'ct' : ''}\n*${FMT(item.price, item.currency)}* — ${item.status}\n\n${url}`
    : `*${item.brand}*\n${item.model}\nRef. ${item.ref}\n${item.year} · ${item.size}mm · ${item.material}\n*${FMT(item.price, item.currency)}* — ${item.status}\n\n${url}`;
  const [copied, setCopied] = useState(false);
  const copy = (text) => navigator.clipboard?.writeText(text).then(() => { setCopied(true); setTimeout(() => setCopied(false), 1500); });

  return (
    <div className="modal-bg" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h3>Compartir pieza</h3>
          <p>{isJewelry ? `SAVAAR · ${item.type}` : `${item.brand} · ${item.model}`}</p>
        </div>
        <div className="modal-body">
          <div className="share-link">{url}</div>
          <div className="share-options">
            <a className="share-option" href={`https://wa.me/?text=${encodeURIComponent(msg)}`} target="_blank" rel="noreferrer">
              <Icon name="wa" size={20} /> WhatsApp
            </a>
            <button className="share-option" onClick={() => copy(msg)}>
              <Icon name={copied ? "check" : "copy"} size={20} /> {copied ? "Copiado" : "Copiar texto"}
            </button>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn btn-ghost" onClick={() => copy(url)}><Icon name="copy" size={13} /> Copiar link</button>
          <button className="btn btn-primary" onClick={onClose}>Cerrar</button>
        </div>
      </div>
    </div>
  );
};

const LoginModal = ({ email, pwd, onEmailChange, onPwdChange, onSubmit, onClose }) => {
  useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);
  const inputStyle = { width: "100%", height: 38, padding: "0 12px", border: "1px solid var(--line-strong)", borderRadius: "var(--radius)", fontSize: 13, outline: "none", marginBottom: 8 };
  return (
    <div className="modal-bg" onClick={onClose}>
      <div className="modal modal-sm" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h3>Acceso administrador</h3>
          <p>Inicia sesión para editar el inventario.</p>
        </div>
        <div className="modal-body">
          <input type="email" autoFocus value={email} onChange={e => onEmailChange(e.target.value)} placeholder="Email" style={inputStyle} onKeyDown={e => { if (e.key === "Enter") onSubmit(); }} />
          <input type="password" value={pwd} onChange={e => onPwdChange(e.target.value)} placeholder="Contraseña" style={inputStyle} onKeyDown={e => { if (e.key === "Enter") onSubmit(); }} />
        </div>
        <div className="modal-foot">
          <button className="btn btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn btn-primary" onClick={onSubmit}>Entrar</button>
        </div>
      </div>
    </div>
  );
};

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
