// components.jsx — Reusable bits para YetiShopping

const { useState, useMemo, useEffect, useRef } = React;

// ─────────────────────────────────────────────────────────────────────────────
// StoreBadge — pílula colorida com o nome da loja
function StoreBadge({ store, size = "sm" }) {
  const s = STORES[store];
  if (!s) return null;
  const pad = size === "lg" ? "6px 12px" : size === "md" ? "4px 9px" : "2px 7px";
  const fs  = size === "lg" ? 13 : size === "md" ? 12 : 10.5;
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 4,
      background: s.color, color: s.text, padding: pad,
      borderRadius: 999, fontSize: fs, fontWeight: 700, letterSpacing: ".01em",
      lineHeight: 1, whiteSpace: "nowrap",
    }}>{size === "lg" ? s.name : s.name}</span>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// ProductImage — imagem real (Lomadee/CJ) ou gradiente como fallback
function ProductImage({ product, size = 180, rounded = 18 }) {
  const [imgErr, setImgErr] = React.useState(false);
  const hasRealImg = product.image && !imgErr;

  if (hasRealImg) {
    return (
      <div style={{
        width: "100%", aspectRatio: "1/1", borderRadius: rounded, overflow: "hidden",
        background: "#F5F3EE", display: "flex", alignItems: "center", justifyContent: "center",
      }}>
        <img
          src={product.image}
          alt={product.title || "produto"}
          onError={() => setImgErr(true)}
          style={{ width: "100%", height: "100%", objectFit: "contain", padding: 8 }}
        />
      </div>
    );
  }

  // Fallback: gradiente + ícone (para produtos sem imagem ou skeleton)
  const [c1, c2] = IMG_THEMES[product.cat] || IMG_THEMES.product;
  const icon = ({ console:"🎮", phone:"📱", tv:"📺", laptop:"💻", audio:"🎧",
                  kitchen:"🍳", shoe:"👟", chair:"🪑", speaker:"🔊", monitor:"🖥️",
                  watch:"⌚", camera:"📷" })[product.cat] || "📦";
  return (
    <div style={{
      position: "relative", width: "100%", aspectRatio: "1/1",
      background: product._skeleton
        ? "linear-gradient(135deg, #E8E1CC 0%, #D4CBAD 100%)"
        : `linear-gradient(135deg, ${c1} 0%, ${c2} 100%)`,
      borderRadius: rounded, overflow: "hidden",
      display: "flex", alignItems: "center", justifyContent: "center",
      boxShadow: "inset 0 -40px 80px -20px rgba(0,0,0,.25)",
      animation: product._skeleton ? "pulse 1.5s ease-in-out infinite" : "none",
    }}>
      {!product._skeleton && (
        <>
          <div style={{ fontSize: size * 0.42, filter: "drop-shadow(0 6px 12px rgba(0,0,0,.35))", opacity: .92 }}>{icon}</div>
          <div style={{
            position: "absolute", inset: 0,
            background: "radial-gradient(circle at 30% 25%, rgba(255,255,255,.18), transparent 50%)",
            pointerEvents: "none",
          }}/>
        </>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// SparkLine — gráfico mini de tendência
function SparkLine({ data, w = 120, h = 32, stroke = "#0E2A47", fillTop = "#FFC72C", fillBottom = null }) {
  if (!data || data.length < 2) return null;
  const min = Math.min(...data.map(d => d.p));
  const max = Math.max(...data.map(d => d.p));
  const range = max - min || 1;
  const points = data.map((d, i) => {
    const x = (i / (data.length - 1)) * w;
    const y = h - ((d.p - min) / range) * (h - 4) - 2;
    return [x, y];
  });
  const path = points.map((p, i) => (i === 0 ? `M${p[0]},${p[1]}` : `L${p[0]},${p[1]}`)).join(" ");
  const fillPath = `${path} L${w},${h} L0,${h} Z`;
  const last = points[points.length - 1];
  return (
    <svg width={w} height={h} style={{ display: "block", overflow: "visible" }}>
      <defs>
        <linearGradient id={`sparkgrad-${stroke.replace("#","")}`} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={fillTop} stopOpacity="0.22"/>
          <stop offset="100%" stopColor={fillTop} stopOpacity="0"/>
        </linearGradient>
      </defs>
      <path d={fillPath} fill={`url(#sparkgrad-${stroke.replace("#","")})`} />
      <path d={path} fill="none" stroke={stroke} strokeWidth="1.5" strokeLinejoin="round" strokeLinecap="round"/>
      <circle cx={last[0]} cy={last[1]} r="2.5" fill={stroke}/>
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// PriceChart — gráfico grande estilo CCC, com hover crosshair
function PriceChart({ history, currentPrice, lowestEver, highestEver, height = 280, period = "180" }) {
  const ref = useRef(null);
  const [hover, setHover] = useState(null);
  const [width, setWidth] = useState(800);

  useEffect(() => {
    if (!ref.current) return;
    const ro = new ResizeObserver(([e]) => setWidth(e.contentRect.width));
    ro.observe(ref.current);
    return () => ro.disconnect();
  }, []);

  // Filtrar por período
  const data = useMemo(() => {
    if (period === "all") return history;
    const days = parseInt(period, 10);
    return history.slice(-days);
  }, [history, period]);

  const PAD = { l: 56, r: 16, t: 16, b: 32 };
  const W = width;
  const H = height;
  const PW = W - PAD.l - PAD.r;
  const PH = H - PAD.t - PAD.b;

  const prices = data.map(d => d.p);
  let min = Math.min(...prices);
  let max = Math.max(...prices);
  const span = (max - min) || 1;
  // pad y range
  min = min - span * 0.1;
  max = max + span * 0.1;

  const xOf = i => PAD.l + (i / (data.length - 1)) * PW;
  const yOf = p => PAD.t + (1 - (p - min) / (max - min)) * PH;

  const path = data.map((d, i) => `${i === 0 ? "M" : "L"}${xOf(i)},${yOf(d.p)}`).join(" ");
  const areaPath = `${path} L${xOf(data.length - 1)},${PAD.t + PH} L${xOf(0)},${PAD.t + PH} Z`;

  // y ticks
  const yTicks = 4;
  const yStep = (max - min) / yTicks;
  const yLabels = Array.from({ length: yTicks + 1 }, (_, i) => Math.round(min + i * yStep));

  // x ticks
  const xLabels = [0, 0.25, 0.5, 0.75, 1].map(t => Math.floor(t * (data.length - 1)));

  // lowest/highest indices
  const loIdx = data.reduce((best, d, i) => d.p < data[best].p ? i : best, 0);
  const hiIdx = data.reduce((best, d, i) => d.p > data[best].p ? i : best, 0);

  function handleMove(e) {
    const rect = e.currentTarget.getBoundingClientRect();
    const x = e.clientX - rect.left;
    if (x < PAD.l || x > PAD.l + PW) { setHover(null); return; }
    const i = Math.round(((x - PAD.l) / PW) * (data.length - 1));
    setHover({ i: Math.max(0, Math.min(data.length - 1, i)) });
  }

  const monthFmt = new Intl.DateTimeFormat("pt-BR", { day: "2-digit", month: "short" });

  return (
    <div ref={ref} style={{ width: "100%", position: "relative", fontFamily: "inherit" }}>
      <svg width={W} height={H} onMouseMove={handleMove} onMouseLeave={() => setHover(null)}
           style={{ display: "block", cursor: "crosshair" }}>
        <defs>
          <linearGradient id="chart-area" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%"  stopColor="#FFC72C" stopOpacity="0.28"/>
            <stop offset="100%" stopColor="#FFC72C" stopOpacity="0"/>
          </linearGradient>
          <linearGradient id="chart-line" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%"  stopColor="#0E2A47"/>
            <stop offset="100%" stopColor="#1A365D"/>
          </linearGradient>
        </defs>

        {/* y grid */}
        {yLabels.map((v, i) => {
          const y = yOf(v);
          return (
            <g key={i}>
              <line x1={PAD.l} x2={W - PAD.r} y1={y} y2={y} stroke="#0E2A47" strokeOpacity={i === 0 ? 0.2 : 0.06} strokeDasharray={i === 0 ? "" : "2 3"}/>
              <text x={PAD.l - 8} y={y + 4} textAnchor="end" fontSize="11" fill="#0E2A47" opacity="0.55" style={{ fontVariantNumeric: "tabular-nums" }}>
                {fmtBRL(v)}
              </text>
            </g>
          );
        })}

        {/* lowest band */}
        <line x1={PAD.l} x2={W - PAD.r} y1={yOf(lowestEver)} y2={yOf(lowestEver)} stroke="#1FB3A6" strokeWidth="1.2" strokeDasharray="4 3" opacity="0.7"/>
        <rect x={W - PAD.r - 110} y={yOf(lowestEver) - 16} width="106" height="14" rx="7" fill="#1FB3A6"/>
        <text x={W - PAD.r - 57} y={yOf(lowestEver) - 5.5} textAnchor="middle" fontSize="9.5" fill="white" fontWeight="700" letterSpacing=".06em">MENOR PREÇO</text>

        {/* area + line */}
        <path d={areaPath} fill="url(#chart-area)"/>
        <path d={path} fill="none" stroke="url(#chart-line)" strokeWidth="2.4" strokeLinejoin="round" strokeLinecap="round"/>

        {/* lowest marker */}
        <g>
          <circle cx={xOf(loIdx)} cy={yOf(data[loIdx].p)} r="5" fill="#1FB3A6" stroke="white" strokeWidth="2"/>
        </g>
        {/* highest marker */}
        <g>
          <circle cx={xOf(hiIdx)} cy={yOf(data[hiIdx].p)} r="4" fill="#FF6B5C" stroke="white" strokeWidth="2"/>
        </g>
        {/* current marker */}
        <g>
          <circle cx={xOf(data.length - 1)} cy={yOf(data[data.length - 1].p)} r="6" fill="#FFC72C" stroke="#0E2A47" strokeWidth="2.5"/>
        </g>

        {/* x labels */}
        {xLabels.map((i, k) => (
          <text key={k} x={xOf(i)} y={H - 10} textAnchor={k === 0 ? "start" : k === xLabels.length - 1 ? "end" : "middle"}
                fontSize="10.5" fill="#0E2A47" opacity="0.55">{monthFmt.format(data[i].d)}</text>
        ))}

        {/* hover */}
        {hover && (
          <g>
            <line x1={xOf(hover.i)} x2={xOf(hover.i)} y1={PAD.t} y2={PAD.t + PH} stroke="#0E2A47" strokeOpacity="0.3" strokeDasharray="3 3"/>
            <circle cx={xOf(hover.i)} cy={yOf(data[hover.i].p)} r="4.5" fill="#0E2A47" stroke="white" strokeWidth="2"/>
          </g>
        )}
      </svg>

      {/* hover tooltip */}
      {hover && (
        <div style={{
          position: "absolute",
          left: Math.min(xOf(hover.i) + 10, W - 140),
          top: yOf(data[hover.i].p) - 50,
          background: "#0E2A47", color: "white", padding: "8px 12px",
          borderRadius: 10, fontSize: 12, fontWeight: 600, pointerEvents: "none",
          boxShadow: "0 8px 24px rgba(14,42,71,.25)", whiteSpace: "nowrap",
        }}>
          <div style={{ opacity: .7, fontWeight: 500, fontSize: 10.5 }}>
            {new Intl.DateTimeFormat("pt-BR", { day: "2-digit", month: "long", year: "numeric" }).format(data[hover.i].d)}
          </div>
          <div style={{ fontSize: 15, marginTop: 2, fontVariantNumeric: "tabular-nums" }}>{fmtBRL(data[hover.i].p)}</div>
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// ProductCard — card de produto para grids (suporta produtos reais + mock)
function ProductCard({ product, onClick }) {
  if (product._skeleton) {
    return (
      <div style={{ background: "white", border: "1px solid #E8E1CC", borderRadius: 20, padding: 14, display: "flex", flexDirection: "column", gap: 12, animation: "pulse 1.5s ease-in-out infinite" }}>
        <div style={{ width: "100%", aspectRatio: "1/1", borderRadius: 14, background: "#F0EBE0" }}/>
        <div style={{ height: 12, borderRadius: 6, background: "#F0EBE0", width: "60%" }}/>
        <div style={{ height: 10, borderRadius: 6, background: "#F0EBE0", width: "90%" }}/>
        <div style={{ height: 20, borderRadius: 6, background: "#F0EBE0", width: "40%" }}/>
      </div>
    );
  }

  const dropPct = product.base > 0 ? Math.round(((product.base - product.current) / product.base) * 100) : 0;
  const isLow  = product.lowestEver > 0 && product.current <= product.lowestEver * 1.03;

  return (
    <button onClick={() => onClick?.(product)} className="ys-card" style={{
      display: "flex", flexDirection: "column", textAlign: "left",
      background: "white", border: "1px solid #E8E1CC", borderRadius: 20,
      padding: 14, cursor: "pointer", gap: 10, position: "relative",
      transition: "transform .18s ease, box-shadow .18s ease, border-color .18s ease",
      width: "100%", font: "inherit", color: "inherit",
    }}>
      <div style={{ position: "relative" }}>
        <ProductImage product={product} size={160}/>
        {dropPct >= 5 && (
          <div style={{ position: "absolute", top: 10, left: 10, background: "#FF6B5C", color: "white", padding: "4px 9px", borderRadius: 999, fontSize: 12, fontWeight: 800 }}>−{dropPct}%</div>
        )}
        {isLow && (
          <div style={{ position: "absolute", top: 10, right: 10, background: "#1FB3A6", color: "white", padding: "4px 8px", borderRadius: 999, fontSize: 10, fontWeight: 700 }}>● MENOR PREÇO</div>
        )}
      </div>

      <div style={{ display: "flex", flexDirection: "column", gap: 3 }}>
        <div style={{ fontSize: 10.5, fontWeight: 700, color: "#7E7458", letterSpacing: ".08em", textTransform: "uppercase" }}>
          AliExpress · {product.cat}
        </div>
        <div style={{ fontSize: 14, fontWeight: 600, color: "#0E2A47", lineHeight: 1.3, display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden", minHeight: 36 }}>
          {product.title}
        </div>
      </div>

      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 8 }}>
        <div>
          {product.base > product.current && (
            <div style={{ fontSize: 11, color: "#7E7458", textDecoration: "line-through" }}>{fmtBRL(product.base)}</div>
          )}
          <div style={{ fontSize: 22, fontWeight: 800, color: "#0E2A47", fontFamily: "var(--font-display)", lineHeight: 1 }}>
            {fmtBRL(product.current)}
          </div>
          <div style={{ fontSize: 11, color: "#1FB3A6", fontWeight: 600, marginTop: 2 }}>
            {fmtBRL(Math.round(product.current * 0.95))} no Pix
          </div>
        </div>
        {product.history?.length >= 2 && (
          <SparkLine data={product.history.slice(-60)} w={84} h={32}/>
        )}
      </div>

      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", paddingTop: 8, borderTop: "1px dashed #E8E1CC" }}>
        <span style={{ padding: "3px 8px", borderRadius: 999, fontSize: 10, fontWeight: 800, background: "#FF6600", color: "white" }}>AE</span>
        {product.rating && (
          <div style={{ display: "flex", alignItems: "center", gap: 3, fontSize: 11.5, color: "#0E2A47", fontWeight: 600 }}>
            <span style={{ color: "#FFC72C" }}>★</span>{product.rating}
            {product.reviews && <span style={{ color: "#7E7458", fontWeight: 500 }}>({(product.reviews/1000).toFixed(1)}k)</span>}
          </div>
        )}
      </div>
    </button>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// StoreLogosStrip — fileira de logos de loja como prova
function StoreLogosStrip({ stores, label = "Comparamos preços em:" }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 16, flexWrap: "wrap" }}>
      <span style={{ fontSize: 12.5, color: "#0E2A47", opacity: .65, fontWeight: 600 }}>{label}</span>
      <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
        {(stores || Object.keys(STORES)).map(id => {
          const s = STORES[id];
          return (
            <div key={id} style={{
              background: s.color, color: s.text, padding: "6px 12px",
              borderRadius: 8, fontSize: 12.5, fontWeight: 700, letterSpacing: ".01em",
            }}>{s.name}</div>
          );
        })}
      </div>
    </div>
  );
}

// Export pra outros scripts
Object.assign(window, { StoreBadge, ProductImage, SparkLine, PriceChart, ProductCard, StoreLogosStrip });
