/* Media — Instagram strip for the landing page.
   Mirrors the Media block on the MNC site (eyebrow + display heading + lede),
   but the cards are Instagram posts in a horizontal, swipeable rail.

   Three behaviours are specified:
     1. horizontal scroll  — scroll-snap rail; native swipe on touch, arrows on desktop
     2. random order       — shuffled once per page load (useMemo on mount)
     3. share              — Web Share API first, on-brand fallback popover after
*/

/* ─────────────────────────────────────────────────────────────────────────
   CONFIG — the chosen posts, in any order (they get shuffled on every load).

     url    the public permalink; also what the share button shares.
            https://www.instagram.com/reel/SHORTCODE/  or  /p/SHORTCODE/
     title  carries the card. Keep it short — it is set in Fraunces at display
            size and is the first thing anyone reads.
     date   shown in the eyebrow next to REEL. Each one is the reel's own
            publication date, decoded from its shortcode.
     kind   "reel" (default) or "post" — only changes the eyebrow word.
     motif  the <gen-cover> drawing behind the title (shared/gen-cover.js),
            chosen per reel for its subject. A post without one gets a stable
            pick from IG_FALLBACK_MOTIFS, so new reels do not all get the same one.
   ───────────────────────────────────────────────────────────────────────── */
const MEC_IG_POSTS = [
  { url: "https://www.instagram.com/reel/Dbcqidqzv7T/", date: "31 July 2026",
    title: "Rumi’s Question To Mankind", motif: "rumi" },
  { url: "https://www.instagram.com/reel/DbITIbBTRhL/", date: "23 July 2026",
    title: "The Greatest Words Ever Spoken", motif: "greatest" },
  { url: "https://www.instagram.com/reel/Da2gX2_pMti/", date: "16 July 2026",
    title: "The Goat That Flew", motif: "goat" },
  { url: "https://www.instagram.com/reel/Dav1R9MPbrE/", date: "13 July 2026",
    title: "One Declaration Changes Everything", motif: "declaration2" },
  { url: "https://www.instagram.com/reel/DakYr4NJa13/", date: "9 July 2026",
    title: "AI or the Brain?", motif: "ai2" },
  { url: "https://www.instagram.com/reel/DYDUCJTPgbb/", date: "7 May 2026",
    title: "Islam: Worship. Avoid. Beautify.", motif: "worship2" },
  { url: "https://www.instagram.com/reel/DXFg7_FPKHK/", date: "13 April 2026",
    title: "The True Reason You Exist", motif: "exist" },
  { url: "https://www.instagram.com/reel/DXBpzMmPTF4/", date: "12 April 2026",
    title: "Want Peace and Success?", motif: "peace" },
  { url: "https://www.instagram.com/reel/DWLlOeVjr31/", date: "22 March 2026",
    title: "The Answer Your Missing", motif: "answer" },
  { url: "https://www.instagram.com/reel/DUjSz7fDTAW/", date: "9 February 2026",
    title: "Code to Unlock Real Success", motif: "success" },
  { url: "https://www.instagram.com/reel/DUY_oYbDS3a/", date: "5 February 2026",
    title: "When Love Overflows", motif: "love2" },
  { url: "https://www.instagram.com/reel/DT_Po9mj-xH/", date: "26 January 2026",
    title: "Unmatched Reward", motif: "reward2" },
  { url: "https://www.instagram.com/reel/DS-31TYElsi/", date: "1 January 2026",
    title: "Jesus Peace Be Upon Him", motif: "jesus2" },
  { url: "https://www.instagram.com/reel/DS3JYvDEmun/", date: "29 December 2025",
    title: "Mary our Beloved Mother", motif: "mary_mihrab" },
  { url: "https://www.instagram.com/reel/DSIzJKVkjCO/", date: "11 December 2025",
    title: "Concerned about Death?", motif: "death2" },
  { url: "https://www.instagram.com/reel/DR2xkvvEiyo/", date: "4 December 2025",
    title: "This may be your only chance!", motif: "chance2" },
  { url: "https://www.instagram.com/reel/DRvDNtJkzLF/", date: "1 December 2025",
    title: "Love But… Which God?", motif: "god_align" },
  { url: "https://www.instagram.com/reel/DRdBnOLEuMC/", date: "24 November 2025",
    title: "Love People & Protect Nature", motif: "nature" },
  { url: "https://www.instagram.com/reel/DRSuZbAkovq/", date: "20 November 2025",
    title: "Feel Like There's No Purpose?", motif: "purpose" },
  { url: "https://www.instagram.com/reel/DRAs35_kpNX/", date: "13 November 2025",
    title: "Paradise Lies Beneath Her Feet", motif: "paradise2" },
  { url: "https://www.instagram.com/reel/DQ4-hL-k1uI/", date: "10 November 2025",
    title: "The Book That Holds Every Answer", motif: "book" },
  { url: "https://www.instagram.com/reel/DQm_BixE58S/", date: "3 November 2025",
    title: "The Secret to True Happiness", motif: "happiness" },
  { url: "https://www.instagram.com/reel/DQKqpflE6wK/", date: "23 October 2025",
    title: "Faith Built for Community", motif: "community2" },
];

/* For a post added without a motif: general-purpose drawings none of the
   listed reels use, picked by the post's url so the choice holds across loads. */
const IG_FALLBACK_MOTIFS = ["peace2", "exist2", "happiness2", "purpose2", "community"];
function igMotif(p) {
  if (p.motif) return p.motif;
  let h = 0; for (const ch of p.url || "") h = (h * 31 + ch.charCodeAt(0)) >>> 0;
  return IG_FALLBACK_MOTIFS[h % IG_FALLBACK_MOTIFS.length];
}

/* Instagram's embed wants a canonical permalink with the trailing slash, and
   ignores query strings (?igsh=… from the share sheet). Normalising here means
   the list above can be pasted in whatever form the links arrive. */
function igPermalink(url) {
  const clean = String(url || "").split("?")[0].split("#")[0].replace(/\/+$/, "");
  return clean ? clean + "/" : "";
}

const MEDIA_I18N = {
  media:      { en: "Media", tr: "Medya", es: "Medios", de: "Medien", fr: "Médias", ru: "Медиа", ja: "メディア", zh: "媒体" },
  media_lede: {
    en: "Explore and share Esad Cosan's reels and posts.",
    tr: "Esad Coşan'ın reel'lerini ve paylaşımlarını keşfedin, paylaşın.",
    es: "Descubre y comparte los reels y publicaciones de Esad Cosan.",
    de: "Entdecken und teilen Sie die Reels und Beiträge von Esad Cosan.",
    fr: "Découvrez et partagez les reels et les publications d'Esad Cosan.",
    ru: "Смотрите Reels и публикации Эсада Джошана и делитесь ими.",
    ja: "エサド・コシャンのリールと投稿を見て、シェアしましょう。",
    zh: "探索并分享科尚的 Reels 与帖子。",
  },
  view_on_ig: { en: "View on Instagram", tr: "Instagram'da gör", es: "Ver en Instagram", de: "Auf Instagram ansehen", fr: "Voir sur Instagram", ru: "Открыть в Instagram", ja: "Instagram で見る", zh: "在 Instagram 上查看" },
  /* Card link label. Short on purpose — the section already says where these
     come from, and the full "Watch on Instagram" crowded the card footer. */
  watch:      { en: "Watch", tr: "İzle", es: "Ver", de: "Ansehen", fr: "Regarder", ru: "Смотреть", ja: "見る", zh: "观看" },
  post:       { en: "Post", tr: "Gönderi", es: "Publicación", de: "Beitrag", fr: "Publication", ru: "Публикация", ja: "投稿", zh: "帖子" },
  share:      { en: "Share", tr: "Paylaş", es: "Compartir", de: "Teilen", fr: "Partager", ru: "Поделиться", ja: "シェア", zh: "分享" },
  share_post: { en: "Share this post", tr: "Bu paylaşımı paylaş", es: "Compartir esta publicación", de: "Diesen Beitrag teilen", fr: "Partager cette publication", ru: "Поделиться публикацией", ja: "この投稿をシェア", zh: "分享这条帖子" },
  copy_link:  { en: "Copy link", tr: "Bağlantıyı kopyala", es: "Copiar enlace", de: "Link kopieren", fr: "Copier le lien", ru: "Скопировать ссылку", ja: "リンクをコピー", zh: "复制链接" },
  copied:     { en: "Link copied", tr: "Bağlantı kopyalandı", es: "Enlace copiado", de: "Link kopiert", fr: "Lien copié", ru: "Ссылка скопирована", ja: "リンクをコピーしました", zh: "链接已复制" },
  more:       { en: "More…", tr: "Diğer…", es: "Más…", de: "Mehr…", fr: "Plus…", ru: "Ещё…", ja: "その他…", zh: "更多…" },
  story_hint: {
    en: "Stories only take a picture, and only from a phone. Open this page on your phone and the share button hands the card straight to Instagram or WhatsApp.",
    tr: "Hikâyeler yalnızca görsel kabul ediyor, o da yalnızca telefondan. Bu sayfayı telefonunuzda açın; paylaş düğmesi kartı doğrudan Instagram'a ya da WhatsApp'a verir.",
    es: "Las historias solo aceptan una imagen, y solo desde el móvil. Abre esta página en tu teléfono y el botón de compartir entrega la tarjeta directamente a Instagram o WhatsApp.",
    de: "Storys nehmen nur ein Bild an, und das nur vom Handy. Öffnen Sie diese Seite auf dem Telefon, dann reicht die Teilen-Schaltfläche die Karte direkt an Instagram oder WhatsApp weiter.",
    fr: "Les stories n'acceptent qu'une image, et seulement depuis un téléphone. Ouvrez cette page sur le vôtre et le bouton de partage remet la carte directement à Instagram ou WhatsApp.",
    ru: "Истории принимают только картинку и только с телефона. Откройте эту страницу на телефоне, и кнопка «Поделиться» передаст карточку прямо в Instagram или WhatsApp.",
    ja: "ストーリーズは画像しか受け取らず、それもスマートフォンからだけです。この画面をスマートフォンで開けば、シェアボタンがカードをそのまま Instagram や WhatsApp に渡します。",
    zh: "快拍只接受图片，而且只能从手机发送。用手机打开本页，分享按钮会把卡片直接交给 Instagram 或 WhatsApp。",
  },
  prev:       { en: "Previous", tr: "Önceki", es: "Anterior", de: "Zurück", fr: "Précédent", ru: "Назад", ja: "前へ", zh: "上一个" },
  next:       { en: "Next", tr: "Sonraki", es: "Siguiente", de: "Weiter", fr: "Suivant", ru: "Вперёд", ja: "次へ", zh: "下一个" },
  /* Instagram's own word for the format — left untranslated the way the rest of
     the site leaves proper nouns alone; it is the clearest "this is video" cue. */
  reel:       { en: "Reel", tr: "Reel", es: "Reel", de: "Reel", fr: "Reel", ru: "Reels", ja: "リール", zh: "Reels" },
};
function mediaT(key, lang) { const e = MEDIA_I18N[key]; return (e && (e[lang] || e.en)) || ""; }

/* Fisher–Yates. Runs once per mount, so every page load gets a fresh order. */
function igShuffle(list) {
  const a = list.slice();
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    const t = a[i]; a[i] = a[j]; a[j] = t;
  }
  return a;
}

/* Web share targets used only when the browser has no native share sheet.
   Instagram and WhatsApp *stories* are deliberately absent: neither platform
   exposes a web endpoint that accepts content from a page — the only route to
   them is the OS share sheet (navigator.share) or pasting a copied link. */
const IG_SHARE_TARGETS = [
  { key: "x",        label: "X",        href: (u, t) => `https://x.com/intent/post?url=${encodeURIComponent(u)}&text=${encodeURIComponent(t)}` },
  { key: "facebook", label: "Facebook", href: (u)    => `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(u)}` },
  { key: "whatsapp", label: "WhatsApp", href: (u, t) => `https://wa.me/?text=${encodeURIComponent(t + " " + u)}` },
];

async function igCopy(text) {
  try {
    if (navigator.clipboard && window.isSecureContext) { await navigator.clipboard.writeText(text); return true; }
  } catch (e) { /* fall through to the legacy path */ }
  try {
    const ta = document.createElement("textarea");
    ta.value = text; ta.setAttribute("readonly", "");
    ta.style.cssText = "position:fixed;top:-1000px;opacity:0";
    document.body.appendChild(ta); ta.select();
    const ok = document.execCommand("copy");
    document.body.removeChild(ta);
    return ok;
  } catch (e) { return false; }
}

/* ───── Share control ─────
   Native sheet when the browser has one (that is the only path that reaches
   Instagram Stories / WhatsApp Status), otherwise an anchored popover.
   The popover is position:fixed so the rail's overflow can't clip it. */
/* `variant="quiet"` drops the box for the sayings strip, whose cards have no
   border of their own; `label` overrides the accessible name for the same
   reason. Everything else — the native sheet, the portalled popover, the copy
   fallback — is shared, so there is one share control on the site, not two. */
const IG_SHARE_SITE = "https://esadcosan.global";

function IgShareButton({ url, title, text, lang, accent, variant, label, image, caption }) {
  const [open, setOpen] = React.useState(false);
  const [copied, setCopied] = React.useState(false);
  const [rect, setRect] = React.useState(null);
  const btnRef = React.useRef(null);
  const popRef = React.useRef(null);
  const t = (k) => mediaT(k, lang);

  const close = React.useCallback(() => { setOpen(false); setCopied(false); }, []);

  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape") { close(); btnRef.current && btnRef.current.focus(); } };
    const onDown = (e) => {
      if (popRef.current && popRef.current.contains(e.target)) return;
      if (btnRef.current && btnRef.current.contains(e.target)) return;
      close();
    };
    document.addEventListener("keydown", onKey);
    document.addEventListener("mousedown", onDown);
    window.addEventListener("resize", close);
    window.addEventListener("scroll", close, true);
    return () => {
      document.removeEventListener("keydown", onKey);
      document.removeEventListener("mousedown", onDown);
      window.removeEventListener("resize", close);
      window.removeEventListener("scroll", close, true);
    };
  }, [open, close]);

  const onShare = async (e) => {
    e.preventDefault(); e.stopPropagation();
    /* The picture route, when the caller has an image for this item. Instagram
       and WhatsApp stories accept a file and nothing else, and only through the
       device's own sheet — a link gets them nowhere. So the card's own picture
       is handed over first, and everything else is the fallback. */
    if (image && navigator.canShare && window.File) {
      try {
        const res = await fetch(image, { cache: "force-cache" });
        if (res.ok) {
          const blob = await res.blob();
          const file = new File([blob], image.split("/").pop(), { type: blob.type || "image/jpeg" });
          if (navigator.canShare({ files: [file] })) {
            await navigator.share({ files: [file], text: (caption || title) + " - " + IG_SHARE_SITE });
            return;
          }
        }
      } catch (err) {
        if (err && err.name === "AbortError") return;   // user dismissed the sheet
        /* anything else: fall through to the link routes below */
      }
    }
    const payload = { title, text, url };
    if (navigator.share && (!navigator.canShare || navigator.canShare(payload))) {
      try { await navigator.share(payload); return; }
      catch (err) {
        if (err && err.name === "AbortError") return;   // user dismissed the sheet
        /* anything else: fall through to the popover */
      }
    }
    const r = btnRef.current.getBoundingClientRect();
    setRect(r);
    setOpen((v) => !v);
  };

  const openTarget = (href) => {
    window.open(href, "_blank", "noopener,noreferrer,width=600,height=640");
    close();
  };

  const PANEL_W = 232;
  let panelStyle = null;
  if (open && rect) {
    const above = rect.top > 320;                       // flip up when there is room
    const left = Math.min(Math.max(12, rect.right - PANEL_W), window.innerWidth - PANEL_W - 12);
    panelStyle = {
      position: "fixed", zIndex: 9999, width: PANEL_W, left,
      ...(above ? { bottom: window.innerHeight - rect.top + 10 } : { top: rect.bottom + 10 }),
    };
  }

  return (
    <>
      <button
        ref={btnRef}
        type="button"
        onClick={onShare}
        aria-haspopup="menu"
        aria-expanded={open}
        aria-label={label || t("share_post")}
        className={"ig-share-btn" + (variant === "quiet" ? " ig-share-quiet" : "")}
        style={{ borderColor: open ? accent : undefined, color: open ? accent : undefined }}
      >
        {/* share glyph — three nodes joined, no vendor branding */}
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7"
          strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
          <circle cx="18" cy="5" r="2.6" /><circle cx="6" cy="12" r="2.6" /><circle cx="18" cy="19" r="2.6" />
          <path d="M8.4 10.8 15.6 6.4M8.4 13.2l7.2 4.4" />
        </svg>
      </button>

      {/* Portalled to <body>: the card lifts on hover with a transform, and a
          transformed ancestor becomes the containing block for position:fixed,
          which threw the panel across the page. */}
      {open && panelStyle && ReactDOM.createPortal(
        <div ref={popRef} role="menu" aria-label={label || t("share_post")} className="ig-share-pop" style={panelStyle}>
          {IG_SHARE_TARGETS.map((s) => (
            <button key={s.key} type="button" role="menuitem" className="ig-share-item"
              onClick={() => openTarget(s.href(url, text))}>
              {s.label}
            </button>
          ))}
          <button type="button" role="menuitem" className="ig-share-item"
            onClick={async () => { const ok = await igCopy(url); setCopied(ok); if (ok) setTimeout(close, 1200); }}>
            {copied ? t("copied") : t("copy_link")}
          </button>
          <p className="ig-share-hint">{t("story_hint")}</p>
        </div>,
        document.body
      )}
    </>
  );
}

/* ───── The strip ─────
   Named IgMediaStrip, not MediaStrip: pages/library-media.jsx already owns
   that global for the video row on /library. */
function IgMediaStrip({ mobile = false, accent = "#B89968" }) {
  const [lang] = (typeof useLang === "function" ? useLang() : ["en"]);
  const t = (k) => mediaT(k, lang);
  const posts = React.useMemo(() => igShuffle(MEC_IG_POSTS), []);
  /* The covers follow the header's sun button: gen-cover redraws itself when
     its tone attribute changes. */
  const [theme] = (typeof useTheme === "function" ? useTheme() : ["light"]);
  const tone = theme === "dark" ? "dark" : "light";
  const railRef = React.useRef(null);
  const secRef = React.useRef(null);
  const prevRef = React.useRef(null);
  const nextRef = React.useRef(null);
  const barRef = React.useRef(null);
  /* Written straight onto the buttons rather than held in state: this runs on
     every scroll frame, and a re-render per frame would be wasteful.
     aria-disabled rather than the disabled attribute, so React never fights us
     over it and the button keeps receiving clicks (nudge no-ops at the ends). */
  const syncEdges = React.useCallback(() => {
    const el = railRef.current; if (!el) return;
    const max = el.scrollWidth - el.clientWidth;
    if (prevRef.current) prevRef.current.setAttribute("aria-disabled", String(el.scrollLeft <= 8));
    if (nextRef.current) nextRef.current.setAttribute("aria-disabled", String(el.scrollLeft >= max - 8));
    /* same progress bar as under the sayings: the viewport drawn onto the row */
    if (barRef.current) {
      barRef.current.style.width = Math.min(100, el.clientWidth / el.scrollWidth * 100) + "%";
      barRef.current.style.left = (max ? el.scrollLeft / el.scrollWidth * 100 : 0) + "%";
    }
  }, []);

  React.useEffect(() => {
    syncEdges();
    const el = railRef.current; if (!el) return;
    el.addEventListener("scroll", syncEdges, { passive: true });
    window.addEventListener("resize", syncEdges);
    return () => { el.removeEventListener("scroll", syncEdges); window.removeEventListener("resize", syncEdges); };
  }, [syncEdges, posts]);

  const nudge = (dir) => {
    const el = railRef.current; if (!el) return;
    const card = el.querySelector("[data-ig-card]");
    const step = (card ? card.getBoundingClientRect().width : 320) + 20;
    const calm = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const from = el.scrollLeft;
    const to = Math.max(0, Math.min(from + dir * step, el.scrollWidth - el.clientWidth));
    if (to === from) return;
    el.scrollTo({ left: to, behavior: calm ? "auto" : "smooth" });
    /* The smooth animation is driven by rAF, which some environments never run
       (throttled background tabs, animation-suppressing modes). If nothing has
       moved shortly after, land the scroll outright so the arrow always works. */
    window.setTimeout(() => {
      if (el.scrollLeft === from) el.scrollTo({ left: to, behavior: "auto" });
      syncEdges();
    }, 280);
    window.setTimeout(syncEdges, 700);   // scroll events alone can't be relied on
  };

  if (!posts.length) return null;

  const title = "Mahmud Esad Coşan";

  return (
    <section ref={secRef} className="hf-reveal" style={{
      padding: mobile ? "56px 0 64px" : "120px 0 140px",
      borderTop: "1px solid var(--hairline)",
    }}>
      {/* header — same rhythm as the other landing sections */}
      <div style={{
        padding: mobile ? "0 22px" : "0 96px",
        display: "flex", justifyContent: "space-between", alignItems: "flex-end",
        gap: 24, marginBottom: mobile ? 28 : 48,
      }}>
        <div style={{ maxWidth: 620 }}>
          <h2 className="serif" style={{
            fontWeight: 400, fontSize: "clamp(34px, 5vw, 66px)", letterSpacing: "-0.02em",
            margin: "0 0 14px", lineHeight: 1.0,
            fontVariationSettings: '"opsz" 96, "SOFT" 30',
          }}>{t("media")}</h2>
          <p className="lede">{t("media_lede")}</p>
        </div>

        {!mobile && (
          <div style={{ display: "flex", gap: 8, flex: "0 0 auto" }}>
            <button ref={prevRef} type="button" className="ig-nav" aria-label={t("prev")} aria-disabled="true" onClick={() => nudge(-1)}>←</button>
            <button ref={nextRef} type="button" className="ig-nav" aria-label={t("next")} aria-disabled="false" onClick={() => nudge(1)}>→</button>
          </div>
        )}
      </div>

      {/* rail */}
      <div ref={railRef} className="ig-rail" style={{ paddingInline: mobile ? 22 : 96, scrollPaddingInline: mobile ? 22 : 96 }}>
        {posts.map((p, i) => {
          const url = igPermalink(p.url);
          const label = p.title || p.caption || t("view_on_ig");
          return (
          <article key={url || i} data-ig-card data-tone={tone} className="ig-card"
            style={{ flexBasis: mobile ? "78%" : 320 }}>
            {/* Styled on the element itself: gen-cover sets no size of its own
                and draws nothing into a box without one. */}
            <gen-cover motif={igMotif(p)} tone={tone} aria-hidden="true"
              style={{ position: "absolute", left: 0, right: 0, top: 0, height: "66%", display: "block" }} />
            <div className="ig-card-veil" aria-hidden="true" />
            <div className="ig-card-head">
              {/* Own play mark, so "video" is stated in the site's own hand
                  rather than borrowed from a platform thumbnail. */}
              <span className="ig-play" aria-hidden="true">
                <svg width="12" height="14" viewBox="0 0 12 14"><path d="M0 0v14l12-7z" fill="currentColor" /></svg>
              </span>
              <span className="ig-card-meta">
                {t(p.kind === "post" ? "post" : "reel")}{p.date ? ` · ${p.date}` : ""}
              </span>
            </div>

            <div className="ig-card-body">
              <h3 className="serif ig-card-title">{label}</h3>
              <div className="ig-card-foot">
                <a href={url} target="_blank" rel="noopener noreferrer"
                  className="ig-card-link ig-card-stretch" style={{ color: accent }}>
                  {t("watch")} <span aria-hidden="true">→</span>
                </a>
                <IgShareButton url={url} title={title} text={label} lang={lang} accent={accent} />
              </div>
            </div>
          </article>
          );
        })}
      </div>

      {/* The sayings strip's progress hairline, so both rails tell the reader
          the same thing. The arrows stay up in the header here. */}
      <div className="sy-rail-foot" style={{ marginInline: mobile ? 22 : 96 }}>
        <div className="sy-rail-track"><i ref={barRef} /></div>
      </div>
    </section>
  );
}

Object.assign(window, { IgMediaStrip, MEC_IG_POSTS });
