/* global React, StudyData, productFamily, FAMILY_COLORS */

// =========================================================
// Product Section view — carousel + per-product 3-question
// drill-in (rating, "stands out", "would change")
// =========================================================

function ProductSectionView({ data, respondents, filters, target }) {
  // All products with their global n
  const allProducts = React.useMemo(() => data._products.slice(), [data]);
  const [selectedId, setSelectedId] = React.useState(target?.productId || allProducts[0]?.id);
  const [query, setQuery] = React.useState("");

  // Deep-link target: select the product and scroll to the matching question.
  React.useEffect(() => {
    if (!target) return;
    if (target.productId) setSelectedId(target.productId);
    const pqs = data.product_questions || [];
    const pq = target.pqTitle && pqs.find((q) => q.title === target.pqTitle);
    let n = 0;
    const tick = () => {
      const parent = document.querySelector("[data-rr-scroll]");
      const el = pq && document.getElementById("rr-pq-" + pq.id);
      if (parent && el && el.getBoundingClientRect().height > 0) {
        const top = el.getBoundingClientRect().top - parent.getBoundingClientRect().top + parent.scrollTop - 14;
        parent.scrollTo({ top, behavior: n === 0 ? "auto" : "smooth" });
        el.classList.add("rr-pq--flash");
        setTimeout(() => el.classList.remove("rr-pq--flash"), 1600);
        return;
      } else if (parent && n === 0) {
        parent.scrollTo({ top: 0 });
      }
      n += 1;
      if (n < 12) setTimeout(tick, 130);
    };
    setTimeout(tick, 120);
  }, [target && target.key]);

  const visibleProducts = React.useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return allProducts;
    return allProducts.filter((p) => p.title.toLowerCase().includes(q));
  }, [allProducts, query]);

  const selected = allProducts.find((p) => p.id === selectedId);
  const productAgg = React.useMemo(
    () => selected ? StudyData.aggregateProduct(selected.id, respondents) : null,
    [selected, respondents]
  );

  if (!selected) return null;
  const productQuestions = data.product_questions || [];

  return (
    <div className="rr-product">
      <div className="rr-product__head">
        <div>
          <div className="rr-product__title-row">
            <span className="rr-product__title">Products</span>
            <span className="rr-product__count">{allProducts.length}</span>
          </div>
          <div className="rr-product__sub">
            Each respondent was randomly served {Math.round(allProducts.reduce((s, p) => s + p.n, 0) / data.respondents.length)} products; click a thumbnail to drill in.
          </div>
        </div>
        <label className="rr-product__search">
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
          <input
            type="text"
            placeholder="Search products"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
          />
        </label>
      </div>

      {/* Carousel */}
      <div className="rr-product__carousel">
        {visibleProducts.map((p) => (
          <ProductThumb
            key={p.id}
            product={p}
            isSelected={p.id === selectedId}
            onClick={() => setSelectedId(p.id)}
          />
        ))}
        {visibleProducts.length === 0 && (
          <div style={{ fontSize: 12, color: "var(--ms-fg-muted)", padding: 12 }}>No products match "{query}"</div>
        )}
      </div>

      {/* P1: would you consider buying (primary scale) */}
      <ProductRatingCard agg={productAgg} />

      {/* Remaining product questions — multi-select bars or verbatim text */}
      {productQuestions.filter((pq) => pq.type !== "scale").map((pq) => {
        const a = productAgg.byPq && productAgg.byPq[pq.id];
        if (!a) return null;
        if (pq.type === "multi") {
          return <div key={pq.id} id={"rr-pq-" + pq.id}><ProductMultiCard num={pq.num} title={pq.title} agg={a} n={productAgg.n} /></div>;
        }
        const responses = a.responses || [];
        return (
          <div key={pq.id} id={"rr-pq-" + pq.id}>
            <ProductTextCard
              num={pq.num}
              title={pq.title}
              responses={responses}
              cloud={buildCloud(responses)}
              n={productAgg.n}
            />
          </div>
        );
      })}
    </div>
  );
}

// ---------- Product multi-select distribution card ----------
function ProductMultiCard({ num, title, agg, n }) {
  const opts = (agg.options || []).filter((o) => o.count > 0);
  return (
    <article className="rr-card rr-card--product">
      <div className="rr-card__head">
        <div className="rr-card__title">
          <span className="rr-card__num">{num}</span>
          {title}
        </div>
        <div className="rr-card__meta">
          <span className="rr-card__chip">Multi-select</span>
          <span className="rr-card__chip">n = {(agg.total || 0).toLocaleString()} responded</span>
          <span className="rr-card__chip">{n > 0 ? Math.round(((agg.total || 0) / n) * 100) : 0}% response rate</span>
        </div>
      </div>
      <div className="rr-card__body">
        {opts.length === 0 && (
          <div style={{ fontSize: 12, color: "var(--ms-fg-muted)", padding: 12 }}>No selections for this product in the current filter set.</div>
        )}
        {opts.map((opt) => (
          <div className="rr-bar" key={opt.label}>
            <div className="rr-bar__row">
              <div className="rr-bar__label">{opt.label}</div>
              <div className="rr-bar__pct">
                <span className="rr-bar__count">{opt.count.toLocaleString()}</span>
                <span className="rr-bar__pct-val">{opt.pct}%</span>
              </div>
            </div>
            <div className="rr-bar__track">
              <div className="rr-bar__fill" style={{ width: `${Math.max(0.5, opt.pct)}%` }}></div>
            </div>
          </div>
        ))}
      </div>
    </article>
  );
}

// ---------- Thumbnail ----------
function ProductThumb({ product, isSelected, onClick }) {
  const fam = productFamily(product.title);
  const apparel = typeof window !== "undefined" && window.ACTIVE_STUDY_CFG && window.ACTIVE_STUDY_CFG.productPlaceholder === "apparel";
  const imgUrl = window.PRODUCT_IMAGES && window.PRODUCT_IMAGES.url(product.id);
  const [imgOk, setImgOk] = React.useState(true);
  return (
    <button
      className={"rr-product__thumb" + (isSelected ? " is-selected" : "")}
      onClick={onClick}
      title={product.title + " · n=" + product.n}
    >
      {imgUrl && imgOk ? (
        <div className="rr-product__thumb-photo" style={{ background: fam.bg }}>
          <img src={imgUrl} alt={product.title} loading="lazy" onError={() => setImgOk(false)} />
        </div>
      ) : apparel ? (
        <ApparelSvg color={product.color} />
      ) : (
        <SneakerSvg fam={fam} />
      )}
      <div className="rr-product__thumb-label">{product.title}</div>
    </button>
  );
}

// ---- Apparel colorway → swatch hex (placeholder tint until real photos) ----
function colorwayHex(color) {
  const c = String(color || "").toLowerCase();
  const has = (s) => c.indexOf(s) >= 0;
  if (has("black") && has("white")) return { bg: "#D8D5D1", fg: "#2A2724" };
  if (has("black")) return { bg: "#CFCBC6", fg: "#2A2724" };
  if (has("dark wash")) return { bg: "#C3CEDA", fg: "#2E4257" };
  if (has("medium wash")) return { bg: "#CBDAE8", fg: "#41658C" };
  if (has("light wash") || has("light")) return { bg: "#DDE7F1", fg: "#6F8CAD" };
  if (has("cider") || has("rust")) return { bg: "#E8C9B0", fg: "#A8521F" };
  if (has("brown") || has("chocolate") || has("espresso")) return { bg: "#DEC9B2", fg: "#6B4A2E" };
  if (has("tan") || has("camel") || has("khaki")) return { bg: "#EBDCC3", fg: "#A07A45" };
  if (has("bone") || has("cream") || has("ivory") || has("white")) return { bg: "#F0EADB", fg: "#B6A883" };
  if (has("denim") || has("blue")) return { bg: "#CBDAE8", fg: "#41658C" };
  return { bg: "#E4DCCD", fg: "#7A6A4E" };
}

// Stylized hanging-garment silhouette per colorway. Placeholder only.
function ApparelSvg({ color }) {
  const cw = colorwayHex(color);
  return (
    <svg viewBox="0 0 100 60" className="rr-product__thumb-svg" preserveAspectRatio="xMidYMid meet">
      <rect x="0" y="0" width="100" height="60" fill={cw.bg} rx="4"/>
      {/* Hanger */}
      <path d="M50 10 a3 3 0 1 1 2 2" fill="none" stroke={cw.fg} strokeWidth="1.3" opacity="0.55"/>
      <path d="M50 13 L34 22 M50 13 L66 22" stroke={cw.fg} strokeWidth="1.3" opacity="0.55" fill="none"/>
      {/* Garment body (top / blouse) */}
      <path d="M40 20 L34 22 L29 30 L34 33 L36 30 L36 48 Q36 50 38 50 L62 50 Q64 50 64 48 L64 30 L66 33 L71 30 L66 22 L60 20 Q55 25 50 25 Q45 25 40 20 Z"
        fill={cw.fg} opacity="0.85"/>
      {/* Color label */}
      <text x="50" y="58" textAnchor="middle" fill={cw.fg} fontSize="6" fontWeight="700" fontFamily="PPTelegraf, sans-serif" opacity="0.6">
        {String(color || "").toUpperCase().slice(0, 16)}
      </text>
    </svg>
  );
}

// SVG placeholder — a stylized sneaker silhouette per family color.
// Not photo-real; this is a placeholder until real images are dropped in.
function SneakerSvg({ fam }) {
  return (
    <svg viewBox="0 0 100 60" className="rr-product__thumb-svg" preserveAspectRatio="xMidYMid meet">
      <rect x="0" y="0" width="100" height="60" fill={fam.bg} rx="4"/>
      {/* Stylized sneaker silhouette */}
      <path
        d="M 12 42 Q 14 32 22 30 L 38 26 Q 46 22 56 22 L 72 24 Q 82 26 86 32 L 88 38 Q 88 44 84 46 L 18 46 Q 12 46 12 42 Z"
        fill={fam.fg}
        opacity="0.85"
      />
      {/* Sole stripe */}
      <rect x="10" y="44" width="80" height="3" fill={fam.fg} opacity="0.95" rx="1"/>
      {/* Lace area highlight */}
      <path
        d="M 38 28 L 56 24 L 58 30 L 40 33 Z"
        fill={fam.bg}
        opacity="0.55"
      />
      {/* Subtle initials */}
      <text x="80" y="20" textAnchor="end" fill={fam.fg} fontSize="10" fontWeight="700" fontFamily="PPTelegraf, sans-serif" opacity="0.55">
        {fam.abbrev}
      </text>
    </svg>
  );
}

// ---------- P1 rating distribution card ----------
function ProductRatingCard({ agg }) {
  const heroUrl = agg && window.PRODUCT_IMAGES ? window.PRODUCT_IMAGES.url(agg.id) : null;
  const heroFam = agg ? productFamily(agg.title) : null;
  const [heroOk, setHeroOk] = React.useState(true);
  React.useEffect(() => { setHeroOk(true); }, [agg && agg.id]);
  if (!agg) return null;

  return (
    <article className="rr-card rr-card--product">
      <div className="rr-card__head">
        <div className="rr-card__title">
          {heroUrl && heroOk && (
            <span className="rr-card__hero" style={{ background: heroFam.bg }}>
              <img src={heroUrl} alt={agg.title} onError={() => setHeroOk(false)} />
            </span>
          )}
          <span className="rr-card__num">P1</span>
          Would you consider buying <strong style={{ color: "var(--ms-fg)" }}>{agg.title}</strong>?
        </div>
        <div className="rr-card__meta">
          <span className="rr-card__chip">5-pt scale</span>
          <span className="rr-card__chip">n = {agg.n.toLocaleString()}</span>
          <span className="rr-card__chip rr-card__chip--accent">★ {agg.meanRating.toFixed(2)} mean</span>
        </div>
      </div>
      <div className="rr-card__body">
        {[...agg.p1].reverse().map((opt) => (
          <RatingBar key={opt.label} opt={opt} maxCount={agg.n} />
        ))}
      </div>
      <div className="rr-card__foot">
        <div className="rr-card__chart-toggles">
          <button className="rr-card__chart-tab is-active" title="Bar chart">
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><line x1="3" y1="6" x2="15" y2="6"/><line x1="3" y1="12" x2="19" y2="12"/><line x1="3" y1="18" x2="10" y2="18"/></svg>
          </button>
          <button className="rr-card__chart-tab" title="Column" disabled><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg></button>
          <button className="rr-card__chart-tab" title="Donut" disabled><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M21.21 15.89A10 10 0 1 1 8 2.83"/><path d="M22 12A10 10 0 0 0 12 2v10z"/></svg></button>
        </div>
        <div style={{ marginLeft: "auto", display: "inline-flex", gap: 4 }}>
          <button className="rr-card__foot-btn">Options</button>
          <button className="rr-card__foot-btn" title="Export">⤓</button>
          <button className="rr-card__foot-btn" title="Expand">⤢</button>
        </div>
      </div>
    </article>
  );
}

function RatingBar({ opt, maxCount }) {
  const stars = parseInt(opt.label[0], 10);
  return (
    <div className="rr-rating-row">
      <div className="rr-rating-row__stars">
        {[1, 2, 3, 4, 5].map((i) => (
          <span key={i} className={i <= stars ? "is-on" : ""}>★</span>
        ))}
        <span className="rr-rating-row__label">{opt.label}</span>
      </div>
      <div className="rr-rating-row__bar">
        <div className="rr-rating-row__fill" style={{ width: `${Math.max(0.5, opt.pct)}%` }}>
          <span className="rr-rating-row__count">{opt.count.toLocaleString()}</span>
        </div>
      </div>
    </div>
  );
}

// ---------- P2/P3 text card ----------
function ProductTextCard({ num, title, responses, cloud, n }) {
  const [showAll, setShowAll] = React.useState(false);
  const visible = showAll ? responses : responses.slice(0, 8);
  return (
    <article className="rr-card rr-card--product">
      <div className="rr-card__head">
        <div className="rr-card__title">
          <span className="rr-card__num">{num}</span>
          {title}
        </div>
        <div className="rr-card__meta">
          <span className="rr-card__chip">Long text</span>
          <span className="rr-card__chip">n = {responses.length.toLocaleString()} responded</span>
          <span className="rr-card__chip">{n > 0 ? Math.round((responses.length / n) * 100) : 0}% response rate</span>
        </div>
      </div>
      <div className="rr-card__body">
        {cloud.length > 0 && (
          <div className="rr-text__cloud rr-text__cloud--product">
            {cloud.map((r) => {
              const max = cloud[0]?.count || 1;
              return (
                <span key={r.text} className="rr-text__word" style={{ fontSize: 12 + (r.count / max) * 18 }}>
                  {r.text} <span className="rr-text__n">{r.count}</span>
                </span>
              );
            })}
          </div>
        )}
        {visible.length > 0 && (
          <div className="rr-text__sample">
            <div className="rr-text__sample-label">Verbatims · {responses.length.toLocaleString()} total</div>
            {visible.map((r, i) => (
              <div key={i} className="rr-text__verbatim">
                "{r.text}"
                {r.demo && (
                  <span className="rr-text__who">
                    — {r.demo.gender || "?"}, {r.demo.age || (r.demo.birth_year ? (2026 - r.demo.birth_year) : "?")}
                  </span>
                )}
              </div>
            ))}
            {responses.length > 8 && (
              <a className="drill" style={{ marginTop: 8, display: "inline-flex" }} onClick={() => setShowAll((v) => !v)}>
                {showAll ? "Show first 8" : `Show all ${responses.length}`}
              </a>
            )}
          </div>
        )}
        {visible.length === 0 && (
          <div style={{ fontSize: 12, color: "var(--ms-fg-muted)", padding: 12 }}>No verbatims for this product in the current filter set.</div>
        )}
      </div>
    </article>
  );
}

// ---------- Token cloud helper ----------
function buildCloud(verbatims) {
  const stop = new Set("a,an,the,and,or,but,of,for,to,in,on,at,with,without,is,are,was,were,be,been,being,it,its,i,you,we,they,this,that,these,those,my,your,our,their,me,him,her,us,them,as,by,from,not,no,if,when,then,than,so,about,into,onto,over,under,up,down,out,more,less,most,least,very,really,just,like,too,also,have,has,had,do,does,did,can,could,would,should,will,may,might,one,two,three,what,who,how,why,where,which,some,any,all,each,every,other,others,same,different,specified,looks,look,maybe,nothing,anything,everything,something".split(","));
  const wc = new Map();
  for (const v of verbatims) {
    const words = (v.text || "").toLowerCase().split(/[^a-z]+/).filter((w) => w.length >= 3 && !stop.has(w));
    for (const w of words) wc.set(w, (wc.get(w) || 0) + 1);
  }
  return [...wc.entries()]
    .map(([text, count]) => ({ text, count }))
    .sort((a, b) => b.count - a.count)
    .slice(0, 20);
}

Object.assign(window, { ProductSectionView });
