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

function Catalog({ theme, onAddToCart, cart, onOpenCart }) {
  const products = window.PRODUCTS;

  return (
    <div className="catalog-page">
      <Hero />

      <div className="product-grid">
        {products.map(p => (
          <ProductCard key={p.id} product={p} onAdd={onAddToCart} />
        ))}
      </div>

      <DeadlineBanner />
    </div>
  );
}

function Hero() {
  const [expanded, setExpanded] = useState(false);
  return (
    <section className="hero">
      <div className="hero-catalog-mark">
        <svg className="hero-flourish left" viewBox="0 0 80 40" aria-hidden="true">
          <path d="M2 20 Q 20 20, 40 20 T 78 20" fill="none" stroke="var(--accent-ink)" strokeWidth="0.8" opacity="0.5" />
          <circle cx="78" cy="20" r="1.6" fill="var(--accent-ink)" opacity="0.6" />
        </svg>
        <img src="assets/hero_catalog.png" alt="70th Anniversary T-shirt & Bag Catalog" className="hero-catalog-img" />
        <svg className="hero-flourish right" viewBox="0 0 80 40" aria-hidden="true">
          <path d="M2 20 Q 20 20, 40 20 T 78 20" fill="none" stroke="var(--accent-ink)" strokeWidth="0.8" opacity="0.5" />
          <circle cx="2" cy="20" r="1.6" fill="var(--accent-ink)" opacity="0.6" />
        </svg>
      </div>
      <div className="hero-copy">
        <p className="hero-lede hero-description">
          小学校の70周年を記念して、オリジナルTシャツを作成いたしました。<br/>
          デザインは2種類、カラーは8色と、豊富なバリエーションをご用意しております。<br/>
          サイズは子ども用・大人用ともにご用意しておりますので、ご家族でお揃いでもお楽しみいただけます。
        </p>
        <div className={`hero-rest ${expanded ? 'open' : ''}`}>
          <p className="hero-lede hero-description">
            子ども用Tシャツは綿100％のベーシックタイプ、<br/>
            大人用Tシャツは、より長く快適に着ていただけるよう、上質な生地を使用したプレミアムタイプをご用意いたしました。
          </p>
          <p className="hero-lede hero-description hero-note">
            ※プレミアムタイプはベーシックカラーのみの展開となります。また、子どもサイズの展開がないため、大人サイズのみのご用意となります。詳しくはサイズ表をご確認ください。
          </p>
          <p className="hero-lede hero-description">
            さらに、バッグも2種類ご用意しております。<br/>
            エコバッグ（2色）とレッスンバッグは、日常でも使いやすいデザインです。
          </p>
          <p className="hero-lede hero-description">
            なお、本デザインは、有名アーティストのCDジャケットやライブグッズのデザインを手がけてこられた保護者の方にご協力いただき、特別感のある仕上がりとなっております。
          </p>
          <p className="hero-lede hero-description">
            本グッズの収益は、学校や子どもたちのための備品購入費への寄付、ならびに周年イベント当日午後に開催されるお祭りの運営費として、大切に活用させていただきます。
          </p>
          <p className="hero-lede hero-description hero-closing">
            ぜひご家族でお揃いで着ていただき、<br/>
            みんなで小学校の70周年を盛り上げていただけましたら嬉しいです。
          </p>
        </div>
        <button
          type="button"
          className={`hero-more ${expanded ? 'open' : ''}`}
          onClick={() => setExpanded(v => !v)}
          aria-expanded={expanded}
        >
          <span>{expanded ? '閉じる' : '続きを読む'}</span>
          <svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true">
            <path d="M4 6 L8 10 L12 6" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </button>
        <div className="hero-meta">
          <div className="meta-item">
            <span className="meta-label">申込締切</span>
            <span className="meta-value">4月30日（水）</span>
          </div>
          <div className="meta-dot" />
          <div className="meta-item">
            <span className="meta-label">お支払い</span>
            <span className="meta-value">お受取時 現金 / PayPay</span>
          </div>
        </div>
      </div>
    </section>
  );
}

function DeadlineBanner() {
  return (
    <section className="deadline-banner">
      <div className="db-inner">
        <div className="db-mark">
          <svg viewBox="0 0 40 40" width="40" height="40">
            <circle cx="20" cy="20" r="18" fill="none" stroke="currentColor" strokeWidth="1.5"/>
            <path d="M20 10 L20 20 L27 24" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round"/>
          </svg>
        </div>
        <div>
          <div className="db-title">お申し込みは4月30日(水)まで</div>
        </div>
      </div>
    </section>
  );
}

function ProductCard({ product, onAdd }) {
  const [activeVariant, setActiveVariant] = useState(product.variants[0]);
  const [activeSize, setActiveSize] = useState(null);
  const [activeColor, setActiveColor] = useState(product.colors ? Object.keys(product.colors)[0] : null);
  const [qty, setQty] = useState(1);
  const [justAdded, setJustAdded] = useState(false);
  const [sizeChartOpen, setSizeChartOpen] = useState(false);
  const imageRef = useRef(null);
  const openSizeChart = () => {
    setSizeChartOpen(v => {
      const next = !v;
      if (next && imageRef.current) {
        // Scroll so the image area sits BELOW the sticky nav + filter bar
        setTimeout(() => {
          const rect = imageRef.current.getBoundingClientRect();
          // Measure the combined height of any sticky chrome at the top
          const nav = document.querySelector('.top-nav');
          const filterBar = document.querySelector('.filter-bar');
          const navH = nav ? nav.getBoundingClientRect().height : 0;
          const filterH = filterBar ? filterBar.getBoundingClientRect().height : 0;
          const stickyH = navH + filterH;
          const gap = 16;
          const offset = window.scrollY + rect.top - stickyH - gap;
          window.scrollTo({ top: offset, behavior: 'smooth' });
        }, 50);
      }
      return next;
    });
  };
  const sizes = product.variantSizes[activeVariant] || [];
  const price = product.price[activeVariant];
  const hasVariantChoice = !product.colors && product.variants.length > 1;
  const minPrice = hasVariantChoice
    ? Math.min(...product.variants.map(v => product.price[v]))
    : price;

  const canAdd = activeSize && qty > 0;

  const handleAdd = (e) => {
    if (!canAdd) return;
    const rect = e.currentTarget.getBoundingClientRect();
    onAdd({
      productId: product.id,
      variant: activeVariant,
      size: activeSize,
      color: activeColor,
      qty,
      unitPrice: price,
    }, { x: rect.left + rect.width / 2, y: rect.top });
    setJustAdded(true);
    setTimeout(() => setJustAdded(false), 1200);
    setActiveSize(null);
    setQty(1);
  };

  return (
    <article className="product-card">
      <div className="pc-image" ref={imageRef}>
        <ProductVisual product={product} size={280} colorKey={activeColor} fill />
        <div className="pc-badge">{product.code}</div>
        {(product.category === 'tshirt-a' || product.category === 'tshirt-b' || product.id === 'bag9' || product.id === 'bag10') && (
          <div className={`size-chart-pop ${sizeChartOpen ? 'open' : ''}`} role="dialog" aria-hidden={!sizeChartOpen}>
            <div className="size-chart-pop-head">
              <span>Size Chart</span>
              <button
                className="size-chart-pop-close"
                onClick={() => setSizeChartOpen(false)}
                aria-label="閉じる"
                type="button"
              >×</button>
            </div>
            <div className="size-chart-pop-body">
              <img
                src={`assets/size_chart_${product.id.toUpperCase()}.png?v=3`}
                onError={(e) => {
                  // Fallback chain: per-product → basic/premium → generic
                  const tried = e.currentTarget.dataset.fallback || '0';
                  if (tried === '0') {
                    e.currentTarget.dataset.fallback = '1';
                    e.currentTarget.src = product.category === 'tshirt-a'
                      ? 'assets/size_chart_tshirt_basic.png?v=3'
                      : 'assets/size_chart_tshirt.png?v=3';
                  } else if (tried === '1') {
                    e.currentTarget.dataset.fallback = '2';
                    e.currentTarget.src = 'assets/size_chart_tshirt.png?v=3';
                  }
                }}
                alt="Tシャツ サイズ表"
              />
            </div>
          </div>
        )}
      </div>
      <div className="pc-body">
        <div className="pc-header">
          <div>
            <h3 className="pc-name">{product.name}</h3>
            <div className="pc-sub">{product.sub}</div>
          </div>
          <div className="pc-price">¥{minPrice.toLocaleString()}{hasVariantChoice ? ' ~' : ''}</div>
        </div>

        {/* Color swatches (eco bag) */}
        {product.colors && (
          <div className="pc-swatch-row">
            <div className="pc-label">カラー</div>
            <div className="pc-swatches">
              {Object.entries(product.colors).map(([k, c]) => (
                <button
                  key={k}
                  className={`swatch ${activeColor === k ? 'active' : ''}`}
                  style={{ background: c }}
                  onClick={() => setActiveColor(k)}
                  aria-label={window.VARIANT_LABELS[k]}
                >
                  <span>{window.VARIANT_LABELS[k]}</span>
                </button>
              ))}
            </div>
          </div>
        )}

        {/* Variants (skip for color-variant products like the eco bag) */}
        {!product.colors && product.variants.length > 1 && (
          <div className="pc-variant-row">
            <div className="pc-label">生地</div>
            <div className="pc-variants">
              {product.variants.map(v => (
                <button
                  key={v}
                  className={`variant-btn ${activeVariant === v ? 'active' : ''}`}
                  onClick={() => { setActiveVariant(v); setActiveSize(null); }}
                >
                  <span className="v-label">{window.VARIANT_LABELS[v]}</span>
                  <span className="v-price">¥{product.price[v].toLocaleString()}</span>
                </button>
              ))}
            </div>
          </div>
        )}

        {/* Sizes */}
        <div className="pc-size-row">
          {(() => {
            const kid = sizes.filter(s => ['100','110','120','130','140','150','160'].includes(s));
            const adult = sizes.filter(s => ['S','M','L','XL','XXL','XXXL'].includes(s));
            const other = sizes.filter(s => !kid.includes(s) && !adult.includes(s));
            const showChart = product.category === 'tshirt-a' || product.category === 'tshirt-b' || product.id === 'bag9' || product.id === 'bag10';
            const renderBtns = (list) => list.map(s => (
              <button
                key={s}
                className={`size-btn ${activeSize === s ? 'active' : ''}`}
                onClick={() => setActiveSize(s)}
              >
                {s}
              </button>
            ));
            return (
              <>
                <div className="pc-label-row">
                  <span className="pc-label">サイズ</span>
                  {showChart && (
                    <button
                      type="button"
                      className={`size-chart-btn ${sizeChartOpen ? 'open' : ''}`}
                      onClick={openSizeChart}
                      aria-expanded={sizeChartOpen}
                    >
                      サイズ表
                    </button>
                  )}
                </div>
                <div className="pc-size-groups">
                  {kid.length > 0 && (
                    <div className="size-group">
                      <div className="size-group-label"><span className="tag tag-kid">キッズ</span></div>
                      <div className="pc-sizes">{renderBtns(kid)}</div>
                    </div>
                  )}
                  {adult.length > 0 && (
                    <div className="size-group">
                      <div className="size-group-label"><span className="tag tag-adult">大人</span></div>
                      <div className="pc-sizes">{renderBtns(adult)}</div>
                    </div>
                  )}
                  {other.length > 0 && (
                    <div className="size-group">
                      <div className="pc-sizes">{renderBtns(other)}</div>
                    </div>
                  )}
                </div>
              </>
            );
          })()}
        </div>

        {/* Qty + Add */}
        <div className="pc-add-row">
          <div className="qty-stepper">
            <button onClick={() => setQty(Math.max(1, qty - 1))}>−</button>
            <span>{qty}</span>
            <button onClick={() => setQty(Math.min(9, qty + 1))}>+</button>
          </div>
          <button
            className={`add-btn ${canAdd ? '' : 'disabled'} ${justAdded ? 'added' : ''}`}
            onClick={handleAdd}
            disabled={!canAdd}
          >
            {justAdded ? '✓ 追加しました' : canAdd ? (
              <>カートに入れる · <span className="add-btn-price">¥{(price * qty).toLocaleString()}</span></>
            ) : 'サイズを選択'}
          </button>
        </div>
      </div>
    </article>
  );
}

window.Catalog = Catalog;
