/* ============ Builder page (Arma tu propia pieza) ============ */
function BuilderPage({ store, categoryId, navigate }) {
  const cat = store.categories.find(c => c.id === categoryId);
  const builder = store.builder || { slots: [], options: [], bases: [] };

  const slots = (builder.slots || [])
    .filter(s => s.category_id === categoryId)
    .sort((a, b) => (a.sort_order || 0) - (b.sort_order || 0));
  const base = (builder.bases || []).find(b => b.category_id === categoryId)
    || { base_price: 0, base_image: null };

  // selection[slotId] = optionId (image slots) or string (text slots).
  const [selection, setSelection] = useState({});
  const [focusedOptionId, setFocusedOptionId] = useState(null);
  const [lightboxUrl, setLightboxUrl] = useState(null);

  const optionImages = (o) => {
    if (!o) return [];
    if (Array.isArray(o.images) && o.images.length) return o.images.filter(Boolean);
    return o.image ? [o.image] : [];
  };

  const allOptionsBySlot = (slotId) =>
    (builder.options || [])
      .filter(o => o.slot_id === slotId)
      .sort((a, b) => (a.sort_order || 0) - (b.sort_order || 0));

  // Initial defaults respecting the parent → child visibility chain.
  useEffect(() => {
    const init = {};
    slots.forEach(s => {
      if (s.type === "text") { init[s.id] = ""; return; }
      const opts = allOptionsBySlot(s.id);
      const visible = opts.filter(o =>
        !o.parent_option_id || Object.values(init).includes(o.parent_option_id)
      );
      if (visible.length) init[s.id] = visible[0].id;
    });
    setSelection(init);
    setFocusedOptionId(null);
  }, [categoryId, slots.length, (builder.options || []).length]);

  // Re-validate dependent selections whenever the user picks something:
  // if a chosen option becomes invalid because its parent changed, swap it
  // for the first visible option.
  useEffect(() => {
    let next = { ...selection };
    let changed = false;
    slots.forEach(s => {
      if (s.type !== "image") return;
      const opts = allOptionsBySlot(s.id);
      if (!opts.length) return;
      const visible = opts.filter(o =>
        !o.parent_option_id || Object.values(next).includes(o.parent_option_id)
      );
      const current = next[s.id];
      if (visible.length && !visible.find(o => o.id === current)) {
        next[s.id] = visible[0].id;
        changed = true;
      } else if (!visible.length && current) {
        next[s.id] = null;
        changed = true;
      }
    });
    if (changed) setSelection(next);
  }, [selection]);

  // Empty state
  if (!cat || !cat.has_builder || slots.length === 0) {
    return (
      <main>
        <div className="section" style={{ paddingTop: 64, paddingBottom: 96, textAlign: "center" }}>
          <div className="eyebrow">Arma tu propia pieza</div>
          <h1 style={{
            fontFamily: "var(--serif)", fontWeight: 400,
            fontSize: "clamp(28px, 5vw, 56px)", color: "var(--burgundy)",
            margin: "12px 0 16px",
          }}>
            Próximamente
          </h1>
          <p style={{ color: "var(--ink-2)", maxWidth: 460, margin: "0 auto 28px" }}>
            {cat
              ? `El configurador para ${cat.name.toLowerCase()} todavía no está disponible. Vuelve pronto.`
              : "Esta categoría no existe."}
          </p>
          <button className="btn btn-ghost" onClick={() => navigate("/")}>Volver al inicio</button>
        </div>
      </main>
    );
  }

  // Compute what's visible/chosen for each slot, honoring dependencies.
  const chosen = slots.map(s => {
    if (s.type === "text") {
      return { slot: s, options: [], visible: [], text: selection[s.id] || "" };
    }
    const opts = allOptionsBySlot(s.id);
    const visible = opts.filter(o =>
      !o.parent_option_id || Object.values(selection).includes(o.parent_option_id)
    );
    const option = visible.find(o => o.id === selection[s.id]) || visible[0] || null;
    return { slot: s, options: opts, visible, option };
  });

  const total = chosen.reduce((sum, c) => {
    if (c.slot.type === "text") return sum;
    return sum + (c.option ? Number(c.option.price_modifier) || 0 : 0);
  }, Number(base.base_price) || 0);

  const missing = chosen.find(c => {
    if (!c.slot.required) return false;
    if (c.slot.type === "text") return !c.text.trim();
    return !c.option;
  });

  // Focused option for the detail gallery — defaults to the last picked
  // image-slot option, or the very first one on initial load.
  const focused = (() => {
    if (focusedOptionId) {
      for (const c of chosen) {
        if (c.option && c.option.id === focusedOptionId) return c.option;
      }
    }
    const firstImageSlot = chosen.find(c => c.slot.type === "image" && c.option);
    return firstImageSlot ? firstImageSlot.option : null;
  })();
  const extraImages = focused ? optionImages(focused).slice(1) : [];

  const phone = (store.content?.social?.whatsapp || "51954796222").replace(/\D/g, "");
  const waMsg = encodeURIComponent(
    [
      "Hola KIRO Jewelry 👋",
      `Quiero armar ${cat.name.toLowerCase().replace(/s$/, "")} a mi medida:`,
      ...chosen.map(c => {
        if (c.slot.type === "text") return `• ${c.slot.name}: ${c.text || "—"}`;
        return `• ${c.slot.name}: ${c.option?.name || "—"}`;
      }),
      `• Precio estimado: ${fmtPrice(total)}`,
      "",
      "¿Es posible coordinarlo?",
    ].join("\n")
  );

  return (
    <main>
      {/* Breadcrumb */}
      <div className="section" style={{ paddingTop: 32, paddingBottom: 12 }}>
        <div style={{ display: "flex", gap: 8, fontSize: 12,
          letterSpacing: "0.16em", textTransform: "uppercase",
          color: "var(--ink-2)" }}>
          <a onClick={() => navigate("/")} style={{ cursor: "pointer" }}>Inicio</a>
          <span>/</span>
          <a onClick={() => navigate("/c/" + cat.id)} style={{ cursor: "pointer" }}>{cat.name}</a>
          <span>/</span>
          <span style={{ color: "var(--burgundy)" }}>Arma tu pieza</span>
        </div>
      </div>

      <section className="section builder-page" style={{
        paddingTop: 24,
        display: "grid",
        gridTemplateColumns: "1fr 1fr",
        gap: 80, alignItems: "start",
      }}>
        {/* PREVIEW */}
        <div className="builder-preview-wrap" style={{ position: "sticky", top: 100 }}>
          <div className="builder-preview" style={{
            position: "relative", width: "100%", aspectRatio: "1",
            background: "var(--cream)", overflow: "hidden",
          }}>
            {base.base_image && (
              <img src={base.base_image} alt=""
                style={{ position: "absolute", inset: 0, width: "100%", height: "100%",
                  objectFit: "contain", zIndex: 0 }}/>
            )}
            {chosen.map(c => {
              if (c.slot.type !== "image" || !c.option) return null;
              const imgs = optionImages(c.option);
              if (!imgs[0]) return null;
              return (
                <img key={c.slot.id}
                  src={imgs[0]}
                  alt={`${c.slot.name}: ${c.option.name}`}
                  style={{
                    position: "absolute", inset: 0,
                    width: "100%", height: "100%",
                    objectFit: "contain",
                    zIndex: (c.slot.z_index || 0) + 1,
                  }}/>
              );
            })}
            {chosen.filter(c => c.slot.type === "text" && c.text.trim()).map(c => (
              <div key={c.slot.id} style={{
                position: "absolute", left: 0, right: 0, bottom: "18%",
                textAlign: "center",
                fontFamily: "var(--serif)",
                fontSize: "clamp(14px, 1.6vw, 20px)",
                fontStyle: "italic",
                color: "var(--burgundy)",
                letterSpacing: "0.04em",
                zIndex: 999,
                pointerEvents: "none",
                textShadow: "0 1px 2px rgba(255,255,255,0.6)",
              }}>
                {c.text}
              </div>
            ))}
          </div>

          {/* Detail gallery — extra images of the focused option */}
          {extraImages.length > 0 && (
            <div style={{ marginTop: 12 }}>
              <div style={{
                fontSize: 10, letterSpacing: "0.2em", textTransform: "uppercase",
                color: "var(--muted)", textAlign: "center", marginBottom: 8,
              }}>
                Más fotos de {focused?.name}
              </div>
              <div style={{
                display: "grid", gap: 8,
                gridTemplateColumns: `repeat(${Math.min(extraImages.length, 4)}, 1fr)`,
              }}>
                {extraImages.map((url, i) => (
                  <button key={i}
                    type="button"
                    onClick={() => setLightboxUrl(url)}
                    style={{
                      padding: 0, aspectRatio: "1",
                      border: "1px solid var(--line-2)",
                      background: "var(--cream)", cursor: "zoom-in", overflow: "hidden",
                    }}>
                    <img src={url} alt=""
                      style={{ width: "100%", height: "100%", objectFit: "cover" }}/>
                  </button>
                ))}
              </div>
            </div>
          )}

          <div style={{
            marginTop: 12, fontSize: 11, letterSpacing: "0.18em",
            textTransform: "uppercase", color: "var(--muted)", textAlign: "center",
          }}>
            Vista previa en tiempo real
          </div>
        </div>

        {/* SELECTORS */}
        <div className="builder-info" style={{ paddingTop: 12 }}>
          <div className="eyebrow">{cat.name} · Configurador</div>
          <h1 style={{
            fontFamily: "var(--serif)", fontWeight: 400,
            fontSize: "clamp(28px, 5vw, 64px)", lineHeight: 1.05,
            letterSpacing: "-0.01em", color: "var(--burgundy)", margin: "12px 0 16px",
          }}>
            Arma tu pieza
          </h1>
          <p style={{ fontSize: 16, lineHeight: 1.7, color: "var(--ink-2)", marginBottom: 28 }}>
            Elegí cada detalle y vé los cambios reflejados al instante. Cuando estés conforme,
            mandanos un WhatsApp con la combinación.
          </p>

          {chosen.map(c => (
            <div key={c.slot.id} style={{ marginBottom: 24 }}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline",
                fontSize: 11, letterSpacing: "0.2em", textTransform: "uppercase",
                fontWeight: 600, color: "var(--burgundy)", marginBottom: 10 }}>
                <span>{c.slot.name}{!c.slot.required && (
                  <span style={{ color: "var(--muted)", marginLeft: 6, textTransform: "none", letterSpacing: 0 }}>· opcional</span>
                )}</span>
                {c.slot.type === "image" && c.option && (
                  <span style={{ color: "var(--ink-2)", textTransform: "none",
                    letterSpacing: "0.06em", fontWeight: 500, fontSize: 13 }}>
                    {c.option.name}
                    {Number(c.option.price_modifier) !== 0 && (
                      <span style={{ marginLeft: 8, color: "var(--muted)" }}>
                        {Number(c.option.price_modifier) > 0 ? "+" : ""}
                        {fmtPrice(Number(c.option.price_modifier))}
                      </span>
                    )}
                  </span>
                )}
              </div>

              {c.slot.type === "text" ? (
                <div>
                  <input
                    type="text"
                    value={c.text}
                    maxLength={c.slot.max_length || 30}
                    placeholder={c.slot.placeholder || "Escribe el texto del grabado"}
                    onChange={e => setSelection(prev => ({ ...prev, [c.slot.id]: e.target.value }))}
                    style={{
                      width: "100%", padding: "14px 16px",
                      background: "var(--cream)",
                      border: "1px solid var(--line)",
                      fontFamily: "var(--serif)", fontSize: 18,
                      color: "var(--ink)", outline: "none",
                    }}/>
                  <div style={{ display: "flex", justifyContent: "space-between",
                    fontSize: 11, color: "var(--muted)", marginTop: 6 }}>
                    <span>Aparecerá grabado en la pieza.</span>
                    <span>{c.text.length}/{c.slot.max_length || 30}</span>
                  </div>
                </div>
              ) : c.visible.length === 0 ? (
                <div style={{ fontSize: 13, color: "var(--ink-2)", padding: "12px 0" }}>
                  No hay opciones disponibles para la combinación actual.
                </div>
              ) : (
                <div style={{
                  display: "grid",
                  gridTemplateColumns: "repeat(auto-fill, minmax(78px, 1fr))",
                  gap: 10,
                }}>
                  {c.visible.map(o => {
                    const active = c.option && o.id === c.option.id;
                    const imgs = optionImages(o);
                    return (
                      <div key={o.id} style={{ display: "flex", flexDirection: "column", alignItems: "stretch" }}>
                        <button
                          type="button"
                          onClick={() => {
                            setSelection(prev => ({ ...prev, [c.slot.id]: o.id }));
                            setFocusedOptionId(o.id);
                          }}
                          aria-pressed={active}
                          aria-label={o.name}
                          style={{
                            padding: 0,
                            border: active ? "2px solid var(--burgundy)" : "1px solid var(--line-2)",
                            background: "var(--cream)",
                            aspectRatio: "1",
                            cursor: "pointer",
                            overflow: "hidden",
                            position: "relative",
                          }}>
                          {imgs[0] ? (
                            <img src={imgs[0]} alt=""
                              style={{ width: "100%", height: "100%", objectFit: "contain" }}/>
                          ) : (
                            <div style={{ width: "100%", height: "100%", display: "flex",
                              alignItems: "center", justifyContent: "center",
                              fontSize: 10, color: "var(--ink-2)", padding: 4, textAlign: "center" }}>
                              Sin imagen
                            </div>
                          )}
                          {imgs.length > 1 && (
                            <span style={{
                              position: "absolute", top: 4, right: 4,
                              background: "rgba(107,31,37,0.85)", color: "var(--pink-50)",
                              fontSize: 9, padding: "2px 5px", letterSpacing: "0.08em",
                              fontWeight: 700,
                            }}>
                              +{imgs.length - 1}
                            </span>
                          )}
                        </button>
                        <span style={{
                          display: "block", marginTop: 6, fontSize: 11,
                          color: "var(--ink-2)", textAlign: "center",
                          letterSpacing: "0.04em",
                        }}>{o.name}</span>
                      </div>
                    );
                  })}
                </div>
              )}
            </div>
          ))}

          {/* Summary */}
          <div style={{
            marginTop: 8, paddingTop: 24,
            borderTop: "1px solid var(--line-2)",
          }}>
            <div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", marginBottom: 18 }}>
              <span style={{ fontSize: 11, letterSpacing: "0.2em", textTransform: "uppercase",
                color: "var(--burgundy)", fontWeight: 600 }}>Total estimado</span>
              <span style={{ fontFamily: "var(--serif)", fontSize: 28, color: "var(--ink)" }}>
                {fmtPrice(total)}
              </span>
            </div>

            {missing ? (
              <button type="button" disabled className="btn btn-lg" style={{ width: "100%", opacity: 0.55, cursor: "not-allowed" }}>
                Completá {missing.slot.name.toLowerCase()} para continuar
              </button>
            ) : (
              <a
                href={`https://wa.me/${phone}?text=${waMsg}`}
                target="_blank"
                rel="noopener noreferrer"
                className="btn btn-whatsapp btn-lg"
                style={{ width: "100%" }}
              >
                <Icon name="whatsapp" size={18}/>
                Pedir por WhatsApp · {fmtPrice(total)}
              </a>
            )}
          </div>
        </div>
      </section>

      {/* Lightbox for extra images */}
      {lightboxUrl && (
        <div
          onClick={() => setLightboxUrl(null)}
          style={{
            position: "fixed", inset: 0, zIndex: 1000,
            background: "rgba(42,15,18,0.85)",
            display: "flex", alignItems: "center", justifyContent: "center",
            cursor: "zoom-out", padding: 24,
          }}>
          <img src={lightboxUrl} alt=""
            onClick={e => e.stopPropagation()}
            style={{
              maxWidth: "min(900px, 90vw)", maxHeight: "90vh",
              objectFit: "contain", background: "var(--cream)",
              boxShadow: "0 20px 60px rgba(0,0,0,0.4)",
            }}/>
          <button
            onClick={() => setLightboxUrl(null)}
            aria-label="Cerrar"
            style={{
              position: "absolute", top: 20, right: 20,
              background: "transparent", border: 0,
              color: "var(--pink-50)", fontSize: 30, cursor: "pointer",
              lineHeight: 1, padding: 8,
            }}>×</button>
        </div>
      )}
    </main>
  );
}

window.BuilderPage = BuilderPage;
