#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Superium — showcase builder
===========================

Generates ``demo.html``: the package's front door. Hero with live counts, the
three homepages as palette cards, a gallery of every page with a lightbox, a
component library rendered in all three palettes, and the feature list.

    python tools/build_demo.py

Driven by ``assets/data/pages.json`` (written by build_pages.py) and the
screenshots in ``assets/images/shots/``. Add a page to the manifest, rebuild,
and its card appears here automatically.
"""

from __future__ import annotations

import json
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))

from components import fa  # noqa: E402
from layout import icon  # noqa: E402

try:  # only used to read each capture's intrinsic size
    from PIL import Image
except ImportError:  # pragma: no cover
    Image = None

ROOT = Path(__file__).resolve().parent.parent
DATA = ROOT / "assets" / "data"
SHOTS = ROOT / "assets" / "images" / "shots"

GROUPS = [
    ("homepages", "سه صفحه اصلی", "سه معماری چیدمان و سه پالت رنگی مستقل"),
    ("shop", "فرآیند خرید", "از لیست کالا تا انتخاب فروشگاه"),
    ("checkout", "تحویل و پرداخت", "ارسال یا دریافت حضوری، نقشه و درگاه"),
    ("account", "حساب کاربری و پشتیبانی", "ورود، پروفایل، سفارش‌ها و راهنما"),
]

PALETTES = [
    (
        "fresh",
        "تازه - گرم",
        "home-1-fresh.html",
        ["#f2600c", "#16a34a", "#fdf7f1", "#241a12"],
        ["هیرو کلاژی", "ریل دسته‌بندی گرد", "فوتر کامل"],
    ),
    (
        "aqua",
        "آکوا - سرد",
        "home-2-aqua.html",
        ["#0e7490", "#f59e0b", "#f1f5f9", "#0f2530"],
        ["هیرو دوستونه", "کارت زمان تحویل", "چیدمان بنتو"],
    ),
    (
        "graphite",
        "گرافیت - خنثی",
        "home-3-graphite.html",
        ["#a3e635", "#fb923c", "#0f1115", "#f2f4f7"],
        ["هیرو بنری تیره", "کاشی تک‌رنگ", "شبکه قیمت‌محور"],
    ),
]

FEATURES = [
    ("store", "مارکت‌پلیس چندفروشگاهی", "سبد را ببندید، قیمتش را بین فروشگاه‌های اطراف مقایسه کنید و فروشنده را انتخاب کنید."),
    ("truck", "ارسال یا دریافت حضوری", "یک کلید، کل صفحه پرداخت را عوض می‌کند: نقشه، زمان و هزینه ارسال."),
    ("pin", "انتخابگر نقشه بدون SDK", "پین قابل جابه‌جایی روی نقشه‌ی برداری درون‌خطی؛ بدون کلید API و بدون درخواست خارجی."),
    ("grid", "سه پالت مستقل", "هر صفحه اصلی توکن‌های خودش را دارد؛ تغییر یکی روی بقیه اثر ندارد."),
    ("percent", "فیلتر و مرتب‌سازی زنده", "دسته، برند، بازه قیمت و پنج حالت مرتب‌سازی، سمت کاربر."),
    ("shield", "راست‌به‌چپ اصولی", "فقط ویژگی‌های منطقی CSS؛ هیچ left/right فیزیکی در استایل‌ها نیست."),
    ("box", "بدون مرحله build", "HTML/CSS/JS ساده. فایل را باز کنید و کار می‌کند."),
    ("headset", "فونت محلی", "وزیرمتن به‌صورت woff2 داخل پکیج؛ بدون وابستگی به CDN."),
]


def load(name: str):
    path = DATA / name
    if not path.exists():
        sys.exit(f"✗ assets/data/{name} missing — run tools/build_pages.py first.")
    return json.loads(path.read_text(encoding="utf-8"))


def shot(stem: str, view: str = "desktop") -> str | None:
    """Relative path of a capture. WebP is what shots.py writes now; a PNG
    left over from an older run still works."""
    for ext in ("webp", "png"):
        rel = f"assets/images/shots/{stem}-{view}.{ext}"
        if (ROOT / rel).exists():
            return rel
    return None


def dims(rel: str) -> tuple[int, int]:
    """
    A capture's real size. Shots run the whole length of the page, so the
    height varies per page — hard-coding one ratio would have the browser
    reserve the wrong box and jump on decode.
    """
    if Image is not None:
        try:
            with Image.open(ROOT / rel) as im:
                return im.size
        except OSError:
            pass
    return (1440, 1000)


def shot_img(rel: str, alt: str, *, lazy: bool = True) -> str:
    w, h = dims(rel)
    loading = ' loading="lazy"' if lazy else ""
    return f'<img src="{rel}" alt="{alt}" width="{w}" height="{h}"{loading} />'


# --------------------------------------------------------------------------
# Sections
# --------------------------------------------------------------------------


def palette_cards() -> str:
    cards = []
    for slug, title, href, swatches, chips in PALETTES:
        img = shot(href.replace(".html", ""))
        media = (
            shot_img(img, f"پیش‌نمایش {title}")
            if img
            else '<div class="d-shot-missing">پیش‌نمایش موجود نیست</div>'
        )
        swatch_html = "".join(
            f'<span style="background:{c}"></span>' for c in swatches
        )
        chip_html = "".join(f"<span>{c}</span>" for c in chips)
        mobile = shot(href.replace(".html", ""), "mobile")
        mobile_btn = (
            f'<button type="button" class="d-mobile-badge" data-shot="{mobile}" '
            f'data-title="{title} - موبایل">{icon("phone", 14)}<span>موبایل</span></button>'
            if mobile
            else ""
        )
        card = f"""
        <article class="d-home-card d-home-card--{slug}">
          <button type="button" class="d-home-shot" data-shot="{img or ''}"
                  data-title="{title}">{media}</button>
          <div class="d-home-body">
            <div class="d-home-head">
              <h3>{title}</h3>
              <div class="d-swatches">{swatch_html}</div>
            </div>
            <div class="d-chips">{chip_html}</div>
            <div class="d-home-actions">
              <button type="button" class="d-btn d-btn--primary" data-shot="{img or ''}"
                      data-title="{title}">
                {icon("search", 15)}<span>بزرگ‌نمایی</span>
              </button>
              {mobile_btn}
            </div>
          </div>
        </article>"""
        cards.append(card)
    return "".join(cards)


def gallery(pages: list[dict]) -> str:
    blocks = []
    for key, title, blurb in GROUPS:
        rows = [p for p in pages if p["group"] == key]
        if not rows:
            continue

        cards = []
        for p in rows:
            stem = p["file"].replace(".html", "")
            desktop = shot(stem)
            mobile = shot(stem, "mobile")
            media = (
                shot_img(desktop, p["label"])
                if desktop
                else '<div class="d-shot-missing">پیش‌نمایش موجود نیست</div>'
            )
            mobile_badge = (
                f'<button type="button" class="d-mobile-badge" '
                f'data-shot="{mobile}" data-title="{p["label"]} - موبایل">'
                f'{icon("phone", 14)}<span>موبایل</span></button>'
                if mobile
                else ""
            )
            cards.append(f"""
            <article class="d-card">
              <button type="button" class="d-card-shot" data-shot="{desktop or ''}"
                      data-title="{p['label']}">
                {media}
              </button>
              <div class="d-card-body">
                <div class="d-card-head">
                  <h4>{p['label']}</h4>
                  <code>{p['file']}</code>
                </div>
                <p>{p['blurb']}</p>
                <div class="d-card-actions">
                  <button type="button" class="d-btn d-btn--sm d-btn--primary"
                          data-shot="{desktop or ''}" data-title="{p['label']}">
                    {icon("search", 14)}<span>بزرگ‌نمایی</span>
                  </button>
                  {mobile_badge}
                </div>
              </div>
            </article>""")

        blocks.append(f"""
        <section class="d-group">
          <header class="d-group-head">
            <h3>{title}</h3>
            <p>{blurb}</p>
            <span class="d-count">{fa(len(rows))} صفحه</span>
          </header>
          <div class="d-grid">{"".join(cards)}</div>
        </section>""")

    return "".join(blocks)


def components() -> str:
    """Every component rendered once per palette, side by side."""
    def swatch_block(theme: str, label: str) -> str:
        return f"""
        <div class="d-comp-col sp-theme--{theme}" data-theme-demo="{theme}">
          <div class="d-comp-label">{label}</div>

          <div class="d-comp-surface">
            <div class="d-comp-row">
              <button class="sp-btn sp-btn--primary sp-btn--sm">اصلی</button>
              <button class="sp-btn sp-btn--outline sp-btn--sm">خطی</button>
              <button class="sp-btn sp-btn--soft sp-btn--sm">ملایم</button>
              <button class="sp-btn sp-btn--ghost sp-btn--sm">خنثی</button>
            </div>

            <div class="d-comp-row">
              <span class="sp-badge sp-badge--discount">۲۵٪</span>
              <span class="sp-badge sp-badge--success">موجود</span>
              <span class="sp-badge sp-badge--warning">کم‌موجود</span>
              <span class="sp-badge sp-badge--brand">Pro</span>
              <span class="sp-badge sp-badge--stamp"><span>کالا</span><span>برگ</span></span>
            </div>

            <div class="d-comp-row">
              <button class="sp-chip is-active">فعال</button>
              <button class="sp-chip">غیرفعال</button>
              <div class="sp-qty">
                <button type="button" aria-label="افزایش">{icon("plus", 16)}</button>
                <span class="sp-qty-val">۲</span>
                <button type="button" aria-label="کاهش">{icon("minus", 16)}</button>
              </div>
              <button class="sp-qty-add" aria-label="افزودن">{icon("plus", 18)}</button>
            </div>

            <label class="sp-field" style="margin:0">
              <span class="sp-label">فیلد ورودی</span>
              <input class="sp-input" placeholder="متن نمونه" />
            </label>

            <button type="button" class="sp-option is-active">
              <span class="sp-option-dot"></span>
              <span class="sp-option-body">
                <span class="sp-option-title">گزینه انتخاب‌شده</span>
                <span class="sp-option-meta">توضیح کوتاه گزینه</span>
              </span>
            </button>
          </div>
        </div>"""

    cols = "".join(swatch_block(slug, title) for slug, title, *_ in PALETTES)
    return f'<div class="d-comp-grid">{cols}</div>'


def feature_cards() -> str:
    return "".join(
        f"""<article class="d-feature">
          <span class="d-feature-icon">{icon(ico, 22)}</span>
          <h4>{title}</h4>
          <p>{text}</p>
        </article>"""
        for ico, title, text in FEATURES
    )


# --------------------------------------------------------------------------
# Page
# --------------------------------------------------------------------------


def build(pages: list[dict], catalogue: dict) -> str:
    n_pages = len(pages)
    n_shots = len(list(SHOTS.glob("*.webp"))) + len(list(SHOTS.glob("*.png")))
    n_products = len(catalogue["products"])
    n_cats = len(catalogue["categories"])
    hero_shot = shot("home-1-fresh") or ""

    return f"""<!doctype html>
<html lang="fa" dir="rtl">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>سوپردوپر مارکت - قالب RTL سوپرمارکت آنلاین</title>
    <meta name="description"
          content="قالب HTML راست‌به‌چپ سوپرمارکت آنلاین: سه صفحه اصلی، مقایسه فروشگاه‌ها، نقشه، پروفایل و پشتیبانی" />
    <link rel="icon" href="assets/images/brand/favicon.svg" type="image/svg+xml" />
    <link rel="stylesheet" href="assets/css/output.css" />
    <link rel="stylesheet" href="assets/css/superium-palettes.css" />
    <link rel="stylesheet" href="assets/css/superium.css" />
    <link rel="stylesheet" href="assets/css/superium-demo.css" />
  </head>

  <body class="sp-page sp-theme--fresh d-page">
    <!-- ================= HEADER ================= -->
    <header class="d-header">
      <div class="d-container d-header-inner">
        <a href="#top" class="d-logo">
          <svg width="30" height="30" viewBox="0 0 40 40" fill="none" aria-hidden="true">
            <path d="M6.5 15.5h27l-2.4 16.2a3.2 3.2 0 01-3.2 2.8H12.1a3.2 3.2 0 01-3.2-2.8z"
                  stroke="currentColor" stroke-width="2.4" stroke-linejoin="round" />
            <path d="M14 15.5c0-5 2.7-8 6-8s6 3 6 8" stroke="currentColor"
                  stroke-width="2.4" stroke-linecap="round" />
          </svg>
          <span><b>SuperDouper</b><small>سوپردوپر مارکت</small></span>
          <span class="d-tag">قالب HTML</span>
        </a>
        <nav class="d-nav">
          <a href="#homes">صفحه‌های اصلی</a>
          <a href="#pages">همه صفحات</a>
          <a href="#components">کامپوننت‌ها</a>
          <a href="#features">ویژگی‌ها</a>
          <a href="help/help.html">راهنما</a>
        </nav>
        <a href="#pages" class="d-btn d-btn--primary">گالری صفحات</a>
      </div>
    </header>

    <!-- ================= HERO ================= -->
    <section class="d-hero" id="top">
      <div class="d-container">
        <div class="d-hero-grid">
          <div>
            <span class="d-eyebrow">RTL · فارسی · بدون مرحله build</span>
            <h1>قالب سوپرمارکت آنلاین<br /><em>سوپردوپر مارکت</em></h1>
            <p class="d-lead">
              یک مارکت‌پلیس سوپرمارکتی کامل: سبد خرید را می‌بندید، قیمتش بین
              فروشگاه‌های اطراف مقایسه می‌شود، فروشنده را انتخاب می‌کنید و با پیک
              یا حضوری تحویل می‌گیرید. سه صفحه اصلی با پالت و چیدمان مستقل،
              به‌همراه تمام صفحات فرآیند خرید و حساب کاربری.
            </p>
            <div class="d-hero-actions">
              <a href="#pages" class="d-btn d-btn--primary d-btn--lg">گالری صفحات</a>
              <a href="#homes" class="d-btn d-btn--ghost d-btn--lg">سه صفحه اصلی</a>
            </div>
            <dl class="d-stats">
              <div><dt>{fa(n_pages)}</dt><dd>صفحه آماده</dd></div>
              <div><dt>۳</dt><dd>صفحه اصلی</dd></div>
              <div><dt>{fa(n_products)}</dt><dd>کالای واقعی</dd></div>
              <div><dt>{fa(n_cats)}</dt><dd>دسته‌بندی</dd></div>
              <div><dt>{fa(n_shots)}</dt><dd>پیش‌نمایش</dd></div>
            </dl>
          </div>
          <button type="button" class="d-hero-media" data-shot="{hero_shot}"
                  data-title="خانه ۱ - تازه">
            {shot_img(hero_shot, "پیش‌نمایش صفحه اصلی", lazy=False) if hero_shot else ""}
            <span class="d-hero-media-hint">برای بزرگ‌نمایی کلیک کنید</span>
          </button>
        </div>
      </div>
    </section>

    <!-- ================= HOMEPAGES ================= -->
    <section class="d-section" id="homes">
      <div class="d-container">
        <header class="d-section-head">
          <h2>سه صفحه اصلی، سه زبان بصری</h2>
          <p>
            هر صفحه اصلی معماری چیدمان و پالت رنگی خودش را دارد - نه صرفاً تعویض
            رنگ. توکن‌های هر پالت زیر کلاس بدنه‌ی خودش تعریف شده‌اند، بنابراین
            تغییر یکی هرگز روی دیگری اثر نمی‌گذارد.
          </p>
        </header>
        <div class="d-home-grid">{palette_cards()}</div>
      </div>
    </section>

    <!-- ================= PAGES ================= -->
    <section class="d-section d-section--alt" id="pages">
      <div class="d-container">
        <header class="d-section-head">
          <h2>همه صفحات</h2>
          <p>برای بزرگ‌نمایی روی هر تصویر کلیک کنید. کلیدهای ← → و Esc هم کار می‌کنند.</p>
        </header>
        {gallery(pages)}
      </div>
    </section>

    <!-- ================= COMPONENTS ================= -->
    <section class="d-section" id="components">
      <div class="d-container">
        <header class="d-section-head">
          <h2>کامپوننت‌ها در هر سه پالت</h2>
          <p>
            یک مجموعه کامپوننت، سه پالت. همه از توکن‌های
            <code>--sp-*</code> تغذیه می‌شوند؛ هیچ رنگی در کامپوننت hard-code نشده.
          </p>
        </header>
        {components()}
      </div>
    </section>

    <!-- ================= FEATURES ================= -->
    <section class="d-section d-section--alt" id="features">
      <div class="d-container">
        <header class="d-section-head">
          <h2>ویژگی‌ها</h2>
          <p>آنچه این قالب را از یک فروشگاه تک‌فروشنده متمایز می‌کند.</p>
        </header>
        <div class="d-features">{feature_cards()}</div>
      </div>
    </section>

    <!-- ================= FOOTER ================= -->
    <footer class="d-footer">
      <div class="d-container">
        <div class="d-footer-grid">
          <div>
            <b>سوپردوپر مارکت</b>
            <p>
              قالب HTML/CSS/JS راست‌به‌چپ برای سوپرمارکت آنلاین - سه صفحه اصلی
              مستقل، جریان کامل خرید و پنل کاربری. بدون jQuery و بدون مرحله build.
            </p>
          </div>
        </div>
        <div class="d-footer-bottom">
          <span>ساخته‌شده بر پایه‌ی زبان طراحی Novira · صفحه نمایش به سبک Bavarsa</span>
          <a href="help/help.html">راهنمای قالب</a>
        </div>
      </div>
    </footer>

    <!-- ================= LIGHTBOX ================= -->
    <div class="d-lightbox" id="d-lightbox" hidden>
      <button type="button" class="d-lightbox-close" data-lb-close aria-label="بستن">
        {icon("close", 22)}
      </button>
      <button type="button" class="d-lightbox-nav d-lightbox-prev" data-lb-prev
              aria-label="قبلی">{icon("chevron-end", 26)}</button>
      <figure class="d-lightbox-figure">
        <img src="" alt="" id="d-lightbox-img" />
        <figcaption id="d-lightbox-cap"></figcaption>
      </figure>
      <button type="button" class="d-lightbox-nav d-lightbox-next" data-lb-next
              aria-label="بعدی">{icon("chevron-start", 26)}</button>
    </div>

    <script src="assets/js/superium-demo.js"></script>
  </body>
</html>
"""


def main() -> int:
    pages = load("pages.json")
    catalogue = load("products.json")
    (ROOT / "demo.html").write_text(build(pages, catalogue), encoding="utf-8")
    shots = len(list(SHOTS.glob("*.webp"))) + len(list(SHOTS.glob("*.png")))
    print(f"  ✓ demo.html  ({len(pages)} pages, {shots} shots)")
    return 0


if __name__ == "__main__":
    sys.exit(main())
