/* global React */
const { useState, useEffect, useRef } = React;

/* ============================ Íconos (line) ============================ */
function Icon({ name, size = 22, stroke = 2 }) {
  const p = {
    width: size, height: size, viewBox: "0 0 24 24", fill: "none",
    stroke: "currentColor", strokeWidth: stroke, strokeLinecap: "round", strokeLinejoin: "round",
  };
  const paths = {
    home: <><path d="M3 10.5 12 3l9 7.5" /><path d="M5 9.5V21h14V9.5" /></>,
    grid: <><rect x="3" y="3" width="7" height="7" rx="1.5" /><rect x="14" y="3" width="7" height="7" rx="1.5" /><rect x="3" y="14" width="7" height="7" rx="1.5" /><rect x="14" y="14" width="7" height="7" rx="1.5" /></>,
    cart: <><circle cx="9" cy="20" r="1.4" /><circle cx="18" cy="20" r="1.4" /><path d="M2 3h3l2.4 12.4a1 1 0 0 0 1 .8h8.7a1 1 0 0 0 1-.8L21 7H6" /></>,
    search: <><circle cx="11" cy="11" r="7" /><path d="m20 20-3.2-3.2" /></>,
    user: <><circle cx="12" cy="8" r="4" /><path d="M4 21c0-4 3.6-6 8-6s8 2 8 6" /></>,
    chat: <><path d="M21 12a8 8 0 0 1-11.3 7.3L3 21l1.7-6.1A8 8 0 1 1 21 12Z" /></>,
    filter: <><path d="M3 5h18M6 12h12M10 19h4" /></>,
    chevR: <path d="m9 6 6 6-6 6" />,
    chevL: <path d="m15 6-6 6 6 6" />,
    chevD: <path d="m6 9 6 6 6-6" />,
    x: <><path d="M6 6l12 12M18 6 6 18" /></>,
    check: <path d="m5 13 4 4L19 7" />,
    plus: <><path d="M12 5v14M5 12h14" /></>,
    minus: <path d="M5 12h14" />,
    truck: <><path d="M3 6h11v9H3z" /><path d="M14 9h4l3 3v3h-7z" /><circle cx="7" cy="18" r="1.6" /><circle cx="17.5" cy="18" r="1.6" /></>,
    store: <><path d="M4 9V6l1.5-2h13L20 6v3" /><path d="M4 9a3 3 0 0 0 6 0 3 3 0 0 0 6 0 3 3 0 0 0 6 0" /><path d="M5 11v9h14v-9" /></>,
    spark: <path d="M12 3v4m0 10v4M3 12h4m10 0h4M6 6l2.5 2.5M15.5 15.5 18 18M18 6l-2.5 2.5M8.5 15.5 6 18" />,
    drop: <path d="M12 3s6 6.5 6 11a6 6 0 0 1-12 0c0-4.5 6-11 6-11Z" />,
    ruler: <><rect x="3" y="8" width="18" height="8" rx="1.5" /><path d="M7 8v3M11 8v4M15 8v3M19 8v4" /></>,
    info: <><circle cx="12" cy="12" r="9" /><path d="M12 11v5M12 8h.01" /></>,
    star: <path d="m12 3 2.6 5.6L21 9.3l-4.5 4.2 1.1 6.1L12 16.8 6.4 19.6l1.1-6.1L3 9.3l6.4-.7Z" />,
    phone: <path d="M5 4h4l1.5 5-2 1.5a12 12 0 0 0 5 5l1.5-2 5 1.5v4a2 2 0 0 1-2.2 2A17 17 0 0 1 3 6.2 2 2 0 0 1 5 4Z" />,
    brush: <><path d="M14 4 20 10l-7.5 7.5a3 3 0 0 1-4.2 0l-1.8-1.8a3 3 0 0 1 0-4.2Z" /><path d="m4 20 2.5-2.5" /></>,
    shield: <><path d="M12 3 5 6v6c0 4 3 7 7 9 4-2 7-5 7-9V6Z" /><path d="m9 12 2 2 4-4" /></>,
    arrowL: <><path d="M19 12H5" /><path d="m11 6-6 6 6 6" /></>,
    pin: <><path d="M12 21s7-6.3 7-11a7 7 0 0 0-14 0c0 4.7 7 11 7 11Z" /><circle cx="12" cy="10" r="2.5" /></>,
    card: <><rect x="2.5" y="5" width="19" height="14" rx="2.5" /><path d="M2.5 9.5h19" /></>,
    clock: <><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3 2" /></>,
    layers: <><path d="m12 3 9 5-9 5-9-5 9-5Z" /><path d="m3 13 9 5 9-5" /></>,
    send: <path d="m4 12 16-8-7 16-2-6-7-2Z" />,
  };
  return <svg {...p} aria-hidden="true">{paths[name] || null}</svg>;
}

/* ============================ Botón ============================ */
function Button({ variant = "primary", size, block, icon, iconRight, children, ...rest }) {
  const cls = ["btn", `btn--${variant}`, size && `btn--${size}`, block && "btn--block"].filter(Boolean).join(" ");
  return (
    <button className={cls} {...rest}>
      {icon && <Icon name={icon} size={size === "sm" ? 16 : 18} />}
      {children}
      {iconRight && <Icon name={iconRight} size={size === "sm" ? 16 : 18} />}
    </button>
  );
}

/* ============================ Badge / Tag ============================ */
function Badge({ tone = "neutral", icon, children }) {
  return <span className={`badge badge--${tone}`}>{icon && <Icon name={icon} size={12} stroke={2.5} />}{children}</span>;
}

/* ============================ Stepper de cantidad ============================ */
function QtyStepper({ value, onChange, min = 1 }) {
  return (
    <div className="row" style={{ border: "1.5px solid var(--border-default)", borderRadius: "var(--radius-md)", overflow: "hidden" }}>
      <button className="btn--icon" style={btnQty} onClick={() => onChange(Math.max(min, value - 1))} aria-label="Quitar"><Icon name="minus" size={16} /></button>
      <span style={{ minWidth: 32, textAlign: "center", fontWeight: 600, color: "var(--text-strong)" }}>{value}</span>
      <button className="btn--icon" style={btnQty} onClick={() => onChange(value + 1)} aria-label="Agregar"><Icon name="plus" size={16} /></button>
    </div>
  );
}
const btnQty = { width: 38, height: 38, display: "grid", placeItems: "center", background: "transparent", border: "none" };

/* ============================ Swatch + Grid ============================ */
function Swatch({ color, active, onClick }) {
  return (
    <button className={`swatch ${active ? "swatch--active" : ""}`} onClick={onClick} aria-pressed={active} title={color.name}>
      <span className="swatch__chip" style={{ background: color.hex }} />
      {active && <span className="swatch__check"><Icon name="check" size={13} stroke={3} /></span>}
      <span className="swatch__name">{color.name}</span>
    </button>
  );
}
function SwatchGrid({ colors, activeHex, onSelect }) {
  return (
    <div className="swatch-grid">
      {colors.map((c) => (
        <Swatch key={c.hex} color={c} active={activeHex === c.hex} onClick={() => onSelect(c)} />
      ))}
    </div>
  );
}

/* ============================ Selector de presentación ============================ */
function PresentationSelector({ options, value, onChange, product }) {
  return (
    <div className="segmented" role="group" aria-label="Presentación">
      {options.map((p) => (
        <button
          key={p.id}
          className={`pill ${value === p.id ? "pill--active" : ""}`}
          onClick={() => onChange(p.id)}
          aria-pressed={value === p.id}
        >
          <span>{p.label}</span>
          <small>{p.unit}</small>
        </button>
      ))}
    </div>
  );
}

/* ============================ Lata "renderizada" (color real) ============================ */
function CanVisual({ hex = "#0077b6", label = "Nogopaint", sub = "" }) {
  // contraste de la etiqueta segun el color
  return (
    <div className="can" aria-hidden="true">
      <div className="can__body" style={{ background: hex }}>
        <div className="can__handle" />
        <div className="can__lid" />
        <div className="can__label">
          <b>{label}</b>
          {sub && <small>{sub}</small>}
          <span style={{ width: 24, height: 24, borderRadius: 5, background: hex, border: "1px solid rgba(0,0,0,.15)", marginTop: 2 }} />
        </div>
      </div>
    </div>
  );
}

function ProductMedia({ product, color, compact = false }) {
  const hex = color?.hex || "#0077b6";
  const sub = product.use === "exterior" ? "Exterior" : "Interior";
  if (!product.image) return <CanVisual hex={hex} label="Nogopaint" sub={sub} />;

  return (
    <div className={`product-photo ${compact ? "product-photo--compact" : ""}`}>
      <img className="product-photo__img" src={product.image} alt={product.name} loading="lazy" decoding="async" />
      <div className="product-photo__shade" />
      <div className="product-photo__chip" aria-hidden="true">
        <span style={{ background: hex }} />
        <b>{sub}</b>
      </div>
    </div>
  );
}

/* ============================ Stock label ============================ */
function StockLabel({ qty }) {
  if (qty === 0) return <span className="t-xs fw-6 stock-no">Sin stock</span>;
  if (qty <= 6) return <span className="t-xs fw-6 stock-low">Últimas {qty} unidades</span>;
  return <span className="t-xs fw-6 stock-ok">En stock</span>;
}

/* ============================ Card de producto ============================ */
function ProductCard({ product, onOpen }) {
  const NOGO = window.NOGO;
  const firstFam = product.colors[0];
  const previewColors = NOGO.palette[firstFam].slice(0, 4);
  const defaultPres = product.pres[Math.min(1, product.pres.length - 1)];
  const price = NOGO.priceFor(product, defaultPres);
  const stock = NOGO.stockFor(product, defaultPres);
  const colorCount = product.colors.reduce((n, f) => n + NOGO.palette[f].length, 0);
  return (
    <div className="card pcard" onClick={() => onOpen(product)}>
      <div className="pcard__media">
        <ProductMedia product={product} color={previewColors[2]} compact />
        {product.featured && <span style={{ position: "absolute", top: 8, left: 8 }}><Badge tone="best" icon="star">Más vendido</Badge></span>}
      </div>
      <div className="pcard__body">
        <div className="row between" style={{ alignItems: "flex-start" }}>
          <span className="badge badge--neutral">{product.use === "exterior" ? "Exterior" : "Interior"}</span>
          <StockLabel qty={stock} />
        </div>
        <div className="pcard__name">{product.name}</div>
        <div className="t-xs muted">{product.tagline}</div>
        <div className="pcard__swatches">
          {previewColors.map((c) => <span key={c.hex} className="pcard__sw" style={{ background: c.hex }} />)}
          <span className="t-xs muted" style={{ marginLeft: 4, alignSelf: "center" }}>+{colorCount}</span>
        </div>
        <div className="row between" style={{ marginTop: "auto", paddingTop: 6 }}>
          <div className="pcard__price">{NOGO.fmt(price)}</div>
          <span className="btn btn--secondary btn--sm">Ver</span>
        </div>
      </div>
    </div>
  );
}

/* ============================ Toast host ============================ */
function ToastHost({ toasts }) {
  return (
    <div className="toast-wrap">
      {toasts.map((t) => (
        <div key={t.id} className={`toast ${t.tone ? "toast--" + t.tone : ""}`}>
          <Icon name={t.icon || "check"} size={18} stroke={2.5} />{t.msg}
        </div>
      ))}
    </div>
  );
}

/* ============================ Sheet (bottom drawer) ============================ */
function Sheet({ title, onClose, children, footer, full }) {
  return (
    <>
      <div className="overlay" onClick={onClose} />
      <div className="sheet" style={full ? { height: "92%" } : null}>
        <div className="sheet__grab" />
        {title && (
          <div className="sheet__head">
            <h3 className="t-lg">{title}</h3>
            <button className="btn--icon" style={{ width: 40, height: 40, display: "grid", placeItems: "center", borderRadius: 999 }} onClick={onClose} aria-label="Cerrar"><Icon name="x" /></button>
          </div>
        )}
        <div className="sheet__body" style={full ? { flex: 1 } : null}>{children}</div>
        {footer && <div className="sheet__foot">{footer}</div>}
      </div>
    </>
  );
}

/* ============================ Field wrapper ============================ */
function Field({ label, hint, error, children }) {
  return (
    <label className="field">
      {label && <span className="field__label">{label}</span>}
      {children}
      {error ? <span className="field__error">{error}</span> : hint ? <span className="field__hint">{hint}</span> : null}
    </label>
  );
}

/* exportar a window para los demás scripts babel */
Object.assign(window, {
  Icon, Button, Badge, QtyStepper, Swatch, SwatchGrid, PresentationSelector,
  CanVisual, ProductMedia, StockLabel, ProductCard, ToastHost, Sheet, Field,
  useState, useEffect, useRef,
});
