// ---- Shared small components ----

const Tag = ({ pillar, children }) => (
  <span className={`tag ${pillar}`}>{children}</span>
);

// stable color hash per instructor name
const nameHash = (s) => {
  let h = 0;
  for (let i=0;i<s.length;i++) h = (h*31 + s.charCodeAt(i)) >>> 0;
  return h % 10;
};
const initial = (name) => {
  // strip role prefix "ผจก.", "ผจก", "ผอ.", "ผอ" etc, take first char of given-name
  const stripped = name.replace(/^(ผจก\.?|ผอ\.?|คุณ|พี่)\s*/, "").trim();
  return stripped.charAt(0);
};
const roleOf = (name) => {
  if (/^ผอ\.?\s*/.test(name)) return "ผู้อำนวยการ";
  if (/^ผจก\.?\s*/.test(name)) return "ผู้จัดการ";
  return "ทีมผู้สอน";
};

// Map normalized names → photo file. Keys are without "ผจก./ผอ./พี่" prefix.
const PHOTO_MAP = {
  "เอ๊ะ": "photos/eh.png",
  "เจต": "photos/toi.png",
  "ต้อย": "photos/toy.png",
  "กระติ๊ก": "photos/kratik.png",
  "กระติก": "photos/kratik.png", // alt spelling
  "บอย": "photos/boy.jpg",
  "อ๋อย": "photos/oy.png",
  "กุ๊ก": "photos/kook.png",
  "นุช": "photos/nuch.png",
  "ธัช": "photos/thach.png",
  "เพ็ชร": "photos/kanpetch.png",
  "พันเอก": "photos/panek.png",
  "แอม": "photos/am.jpg",
  "กุ๊กกิ๊ก": "photos/kookkik.jpg",
  "ลักกี้": "photos/lucky.png",
  "ชัย": "photos/chai.png",
  "แคท": "photos/cat.png",
};
const normName = (name) => name.replace(/^(ผจก\.?|ผอ\.?|คุณ)\s*/, "").replace(/^พี่\s*/, "").trim();
const photoOf = (name) => PHOTO_MAP[normName(name)] || null;

const MEMBERSHIP_DAYS = 90;
const PAYMENT_SLIP_FOLDER = "payment-slips";
const DAY_MS = 24 * 60 * 60 * 1000;
const membershipExpiresAt = (createdAt) => {
  const registeredAt = new Date(createdAt);
  if (!createdAt || Number.isNaN(registeredAt.getTime())) return null;
  return new Date(registeredAt.getTime() + MEMBERSHIP_DAYS * DAY_MS);
};
const membershipEndDate = (createdAt) => {
  const expiresAt = membershipExpiresAt(createdAt);
  return expiresAt ? expiresAt.toISOString().slice(0, 10) : null;
};
const membershipExpired = (createdAt, now = Date.now()) => {
  const expiresAt = membershipExpiresAt(createdAt);
  return !!expiresAt && now >= expiresAt.getTime();
};
const paymentSlipPath = (agentId) => `${PAYMENT_SLIP_FOLDER}/${agentId}`;
const paymentSlipSrc = (agentId, bust = "") =>
  `${window.SUPABASE_URL}/storage/v1/object/public/avatars/${paymentSlipPath(agentId)}${bust ? `?bust=${bust}` : ""}`;

const Avatar = ({ name, size }) => {
  const photo = photoOf(name);
  return (
    <span className="avatar">
      {photo
        ? <span className={`avatar-circle ${size||""} has-photo`} style={{backgroundImage:`url("${photo}")`}}></span>
        : <span className={`avatar-circle ${size||""} avatar-c${nameHash(name)}`}>{initial(name)}</span>}
      <span className="avatar-name">{name}</span>
    </span>
  );
};

const Eyebrow = ({ children }) => <p className="eyebrow">{children}</p>;

const SectionHead = ({ eyebrow, title, sub, right }) => (
  <header className="section-head">
    <div>
      {eyebrow && <Eyebrow>{eyebrow}</Eyebrow>}
      <h2 className="section-title">{title}</h2>
      {sub && <p className="section-sub">{sub}</p>}
    </div>
    {right}
  </header>
);

const Legend = () => (
  <div className="legend">
    {PILLARS.map(p => (
      <span key={p.key} className="lg">
        <span className="sw" style={{background: `var(--${p.cls})`}}></span>
        <span>{p.key} · {p.th}</span>
      </span>
    ))}
  </div>
);

const KpiCard = ({ label, value, suffix, sub, feature, progress }) => (
  <div className={`kpi ${feature ? "feature" : ""}`}>
    <div className="kpi-label">{label}</div>
    <div className="kpi-value">
      {value}
      {suffix && <em>{suffix}</em>}
    </div>
    <div className="kpi-sub">{sub}</div>
    <div className="kpi-bar"><div className="kpi-bar-fill" style={{width: `${progress ?? 8}%`}}></div></div>
  </div>
);

const HeroDiagram = () => {
  // 4-quadrant RTMS circular diagram
  const center = 230;
  const r = 180;
  const ringR = 130;
  return (
    <svg viewBox="0 0 460 460" aria-hidden="true">
      <defs>
        <radialGradient id="paper" cx="50%" cy="50%" r="60%">
          <stop offset="0%" stopColor="#FBF7EE" />
          <stop offset="100%" stopColor="#F0E9D8" />
        </radialGradient>
      </defs>
      {/* outer faint ring */}
      <circle cx={center} cy={center} r={r+20} fill="none" stroke="#E4DFD3" strokeDasharray="2 6" />
      <circle cx={center} cy={center} r={r} fill="url(#paper)" stroke="#D9B976" strokeWidth="1" />
      {/* quadrant dividers */}
      <line x1={center-r} y1={center} x2={center+r} y2={center} stroke="#E4DFD3" />
      <line x1={center} y1={center-r} x2={center} y2={center+r} stroke="#E4DFD3" />
      {/* quadrant labels */}
      {[
        {k:"R", x:center-90, y:center-90, color:"#C2552B", th:"สรรหา"},
        {k:"T", x:center+90, y:center-90, color:"#2F6A5A", th:"พัฒนา"},
        {k:"S", x:center-90, y:center+90, color:"#3B5B8C", th:"ติดตาม"},
        {k:"M", x:center+90, y:center+90, color:"#B68A3E", th:"จูงใจ"},
      ].map(q => (
        <g key={q.k}>
          <text x={q.x} y={q.y-4} textAnchor="middle" fontFamily="DM Serif Display" fontStyle="italic" fontSize="56" fill={q.color} opacity="0.9">{q.k}</text>
          <text x={q.x} y={q.y+24} textAnchor="middle" fontFamily="Prompt" fontSize="13" fill="#3B4862" letterSpacing="2">{q.th}</text>
        </g>
      ))}
      {/* center medallion */}
      <circle cx={center} cy={center} r="58" fill="#0F1A2E" />
      <text x={center} y={center-4} textAnchor="middle" fontFamily="DM Serif Display" fontSize="34" fill="#D9B976" fontStyle="italic">83G</text>
      <text x={center} y={center+18} textAnchor="middle" fontFamily="Prompt" fontSize="10" letterSpacing="3" fill="#94896C">2026</text>
    </svg>
  );
};

const LAUNCH_AT = new Date("2026-06-01T00:00:00+07:00").getTime();

const Countdown = () => {
  const [now, setNow] = React.useState(() => Date.now());
  React.useEffect(() => {
    const id = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(id);
  }, []);

  const diff = LAUNCH_AT - now;
  if (diff <= 0) {
    return (
      <div className="countdown countdown-live">
        <div className="countdown-label">เปิดตัวแล้ว</div>
        <div className="countdown-title">แอปพลิเคชัน 83G ใช้งานได้แล้ววันนี้</div>
      </div>
    );
  }

  const days  = Math.floor(diff / 86400000);
  const hours = Math.floor((diff % 86400000) / 3600000);
  const mins  = Math.floor((diff % 3600000) / 60000);
  const secs  = Math.floor((diff % 60000) / 1000);
  const pad = (n) => String(n).padStart(2, "0");

  return (
    <div className="countdown" role="timer" aria-label="นับถอยหลังถึงวันเปิดตัวแอปพลิเคชัน">
      <div className="countdown-label">เปิดตัวแอปพลิเคชัน · 1 มิถุนายน 2026</div>
      <div className="countdown-grid">
        <div className="countdown-unit"><span className="countdown-num">{days}</span><span className="countdown-tag">วัน</span></div>
        <div className="countdown-sep">:</div>
        <div className="countdown-unit"><span className="countdown-num">{pad(hours)}</span><span className="countdown-tag">ชั่วโมง</span></div>
        <div className="countdown-sep">:</div>
        <div className="countdown-unit"><span className="countdown-num">{pad(mins)}</span><span className="countdown-tag">นาที</span></div>
        <div className="countdown-sep">:</div>
        <div className="countdown-unit"><span className="countdown-num">{pad(secs)}</span><span className="countdown-tag">วินาที</span></div>
      </div>
    </div>
  );
};

Object.assign(window, { Tag, Eyebrow, SectionHead, Legend, KpiCard, HeroDiagram, Avatar, Countdown, nameHash, initial, roleOf, photoOf, normName });
