// MT Research — Ko-fi content gallery. Interactive: search / filter / sort / free-vs-member.
// Three switchable visual directions via Tweaks: gallery · editorial · index.
const { useState, useMemo, useEffect } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "direction": "blog",
  "accent": "#6A3CC7",
  "font": "Anuphan",
  "density": "regular",
  "dark": false,
  "showTags": true,
  "mono": false
}/*EDITMODE-END*/;

const ACCENTS = ["#6A3CC7", "#7A5AE0", "#15835B", "#2C7BD6", "#E0563B"];
const FONTS = ["Anuphan", "IBM Plex Sans Thai", "Sarabun"];

// ---------- helpers ----------
function fmtDate(iso) {
  const d = new Date(iso + "T00:00:00");
  const m = ["ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค."];
  return `${d.getDate()} ${m[d.getMonth()]} ${(d.getFullYear() + 543) % 100}`;
}
function fmtViews(n) { return n >= 1000 ? (n / 1000).toFixed(1).replace(/\.0$/, "") + "k" : "" + n; }
function hexLum(hex) { const m = hex.replace("#", ""); const r = parseInt(m.slice(0, 2), 16) / 255, g = parseInt(m.slice(2, 4), 16) / 255, b = parseInt(m.slice(4, 6), 16) / 255; const f = c => c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4); return 0.2126 * f(r) + 0.7152 * f(g) + 0.0722 * f(b); }

// Each card opens its own Ko-fi post when a link is set; otherwise the profile page.
function postUrl(post) { return (post && post.link) ? post.link : MT_PROFILE.kofiUrl; }

// ---------- small UI atoms ----------
function Icon({ name, size = 18 }) {
  const p = {
    search: "M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16Zm10 2-4.35-4.35",
    lock: "M7 11V8a5 5 0 0 1 10 0v3M5 11h14v10H5z",
    heart: "M12 21s-7.5-4.6-10-9.5C.5 8 2 4.5 5.5 4.5c2 0 3.3 1.2 4 2.3.7-1.1 2-2.3 4-2.3C17 4.5 18.5 8 17 11.5 14.5 16.4 12 21 12 21Z",
    star: "M12 3l2.6 5.6 6.1.8-4.5 4.2 1.2 6.1L12 17l-5.4 2.7 1.2-6.1L3.3 9.4l6.1-.8L12 3Z",
    sort: "M3 6h12M3 12h8M3 18h5M17 8v10m0 0 3-3m-3 3-3-3",
    arrow: "M5 12h14m-6-6 6 6-6 6",
    grid: "M4 4h7v7H4zM13 4h7v7h-7zM4 13h7v7H4zM13 13h7v7h-7z",
    x: "M6 6l12 12M18 6 6 18",
  }[name];
  return <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round">{p.split("M").filter(Boolean).map((seg, i) => <path key={i} d={"M" + seg} />)}</svg>;
}

function CatBadge({ category }) {
  const member = category === "member";
  return <span className={"badge " + (member ? "badge-member" : "badge-free")}>
    {member ? <Icon name="lock" size={12} /> : null}
    {member ? "เลี้ยงข้าว MT" : "ฟรี"}
  </span>;
}

// ---------- card cover ----------
function Cover({ post, locked }) {
  return (
    <div className={"cover" + (locked ? " cover-locked" : "")}>
      {post.cover ? <img src={post.cover} alt="" loading="lazy" /> : <Thumb thumb={post.thumb} seed={post.id} />}
      {locked ? (
        <div className="lock-overlay">
          <div className="lock-pill"><Icon name="lock" size={14} /> สมาชิกเท่านั้น</div>
        </div>
      ) : null}
    </div>
  );
}

function TagRow({ tags, onTag, active }) {
  return <div className="tagrow">{tags.map(t => (
    <button key={t} className={"tag" + (active && active.has(t) ? " tag-on" : "")} onClick={(e) => { e.preventDefault(); e.stopPropagation(); onTag && onTag(t); }}>#{t}</button>
  ))}</div>;
}

// ---------- GALLERY direction ----------
function GalleryCard({ post, t, onTag, activeTags }) {
  const locked = post.category === "member";
  return (
    <a className="g-card" href={postUrl(post)} target="_blank" rel="noopener">
      <Cover post={post} locked={locked} />
      <div className="g-body">
        <div className="g-meta">
          <CatBadge category={post.category} />
          <span className="type">{post.type}</span>
        </div>
        <h3 className="card-title">{post.title}</h3>
        <div className="g-foot">
          <span className="muted small">{fmtDate(post.date)}</span>
          <span className="muted small views"><Icon name="heart" size={13} />{fmtViews(post.views)}</span>
        </div>
        {t.showTags ? <TagRow tags={post.tags} onTag={onTag} active={activeTags} /> : null}
      </div>
    </a>
  );
}

// ---------- EDITORIAL direction ----------
function FeatureCard({ post, t, onTag, activeTags }) {
  const locked = post.category === "member";
  return (
    <a className="feat" href={postUrl(post)} target="_blank" rel="noopener">
      <div className="feat-cover"><Cover post={post} locked={locked} /></div>
      <div className="feat-body">
        <div className="g-meta"><CatBadge category={post.category} /><span className="type">{post.type}</span></div>
        <h2 className="feat-title">{post.title}</h2>
        <p className="feat-sub muted">บทวิเคราะห์ล่าสุดจาก MT — แตะเพื่ออ่านฉบับเต็มบน Ko-fi</p>
        <div className="g-foot"><span className="muted small">{fmtDate(post.date)}</span><span className="muted small views"><Icon name="heart" size={13} />{fmtViews(post.views)}</span></div>
        {t.showTags ? <TagRow tags={post.tags} onTag={onTag} active={activeTags} /> : null}
      </div>
    </a>
  );
}
function EditorialCard({ post, t, onTag, activeTags }) {
  const locked = post.category === "member";
  return (
    <a className="e-card" href={postUrl(post)} target="_blank" rel="noopener">
      <div className="e-cover"><Cover post={post} locked={locked} /></div>
      <div className="e-body">
        <div className="g-meta"><CatBadge category={post.category} /><span className="type">{post.type}</span></div>
        <h3 className="card-title">{post.title}</h3>
        <div className="g-foot"><span className="muted small">{fmtDate(post.date)}</span><span className="muted small views"><Icon name="heart" size={13} />{fmtViews(post.views)}</span></div>
      </div>
    </a>
  );
}

// ---------- NEWSROOM direction (Apple Newsroom style) ----------
function NewsroomCard({ post, variant }) {
  const locked = post.category === "member";
  const member = post.category === "member";
  return (
    <a className={"n-card n-" + variant} href={postUrl(post)} target="_blank" rel="noopener">
      <div className="n-cover"><Cover post={post} locked={locked} /></div>
      <div className="n-body">
        <span className={"n-eyebrow" + (member ? " n-eyebrow-m" : "")}>{member ? <Icon name="lock" size={12} /> : null}{post.type}{member ? " · เลี้ยงข้าว MT" : ""}</span>
        <h3 className="n-title">{post.title}</h3>
        <span className="n-date">{fmtDate(post.date)} · <span className="views"><Icon name="heart" size={12} />{fmtViews(post.views)}</span></span>
      </div>
    </a>
  );
}
function NewsroomLayout({ posts }) {
  const hero = posts[0];
  const secondary = posts.slice(1, 3);
  const rest = posts.slice(3);
  return (
    <div className="newsroom-wrap">
      <NewsroomCard post={hero} variant="hero" />
      {secondary.length ? <div className="n-secondary">{secondary.map(p => <NewsroomCard key={p.id} post={p} variant="mid" />)}</div> : null}
      {rest.length ? <React.Fragment><h2 className="n-section">ข่าวล่าสุด</h2><div className="n-grid">{rest.map(p => <NewsroomCard key={p.id} post={p} variant="grid" />)}</div></React.Fragment> : null}
    </div>
  );
}

// ---------- BLOG (Blogger style) direction ----------
const BLOG_EXCERPTS = {
  "สรุปตลาด": "สรุปภาพรวมการเคลื่อนไหวของดัชนีและปัจจัยที่มีผลต่อตลาดในวันนี้ พร้อมแนวรับแนวต้านที่ต้องจับตา",
  "วิเคราะห์หุ้น": "เจาะลึกพื้นฐานและปัจจัยทางเทคนิค ประเมินมูลค่าและโอกาสการลงทุน พร้อมระดับราคาที่น่าสนใจ",
  "Weekly Plan": "วางแผนการลงทุนสำหรับสัปดาห์นี้ คัดหุ้นเด่น จุดเข้า–ออก และการบริหารพอร์ตให้รับมือกับความผันผวน",
  "การเงิน": "ความรู้และแนวคิดด้านการเงินการลงทุน อ่านง่าย นำไปปรับใช้กับพอร์ตของคุณได้จริง",
};
function excerptOf(post) { return BLOG_EXCERPTS[post.type] || "อ่านบทวิเคราะห์ฉบับเต็มได้บน Ko-fi"; }

function BlogEntry({ post, t, onTag, activeTags, feature }) {
  const locked = post.category === "member";
  return (
    <article className={"b-entry" + (feature ? " b-feature" : "")}>
      <a className="b-cover" href={postUrl(post)} target="_blank" rel="noopener"><Cover post={post} locked={locked} /></a>
      <div className="b-body">
        <div className="b-eyebrow">
          <CatBadge category={post.category} />
          <span className="type">{post.type}</span>
          <span className="b-dot">·</span>
          <span className="muted small">{fmtDate(post.date)}</span>
        </div>
        <a href={postUrl(post)} target="_blank" rel="noopener"><h2 className="b-title">{post.title}</h2></a>
        <p className="b-excerpt">{excerptOf(post)}</p>
        <div className="b-foot">
          {t.showTags ? <TagRow tags={post.tags} onTag={onTag} active={activeTags} /> : <span />}
          <a className="b-readmore" href={postUrl(post)} target="_blank" rel="noopener">อ่านต่อ <Icon name="arrow" size={15} /></a>
        </div>
      </div>
    </article>
  );
}

function BlogSidebar({ allPosts, setCat, setType, onTag, cat }) {
  const popular = allPosts.slice().sort((a, b) => b.views - a.views).slice(0, 4);
  const tagCounts = {};
  allPosts.forEach(p => (p.tags || []).forEach(x => { tagCounts[x] = (tagCounts[x] || 0) + 1; }));
  const tags = Object.entries(tagCounts).sort((a, b) => b[1] - a[1]);
  const freeN = allPosts.filter(p => p.category === "free").length;
  const memN = allPosts.filter(p => p.category === "member").length;
  return (
    <aside className="blog-side">
      <div className="side-card side-about">
        <img className="side-avatar" src="assets/mt-pfp.png" alt="MT Research" />
        <b className="side-name">{MT_PROFILE.name}</b>
        <p className="muted small side-bio">{MT_PROFILE.bio}</p>
        <a className="support-btn side-support" href={MT_PROFILE.kofiUrl} target="_blank" rel="noopener"><Icon name="heart" size={15} /> สนับสนุนบน Ko-fi</a>
      </div>

      <div className="side-card">
        <h4 className="side-h">หมวดหมู่</h4>
        <ul className="side-cats">
          <li><button className={cat === "all" ? "on" : ""} onClick={() => setCat("all")}><span>ทั้งหมด</span><span className="side-count">{allPosts.length}</span></button></li>
          <li><button className={cat === "free" ? "on" : ""} onClick={() => setCat("free")}><span>ฟรี</span><span className="side-count">{freeN}</span></button></li>
          <li><button className={cat === "member" ? "on" : ""} onClick={() => setCat("member")}><span><Icon name="lock" size={12} /> เลี้ยงข้าว MT</span><span className="side-count">{memN}</span></button></li>
        </ul>
      </div>

      <div className="side-card">
        <h4 className="side-h">โพสต์ยอดนิยม</h4>
        <ul className="side-pop">
          {popular.map((p, i) => (
            <li key={p.id}><a href={postUrl(p)} target="_blank" rel="noopener">
              <span className="pop-rank">{i + 1}</span>
              <span className="pop-thumb">{p.cover ? <img src={p.cover} alt="" loading="lazy" /> : <Thumb thumb={p.thumb} seed={p.id} />}{p.category === "member" ? <span className="pop-lock"><Icon name="lock" size={9} /></span> : null}</span>
              <span className="pop-info"><span className="pop-title">{p.title}</span><span className="muted small views"><Icon name="heart" size={11} />{fmtViews(p.views)}</span></span>
            </a></li>
          ))}
        </ul>
      </div>

      <div className="side-card">
        <h4 className="side-h">แท็กยอดนิยม</h4>
        <div className="side-tags">{tags.map(([x, n]) => <button key={x} className="tag" onClick={() => onTag(x)}>#{x} <span className="side-count">{n}</span></button>)}</div>
      </div>
    </aside>
  );
}

function BlogLayout({ posts, allPosts, t, onTag, activeTags, setCat, setType, cat }) {
  return (
    <div className="blog-wrap">
      <div className="blog-main">
        {posts.map((p, i) => <BlogEntry key={p.id} post={p} t={t} onTag={onTag} activeTags={activeTags} feature={i === 0} />)}
      </div>
      <BlogSidebar allPosts={allPosts} setCat={setCat} setType={setType} onTag={onTag} cat={cat} />
    </div>
  );
}

// ---------- INDEX (Notion list) direction ----------
function IndexRow({ post }) {
  const locked = post.category === "member";
  return (
    <a className="i-row" href={postUrl(post)} target="_blank" rel="noopener">
      <div className="i-main">
        <div className="i-thumb">{post.cover ? <img src={post.cover} alt="" loading="lazy" /> : <Thumb thumb={post.thumb} seed={post.id} />}{locked ? <div className="i-lock"><Icon name="lock" size={11} /></div> : null}</div>
        <div className="i-text">
          <h3 className="card-title">{post.title}</h3>
          <div className="i-tags">{post.tags.map(x => <span key={x} className="i-tag">#{x}</span>)}</div>
        </div>
      </div>
      <span className="i-type">{post.type}</span>
      <span className="i-cat"><CatBadge category={post.category} /></span>
      <span className="i-date muted small">{fmtDate(post.date)}</span>
      <span className="i-views muted small"><Icon name="heart" size={13} />{fmtViews(post.views)}</span>
    </a>
  );
}

// ---------- filter bar ----------
function FilterBar({ cat, setCat, type, setType, sort, setSort, count, activeTags, clearTags }) {
  return (
    <div className="filters">
      <div className="filter-row">
        <div className="segmented">
          {MT_CATEGORIES.map(c => <button key={c.id} className={"seg" + (cat === c.id ? " seg-on" : "")} onClick={() => setCat(c.id)}>{c.label}</button>)}
        </div>
        <div className="sort">
          <Icon name="sort" size={15} />
          <select value={sort} onChange={e => setSort(e.target.value)}>
            <option value="new">ใหม่สุด</option>
            <option value="old">เก่าสุด</option>
            <option value="hot">ฮิตสุด</option>
          </select>
        </div>
      </div>
      <div className="filter-row">
        <div className="types">
          <button className={"chip" + (type === null ? " chip-on" : "")} onClick={() => setType(null)}>ทุกประเภท</button>
          {MT_TYPES.map(tp => <button key={tp} className={"chip" + (type === tp ? " chip-on" : "")} onClick={() => setType(type === tp ? null : tp)}>{tp}</button>)}
        </div>
        <div className="result-count">
          {activeTags.size > 0 ? <button className="clear-tags" onClick={clearTags}>ล้าง tag ({activeTags.size}) <Icon name="x" size={12} /></button> : null}
          <span className="muted small">{count} บทความ</span>
        </div>
      </div>
    </div>
  );
}

// ---------- header / hero ----------
function SiteHeader({ q, setQ }) {
  return (
    <header className="navbar">
      <div className="nav-inner">
        <a className="brand" href={MT_PROFILE.kofiUrl} target="_blank" rel="noopener">
          <img className="brand-mark" src="assets/mt-pfp.png" alt="MT Research" />
          <span className="brand-text"><b>{MT_PROFILE.name}</b><span className="muted small">รวมบทวิเคราะห์จาก Ko-fi</span></span>
        </a>
        <div className="nav-actions">
          <div className="search">
            <Icon name="search" size={17} />
            <input value={q} onChange={e => setQ(e.target.value)} placeholder="ค้นหา… เช่น ทองคำ, SET, Fed" />
            {q ? <button className="search-x" onClick={() => setQ("")}><Icon name="x" size={15} /></button> : null}
          </div>
          <a className="support-btn" href={MT_PROFILE.kofiUrl} target="_blank" rel="noopener"><Icon name="heart" size={15} /> <span className="support-label">สนับสนุน</span></a>
        </div>
      </div>
    </header>
  );
}
function BrandBanner() {
  return (
    <a className="brand-banner" href={MT_PROFILE.kofiUrl} target="_blank" rel="noopener">
      <img src="assets/mt-banner.jpg" alt="ลงทุนหุ้นนอก by MT Research" />
    </a>
  );
}

function MemberCTA() {
  return (
    <a className="member-cta" href={MT_PROFILE.kofiUrl} target="_blank" rel="noopener">
      <div className="cta-icon"><Icon name="star" size={22} /></div>
      <div className="cta-text">
        <b>เลี้ยงข้าว MT เพื่อปลดล็อกทุกบทวิเคราะห์</b>
        <span className="muted small">Weekly Plan, เจาะหุ้นรายตัว และพอร์ตจำลอง — อ่านได้ไม่จำกัดสำหรับสมาชิก</span>
      </div>
      <span className="cta-go">เป็นสมาชิก <Icon name="arrow" size={16} /></span>
    </a>
  );
}

// ---------- app ----------
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [posts, setPosts] = useState(null); // null = loading
  const [loadErr, setLoadErr] = useState(null);
  const [q, setQ] = useState("");
  const [cat, setCat] = useState("all");
  const [type, setType] = useState(null);
  const [sort, setSort] = useState("new");
  const [tags, setTags] = useState(new Set());

  useEffect(() => {
    // Before Firebase is configured, fall back to the bundled sample posts so the
    // layouts and Tweaks are previewable locally. Once configured, read live from Firestore.
    if (!MTStore.isConfigured()) { setPosts(window.MT_POSTS || []); return; }
    return MTStore.subscribePublished(setPosts, err => { setPosts([]); setLoadErr(err.code || err.message); });
  }, []);

  function toggleTag(tag) { setTags(prev => { const n = new Set(prev); n.has(tag) ? n.delete(tag) : n.add(tag); return n; }); }

  const allPosts = posts || [];
  const filtered = useMemo(() => {
    let list = allPosts.filter(p => {
      if (cat !== "all" && p.category !== cat) return false;
      if (type && p.type !== type) return false;
      if (tags.size && !(p.tags || []).some(x => tags.has(x))) return false;
      if (q.trim()) { const s = (p.title + " " + (p.tags || []).join(" ") + " " + p.type).toLowerCase(); if (!s.includes(q.trim().toLowerCase())) return false; }
      return true;
    });
    list = list.slice().sort((a, b) => sort === "hot" ? b.views - a.views : sort === "old" ? a.date.localeCompare(b.date) : b.date.localeCompare(a.date));
    return list;
  }, [posts, q, cat, type, sort, tags]);

  const dir = t.direction;
  const accent = t.dark && hexLum(t.accent) < 0.2 ? "#F2F2F2" : t.accent;
  const rootStyle = {
    "--accent": accent,
    "--font": `'${t.font}', sans-serif`,
    "--gap": t.density === "compact" ? "14px" : t.density === "comfy" ? "26px" : "20px",
    "--cardmin": t.density === "compact" ? "210px" : t.density === "comfy" ? "280px" : "246px",
  };

  return (
    <div className={"root dir-" + dir + (t.dark ? " dark" : "") + (t.mono ? " mono-thumb" : "")} style={rootStyle}>
      <SiteHeader q={q} setQ={setQ} />
      <div className="page">
        {!MTStore.isConfigured() ? (
          <div className="preview-note"><Icon name="star" size={15} /><span>โหมดพรีวิว — กำลังแสดง<b>ข้อมูลตัวอย่าง</b> เพราะยังไม่ได้เชื่อมต่อ Firebase · ดูวิธีตั้งค่าใน <b>README-firebase.md</b></span></div>
        ) : null}
        <BrandBanner />
        <MemberCTA />
        <FilterBar cat={cat} setCat={setCat} type={type} setType={setType} sort={sort} setSort={setSort} count={filtered.length} activeTags={tags} clearTags={() => setTags(new Set())} />

        {posts === null ? (
          <div className="empty"><Icon name="grid" size={28} /><p>กำลังโหลดบทความ…</p></div>
        ) : allPosts.length === 0 ? (
          <div className="empty"><Icon name="grid" size={28} /><p>ยังไม่มีบทความที่เผยแพร่{loadErr ? " · " + loadErr : ""}</p></div>
        ) : filtered.length === 0 ? (
          <div className="empty"><Icon name="search" size={28} /><p>ไม่พบบทวิเคราะห์ที่ตรงกับเงื่อนไข</p><button onClick={() => { setQ(""); setCat("all"); setType(null); setTags(new Set()); }}>ล้างตัวกรอง</button></div>
        ) : dir === "editorial" ? (
          <div className="editorial-wrap">
            <FeatureCard post={filtered[0]} t={t} onTag={toggleTag} activeTags={tags} />
            <div className="e-grid">{filtered.slice(1).map(p => <EditorialCard key={p.id} post={p} t={t} onTag={toggleTag} activeTags={tags} />)}</div>
          </div>
        ) : dir === "newsroom" ? (
          <NewsroomLayout posts={filtered} />
        ) : dir === "blog" ? (
          <BlogLayout posts={filtered} allPosts={allPosts} t={t} onTag={toggleTag} activeTags={tags} setCat={setCat} setType={setType} cat={cat} />
        ) : dir === "index" ? (
          <div className="index-wrap">
            <div className="i-head"><span>ชื่อบทวิเคราะห์</span><span>ประเภท</span><span>หมวด</span><span>วันที่</span><span>ฮิต</span></div>
            {filtered.map(p => <IndexRow key={p.id} post={p} />)}
          </div>
        ) : (
          <div className="g-grid">{filtered.map(p => <GalleryCard key={p.id} post={p} t={t} onTag={toggleTag} activeTags={tags} />)}</div>
        )}

        <footer className="foot">
          <span className="muted small">MT Research · รวมคอนเทนต์จาก Ko-fi · ภาพและชื่อเป็นตัวอย่าง (placeholder)</span>
          <a className="support-btn small-btn" href={MT_PROFILE.kofiUrl} target="_blank" rel="noopener"><Icon name="heart" size={14} /> สนับสนุน</a>
        </footer>
      </div>

      <TweaksPanel>
        <TweakSection label="แนวดีไซน์" />
        <TweakSelect label="เลย์เอาต์" value={t.direction} options={["blog", "newsroom", "gallery", "editorial", "index"]} onChange={v => setTweak("direction", v)} />
        <TweakSection label="สไตล์" />
        <TweakColor label="สีหลัก" value={t.accent} options={ACCENTS} onChange={v => setTweak("accent", v)} />
        <TweakSelect label="ฟอนต์" value={t.font} options={FONTS} onChange={v => setTweak("font", v)} />
        <TweakRadio label="ความหนาแน่น" value={t.density} options={["compact", "regular", "comfy"]} onChange={v => setTweak("density", v)} />
        <TweakToggle label="โหมดมืด" value={t.dark} onChange={v => setTweak("dark", v)} />
        <TweakToggle label="แสดง tag บนการ์ด" value={t.showTags} onChange={v => setTweak("showTags", v)} />
        <TweakToggle label="Thumbnail ขาวดำ" value={t.mono} onChange={v => setTweak("mono", v)} />
      </TweaksPanel>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
