(() => {
  window.MamoruApp = window.MamoruApp || {};

  const { C, NS } = window.MamoruApp;
  const GUIDE_VISUALS = {
    cityWalk: {
      src: "https://images.pexels.com/photos/14934116/pexels-photo-14934116.jpeg?auto=compress&cs=tinysrgb&w=1200",
      alt: "街中を歩く女性の後ろ姿",
      creditLabel: "Photo: Pexels / Masood Aslami",
      creditUrl: "https://www.pexels.com/photo/woman-in-coat-with-backpack-in-city-14934116/",
    },
    bagStyle: {
      src: "https://images.pexels.com/photos/7242769/pexels-photo-7242769.jpeg?auto=compress&cs=tinysrgb&w=1200",
      alt: "街中でバッグを持つ女性",
      creditLabel: "Photo: Pexels / Marcus Queiroga Silva",
      creditUrl: "https://www.pexels.com/photo/woman-with-bag-12774440/",
    },
    homeDesk: {
      src: "https://images.pexels.com/photos/12911629/pexels-photo-12911629.jpeg?auto=compress&cs=tinysrgb&w=1200",
      alt: "自宅の机でノートPCを使う女性",
      creditLabel: "Photo: Pexels / Mizuno K",
      creditUrl: "https://www.pexels.com/photo/woman-sitting-at-table-at-home-working-at-laptop-12911629/",
    },
    cozyHome: {
      src: "https://images.pexels.com/photos/35962982/pexels-photo-35962982.jpeg?auto=compress&cs=tinysrgb&w=1200",
      alt: "リビングでノートPCを使う女性",
      creditLabel: "Photo: Pexels / Letícia Alvares",
      creditUrl: "https://www.pexels.com/photo/woman-working-comfortably-at-home-with-laptop-35962982/",
    },
    flashlight: {
      src: "https://images.pexels.com/photos/11718775/pexels-photo-11718775.jpeg?auto=compress&cs=tinysrgb&w=1200",
      alt: "夜にライトを使う人のシルエット",
      creditLabel: "Photo: Pexels / Jeffry Surianto",
      creditUrl: "https://www.pexels.com/photo/woman-pointing-a-flash-light-to-the-sky-11718775/",
    },
  };

  function pickGuideVisual(article = {}) {
    const slug = article.slug || "";
    const title = article.title || "";
    const category = article.category || "";

    if (/led-light|ライト/i.test(slug) || /LED|ライト/.test(title)) return GUIDE_VISUALS.flashlight;
    if (/living-alone|return-home|apartment|home/i.test(slug) || /一人暮らし|帰宅/.test(title)) return GUIDE_VISUALS.homeDesk;
    if (/cute|bag|portable|wallet/i.test(slug) || /かわいい|バッグ|持ち歩き/.test(title)) return GUIDE_VISUALS.bagStyle;
    if (/gps|privacy|legal|spray/i.test(slug) || /GPS|法律|スプレー/.test(title) || category === "一人暮らし") return GUIDE_VISUALS.cozyHome;
    return GUIDE_VISUALS.cityWalk;
  }

  window.MamoruApp.getGuideVisual = function getGuideVisual(article) {
    return pickGuideVisual(article);
  };

  window.MamoruApp.Wrap = function Wrap({ children, className = "", style = {} }) {
    return <div className={className} style={{ maxWidth: 1120, width: "100%", margin: "0 auto", paddingLeft: "var(--wrap-inline, 40px)", paddingRight: "var(--wrap-inline, 40px)", ...style }}>{children}</div>;
  };

  window.MamoruApp.Eyebrow = function Eyebrow({ children, light = false }) {
    return (
      <div
        style={{
          fontSize: 10,
          fontFamily: NS,
          letterSpacing: "0.2em",
          textTransform: "uppercase",
          color: light ? "rgba(255,255,255,0.52)" : C.accent,
          marginBottom: 10,
        }}
      >
        {children}
      </div>
    );
  };

  window.MamoruApp.SectionHeading = function SectionHeading({ children, light = false, align = "left" }) {
    return (
      <h2
        style={{
          fontSize: "clamp(20px,2.2vw,24px)",
          fontFamily: NS,
          fontWeight: 700,
          color: light ? "#fff" : C.navy,
          lineHeight: 1.4,
          letterSpacing: "0.01em",
          textAlign: align,
        }}
      >
        {children}
      </h2>
    );
  };

  window.MamoruApp.SectionHeader = function SectionHeader({
    eyebrow,
    title,
    body,
    action = null,
    align = "left",
    maxWidth = 460,
    style = {},
  }) {
    const Eyebrow = window.MamoruApp.Eyebrow;
    const SectionHeading = window.MamoruApp.SectionHeading;

    const textBlock = (
      <div style={{ maxWidth, textAlign: align }}>
        {eyebrow && <Eyebrow>{eyebrow}</Eyebrow>}
        <SectionHeading align={align}>{title}</SectionHeading>
        {body && (
          <p
            style={{
              fontSize: 14,
              fontFamily: NS,
              color: C.muted,
              lineHeight: 1.85,
              marginTop: 10,
            }}
          >
            {body}
          </p>
        )}
      </div>
    );

    if (action) {
      return (
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            alignItems: "flex-end",
            gap: 16,
            flexWrap: "wrap",
            ...style,
          }}
        >
          {textBlock}
          <div style={{ flexShrink: 0 }}>{action}</div>
        </div>
      );
    }

    return (
      <div
        style={{
          maxWidth,
          textAlign: align,
          ...style,
        }}
      >
        {eyebrow && <Eyebrow>{eyebrow}</Eyebrow>}
        <SectionHeading align={align}>{title}</SectionHeading>
        {body && (
          <p
            style={{
              fontSize: 14,
              fontFamily: NS,
              color: C.muted,
              lineHeight: 1.85,
              marginTop: 10,
            }}
          >
            {body}
          </p>
        )}
      </div>
    );
  };

  window.MamoruApp.VisualPlaceholder = function VisualPlaceholder({
    label = "画像が入ります",
    note = "差し替え用ビジュアル",
    aspect = "4 / 3",
    compact = false,
    light = false,
    style = {},
  }) {
    const borderColor = light ? "rgba(255,255,255,0.22)" : C.border;
    const textColor = light ? "rgba(255,255,255,0.72)" : C.navy;
    const noteColor = light ? "rgba(255,255,255,0.48)" : C.muted;
    const fillColor = light ? "rgba(255,255,255,0.12)" : C.navyPale;

    return (
      <div
        style={{
          width: "100%",
          aspectRatio: aspect,
          borderRadius: 10,
          border: `1px solid ${borderColor}`,
          background: fillColor,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          padding: compact ? 18 : 28,
          position: "relative",
          overflow: "hidden",
          ...style,
        }}
      >
        <div
          style={{
            position: "absolute",
            inset: compact ? 10 : 14,
            border: `1px solid ${borderColor}`,
            borderRadius: 8,
          }}
        />
        <div style={{ textAlign: "center", position: "relative" }}>
          <div
            style={{
              width: compact ? 40 : 54,
              height: compact ? 40 : 54,
              borderRadius: "50%",
              border: `1px solid ${borderColor}`,
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              margin: "0 auto 12px",
            }}
          >
            <svg width={compact ? 20 : 24} height={compact ? 20 : 24} viewBox="0 0 24 24" fill="none">
              <rect x="4" y="5" width="16" height="14" rx="2" stroke={textColor} strokeWidth="1.4" />
              <path d="M7 16L10.5 12.5L13 15L15 13L18 16" stroke={textColor} strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" />
              <circle cx="9" cy="9" r="1.2" fill={textColor} />
            </svg>
          </div>
          <div style={{ fontSize: compact ? 12 : 13, fontFamily: NS, fontWeight: 700, color: textColor, letterSpacing: "0.04em" }}>{label}</div>
          <div style={{ fontSize: 11, fontFamily: NS, color: noteColor, marginTop: 5, letterSpacing: "0.04em" }}>{note}</div>
        </div>
      </div>
    );
  };

  window.MamoruApp.TextList = function TextList({ items = [], tone = "muted" }) {
    const color = tone === "body" ? C.text : C.muted;

    return (
      <div className="bullet-list">
        {items.map((item) => (
          <div key={item} className="bullet-list__item">
            <span className="bullet-list__dot" />
            <span className="bullet-list__text" style={{ color }}>{item}</span>
          </div>
        ))}
      </div>
    );
  };

  window.MamoruApp.ProductCard = function ProductCard({
    product,
    categoryLabel = "",
    setPage,
    showExternalLink = true,
    detailLabel = "詳しく見る",
  }) {
    const externalUrl = product.externalUrl || "";
    const shopName = product.shopName || "外部サイト";

    return (
      <article className="product-card" onClick={() => setPage(`product:${product.id}`)}>
        <div className="product-card__media">
          {product.imageSrc ? (
            <div className="product-card__image-frame">
              <img className="product-card__image" src={product.imageSrc} alt={product.imageAlt || product.name} loading="lazy" />
            </div>
          ) : (
            <div className="product-card__image-frame">
              <img
                className="product-card__image"
                src="./assets/images/product-fallback-soft.svg"
                alt={product.imageAlt || `${product.name} のイメージ`}
                loading="lazy"
              />
            </div>
          )}
        </div>
        <div className="product-card__content">
          <div className="product-card__badges">
            {categoryLabel && <span className="badge badge--category">{product.cat} / {categoryLabel}</span>}
            {product.subtype && <span className="badge badge--soft">{product.subtype}</span>}
            {product.tag && <span className="badge badge--outline">{product.tag}</span>}
          </div>
          <h2 className="product-card__title">{product.name}</h2>
          <div className="product-card__meta">{product.scene.join("・")} / {product.tagline}</div>
          <p className="product-card__desc">{product.desc}</p>
          <div className="product-card__fit">おすすめ: {product.fit}</div>
          <div className="product-card__footer">
            <div className="product-card__price-block">
              <span className="product-card__price">{product.price}</span>
              {product.priceNote && <span className="product-card__price-note">{product.priceNote}</span>}
            </div>
            <div className="product-card__actions">
              <button
                onClick={(e) => {
                  e.stopPropagation();
                  setPage(`product:${product.id}`);
                }}
                className="text-link text-link--subtle"
              >
                {detailLabel}
              </button>
              {showExternalLink && (
                externalUrl ? (
                  <a
                    href={externalUrl}
                    target="_blank"
                    rel="noreferrer"
                    onClick={(e) => e.stopPropagation()}
                    className="text-link text-link--accent"
                  >
                    {shopName} →
                  </a>
                ) : (
                  <span className="text-link text-link--disabled">リンク準備中</span>
                )
              )}
            </div>
          </div>
        </div>
      </article>
    );
  };

  window.MamoruApp.Divider = function Divider({ style = {} }) {
    return <div style={{ height: 1, background: C.border, ...style }} />;
  };

  window.MamoruApp.surfaceStyle = function surfaceStyle({ tone = "white", accent = false } = {}) {
    return {
      background: tone === "cool" ? C.bgCool : tone === "warm" ? C.bgWarm : C.white,
      border: `1px solid ${accent ? C.borderAccent : C.border}`,
      borderRadius: 10,
      boxShadow: C.shadowSoft,
    };
  };
})();
