(function() {
  const { useState, useEffect } = React;

  // 77 จังหวัด (ชื่อทางการ — ตรงกับที่ระบบเก็บใน field จังหวัด) จัดกลุ่มตามภาค · ใช้ในตัวแก้แมพความเสี่ยงทำเล
  const PROVINCES_BY_REGION = {
    'ภาคกลาง': ['กรุงเทพมหานคร','กำแพงเพชร','ชัยนาท','นครนายก','นครปฐม','นครสวรรค์','นนทบุรี','ปทุมธานี','พระนครศรีอยุธยา','พิจิตร','พิษณุโลก','เพชรบูรณ์','ลพบุรี','สมุทรปราการ','สมุทรสงคราม','สมุทรสาคร','สิงห์บุรี','สุโขทัย','สุพรรณบุรี','สระบุรี','อ่างทอง','อุทัยธานี'],
    'ภาคเหนือ': ['เชียงราย','เชียงใหม่','น่าน','พะเยา','แพร่','แม่ฮ่องสอน','ลำปาง','ลำพูน','อุตรดิตถ์'],
    'ภาคตะวันออกเฉียงเหนือ': ['กาฬสินธุ์','ขอนแก่น','ชัยภูมิ','นครพนม','นครราชสีมา','บึงกาฬ','บุรีรัมย์','มหาสารคาม','มุกดาหาร','ยโสธร','ร้อยเอ็ด','เลย','ศรีสะเกษ','สกลนคร','สุรินทร์','หนองคาย','หนองบัวลำภู','อุดรธานี','อุบลราชธานี','อำนาจเจริญ'],
    'ภาคตะวันออก': ['จันทบุรี','ฉะเชิงเทรา','ชลบุรี','ตราด','ปราจีนบุรี','ระยอง','สระแก้ว'],
    'ภาคตะวันตก': ['กาญจนบุรี','ตาก','ประจวบคีรีขันธ์','เพชรบุรี','ราชบุรี'],
    'ภาคใต้': ['กระบี่','ชุมพร','ตรัง','นครศรีธรรมราช','นราธิวาส','ปัตตานี','พังงา','พัทลุง','ภูเก็ต','ยะลา','ระนอง','สงขลา','สตูล','สุราษฎร์ธานี'],
  };
  const ALL_PROVINCES = Object.values(PROVINCES_BY_REGION).reduce((a, b) => a.concat(b), []);
  const LV_TH = { low: 'ต่ำ', medium: 'กลาง', high: 'สูง' };

  // ตัวแก้แมพความเสี่ยงทำเล: โชว์จังหวัด low/medium (high = ที่เหลือ) + ให้แอดมินย้ายระดับ + บันทึกลง site_settings
  function LocationRiskEditor() {
    const [low, setLow] = useState(null);   // null = กำลังโหลด
    const [medium, setMedium] = useState([]);
    const [sel, setSel] = useState('');
    const [saving, setSaving] = useState(false);
    const [msg, setMsg] = useState('');
    const [dirty, setDirty] = useState(false);

    function loadMap() {
      window.api.riskConfig().then(d => {
        const lv = (d && d.location_risk_map && d.location_risk_map.levels) || {};
        setLow(Array.isArray(lv.low) ? lv.low.slice() : []);
        setMedium(Array.isArray(lv.medium) ? lv.medium.filter(p => p !== 'หัวหิน') : []);
        setDirty(false); setMsg('');
      }).catch(() => { setLow([]); setMedium([]); });
    }
    useEffect(loadMap, []);

    if (low === null) return <div className="card" style={{padding:20,color:'#6B7280'}}>กำลังโหลดแมพจังหวัด...</div>;

    const levelOf = (p) => low.includes(p) ? 'low' : (medium.includes(p) ? 'medium' : 'high');
    function assign(p, level) {
      if (!p) return;
      setLow(prev => level === 'low' ? Array.from(new Set(prev.concat(p))) : prev.filter(x => x !== p));
      setMedium(prev => level === 'medium' ? Array.from(new Set(prev.concat(p))) : prev.filter(x => x !== p));
      setDirty(true); setMsg('');
    }
    async function save() {
      setSaving(true); setMsg('');
      try {
        await window.api.saveLocationRiskMap({ default: 'high', levels: { low, medium } });
        setDirty(false); setMsg('บันทึกแล้ว — มีผลกับการคำนวณเกรดทันที ✓');
      } catch (e) { setMsg('บันทึกไม่สำเร็จ: ' + e.message); }
      setSaving(false);
    }

    const chip = (p, color, bg) => (
      <span key={p} style={{display:'inline-flex',alignItems:'center',gap:4,background:bg,color:color,border:'1px solid '+color+'44',borderRadius:99,padding:'4px 4px 4px 12px',fontSize:12.5,fontWeight:600}}>
        {p}
        <button onClick={() => assign(p, 'high')} title="เอาออก (→ สูง)" style={{border:'none',background:'transparent',color:color,cursor:'pointer',fontSize:13,lineHeight:1,padding:'2px 4px',borderRadius:99}}><i className="ph ph-x"></i></button>
      </span>
    );
    const setBtn = (level, label, c) => (
      <button disabled={!sel} onClick={() => assign(sel, level)}
        style={{padding:'8px 12px',borderRadius:8,border:'1px solid '+c,background: sel?'#fff':'#F3F4F6',color: sel?c:'#9CA3AF',fontWeight:700,fontSize:12.5,cursor: sel?'pointer':'default',fontFamily:'inherit'}}>{label}</button>
    );

    return (
      <div className="card" style={{padding:16,marginTop:14}}>
        <div style={{marginBottom:14}}>
          <div style={{fontSize:13,fontWeight:700,marginBottom:8,color:'#15976A'}}>🟢 low — คะแนน 1 ({low.length} จังหวัด)</div>
          <div style={{display:'flex',flexWrap:'wrap',gap:8}}>
            {low.length ? low.map(p => chip(p, '#15976A', '#E9F7F0')) : <span style={{fontSize:12.5,color:'#9CA3AF'}}>— ไม่มี —</span>}
          </div>
        </div>
        <div style={{marginBottom:14}}>
          <div style={{fontSize:13,fontWeight:700,marginBottom:8,color:'#B5860B'}}>🟡 medium — คะแนน 2 ({medium.length} จังหวัด)</div>
          <div style={{display:'flex',flexWrap:'wrap',gap:8}}>
            {medium.length ? medium.map(p => chip(p, '#B5860B', '#FBF3E0')) : <span style={{fontSize:12.5,color:'#9CA3AF'}}>— ไม่มี —</span>}
          </div>
        </div>
        <div style={{fontSize:12.5,color:'#6B7280',marginBottom:16,paddingBottom:14,borderBottom:'1px solid var(--border,#E8ECF3)'}}>
          🔴 high — คะแนน 3: จังหวัดที่เหลือทั้งหมด ({Math.max(0, ALL_PROVINCES.length - low.length - medium.length)} จังหวัด) เป็นค่า default อัตโนมัติ
        </div>
        <div style={{display:'flex',flexWrap:'wrap',gap:8,alignItems:'center'}}>
          <span style={{fontSize:13,fontWeight:600}}>ตั้งระดับจังหวัด:</span>
          <select value={sel} onChange={e => setSel(e.target.value)} style={{padding:'8px 10px',borderRadius:8,border:'1px solid #D8DEE9',fontSize:13,fontFamily:'inherit',minWidth:200}}>
            <option value="">— เลือกจังหวัด —</option>
            {Object.entries(PROVINCES_BY_REGION).map(([region, provs]) => (
              <optgroup key={region} label={region}>
                {provs.map(p => <option key={p} value={p}>{p + ' (' + LV_TH[levelOf(p)] + ')'}</option>)}
              </optgroup>
            ))}
          </select>
          {setBtn('low', '→ ต่ำ (1)', '#15976A')}
          {setBtn('medium', '→ กลาง (2)', '#B5860B')}
          {setBtn('high', '→ สูง (3)', '#D8567A')}
        </div>
        <div style={{display:'flex',alignItems:'center',gap:12,marginTop:16,paddingTop:14,borderTop:'1px solid var(--border,#E8ECF3)'}}>
          <button onClick={save} disabled={saving || !dirty}
            style={{padding:'9px 20px',borderRadius:9,border:'none',background: (dirty && !saving)?'#2A6BE0':'#C7D2E0',color:'#fff',fontWeight:700,fontSize:14,cursor:(dirty && !saving)?'pointer':'default',fontFamily:'inherit'}}>{saving?'กำลังบันทึก...':'บันทึกแมพ'}</button>
          <button onClick={loadMap} disabled={saving}
            style={{padding:'9px 16px',borderRadius:9,border:'1px solid #D8DEE9',background:'#fff',fontSize:13,cursor:saving?'default':'pointer',fontFamily:'inherit'}}>รีเซ็ต</button>
          {msg && <span style={{fontSize:13,fontWeight:600,color: msg.indexOf('ไม่สำเร็จ')>=0?'#D8567A':'#15976A'}}>{msg}</span>}
          {dirty && !msg && <span style={{fontSize:12.5,color:'#B5860B'}}><i className="ph ph-warning-circle" style={{marginRight:4}}></i>มีการแก้ไขที่ยังไม่บันทึก</span>}
        </div>
      </div>
    );
  }
  window.LocationRiskEditor = LocationRiskEditor;

  // นำเข้าผังเมืองทั้งประเทศ — เบราว์เซอร์ไล่ยิงทีละจังหวัด (แต่ละ request สั้น ไม่ชน Cloud Run timeout)
  const ZONING_CODES = [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,60,61,62,63,64,65,66,67,70,71,72,73,74,75,76,77,80,81,82,83,84,85,86,90,91,92,93,94,95,96];
  function ZoningImportAll() {
    const [running, setRunning] = useState(false);
    const [i, setI] = useState(0);
    const [sum, setSum] = useState(0);
    const [rows, setRows] = useState([]);
    const stop = React.useRef(false);
    async function run() {
      setRunning(true); stop.current = false; setI(0); setSum(0); setRows([]);
      let total = 0;
      for (let k = 0; k < ZONING_CODES.length; k++) {
        if (stop.current) break;
        const code = ZONING_CODES[k]; setI(k + 1);
        try {
          const r = await window.api.importProvinceBrowser(code);
          const c = (r && r.inserted) || 0; total += c;
          setRows(prev => [{ code, count: c, ok: true }, ...prev]);
        } catch (e) { setRows(prev => [{ code, count: 0, ok: false }, ...prev]); }
        setSum(total);
      }
      setRunning(false);
    }
    const pct = Math.round((i / ZONING_CODES.length) * 100);
    return (
      <div className="card" style={{ padding: 16 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
          <button onClick={running ? () => { stop.current = true; } : run}
            style={{ padding: '9px 18px', borderRadius: 9, border: 'none', background: running ? '#D8567A' : '#2A6BE0', color: '#fff', fontWeight: 700, fontSize: 14, cursor: 'pointer', fontFamily: 'inherit' }}>
            {running ? 'หยุด' : 'นำเข้าทั้งประเทศ (77 จังหวัด)'}</button>
          <span style={{ fontSize: 13, color: '#334155' }}>{(running || i) ? (i + '/' + ZONING_CODES.length + ' จังหวัด · รวม ' + sum.toLocaleString() + ' โซน') : 'ยังไม่เริ่ม'}</span>
        </div>
        {(running || i > 0) &&
          <div style={{ height: 8, background: '#E8ECF3', borderRadius: 99, marginTop: 12, overflow: 'hidden' }}>
            <div style={{ height: '100%', width: pct + '%', background: '#2A6BE0', transition: 'width .2s' }} /></div>}
        <div style={{ fontSize: 11.5, color: '#6B7280', marginTop: 8 }}><i className="ph ph-info" style={{marginRight:4}}></i>ไล่ยิงทีละจังหวัดจากเบราว์เซอร์ · เปิดหน้านี้ค้างไว้จนเสร็จ (อาจหลายสิบนาที) · จังหวัดที่ DPT ล่ม/ไม่มีข้อมูล = 0 (กดใหม่เก็บตกได้)</div>
        {rows.length > 0 &&
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 10, maxHeight: 130, overflowY: 'auto' }}>
            {rows.map((r, idx) => (
              <span key={idx} title={'จังหวัด ' + r.code} style={{ fontSize: 11.5, fontFamily: 'monospace', padding: '2px 8px', borderRadius: 6, background: r.ok ? (r.count ? '#E9F7F0' : '#F3F4F6') : '#FDECEC', color: r.ok ? (r.count ? '#0A7D46' : '#6B7280') : '#C0392B' }}>{r.code}:{r.count}</span>
            ))}
          </div>}
      </div>
    );
  }
  window.ZoningImportAll = ZoningImportAll;

  function InfraPage({ embedded }) {
    const [cfg, setCfg] = useState(null); // สถานะความพร้อมระบบ ดึงสดจาก backend
    useEffect(() => { window.api.systemConfig().then(setCfg).catch(() => setCfg(false)); }, []);

    // Environment Variables ที่ระบบใช้ (ชื่อตัวแปรเท่านั้น — ไม่โชว์ค่า/secret)
    const envGroups = [
      { group: "หลัก / Core", vars: ["DATABASE_URL", "NODE_ENV", "PORT", "FRONTEND_URL", "ALLOWED_ORIGINS"] },
      { group: "ยืนยันตัวตน / Auth", vars: ["FIREBASE_WEB_API_KEY", "STAFF_EMAIL_DOMAIN"] },
      { group: "จัดเก็บไฟล์ + แปลภาษา / GCS", vars: ["GCS_PROJECT_ID", "GCS_CLIENT_EMAIL", "GCS_PRIVATE_KEY", "GCS_BUCKET"] },
      { group: "อีเมล / Email (Gmail API)", vars: ["GMAIL_SENDER", "EMAIL_FROM", "ADMIN_NOTIFY_EMAIL", "EMAIL_SITE_URL", "EMAIL_LOGO_URL", "ADMIN_URL"] },
      { group: "SMS OTP / ThaiBulkSMS", vars: ["THAIBULKSMS_API_KEY", "THAIBULKSMS_API_SECRET", "THAIBULKSMS_SENDER", "THAIBULKSMS_FORCE"] },
    ];

    // ตารางฐานข้อมูลหลัก + หน้าที่
    const dbTables = [
      { t: "users", d: "ผู้ใช้ทั้งหมด (เชื่อม Firebase) + บทบาท/สิทธิ์" },
      { t: "investor_profiles", d: "โปรไฟล์นักลงทุน + สถานะอนุมัติ (KYC)" },
      { t: "listings", d: "ประกาศทรัพย์ทั้งหมด (ขายขาด/ขายฝาก/จำนอง)" },
      { t: "listing_images", d: "รูปภาพทรัพย์" },
      { t: "listing_submissions", d: "ทรัพย์ที่คนภายนอกส่งเข้ามา รออนุมัติ" },
      { t: "listing_documents", d: "เอกสารแนบใบสินเชื่อ (โฉนด/เล่มประเมิน/สเตทเมนท์ · private GCS)" },
      { t: "listing_activities", d: "ไทม์ไลน์ CRM ของแต่ละดีล" },
      { t: "lead_activities", d: "ไทม์ไลน์การติดตามผู้สนใจ (โทร/ส่งลิงก์ KYC)" },
      { t: "investor_events", d: "กิจกรรม/ความสนใจนักลงทุน (รวมลีดเบอร์ที่ยังไม่สมัคร)" },
      { t: "buyer_leads", d: "ผู้สนใจซื้อทรัพย์ขายขาด (เบอร์ยืนยัน OTP)" },
      { t: "matching_leads", d: "คำขอเงินทุนจากเจ้าของทรัพย์ (หน้าโฉนดแลกเงิน)" },
      { t: "inquiries", d: "ข้อความติดต่อสอบถามรายทรัพย์" },
      { t: "brokers", d: "ข้อมูลนายหน้า" },
      { t: "articles", d: "บทความ/ความรู้ (CMS) + สถานะร่าง/เผยแพร่" },
      { t: "consent_logs", d: "บันทึกความยินยอม PDPA (แก้ไขไม่ได้)" },
      { t: "data_subject_requests", d: "คำขอใช้สิทธิเจ้าของข้อมูล (DSR)" },
      { t: "email_logs", d: "บันทึกการส่งอีเมล (sent/failed/skipped)" },
    ];

    // สิ่งที่ค้าง/ต้องทำก่อนขยายระบบ (Pending / Tech debt)
    const pending = [
      { p: "high", t: "หมุนรหัสลับที่เคยหลุด (rotate secrets)", d: "รหัส Cloud SQL / GCS service-account key / Supabase เคยหลุดในแชต — ต้องหมุนใหม่ใน GCP Console (ความเสี่ยงอันดับ 1 ที่เหลือ · โค้ดปิดครบแล้ว)" },
      { p: "high", t: "เนื้อหาหน้า 'เงื่อนไขการใช้งาน' (Terms)", d: "ยังขึ้น [รอผู้เชี่ยวชาญกฎหมายเติม] 7/9 หัวข้อ — ต้องให้ทนายเติมก่อนเปิดตัว (หน้า Privacy/PDPA ครบแล้ว)" },
      { p: "high", t: "อนุมัติ Sender Name กับ ThaiBulkSMS", d: "sender PROPFINN ยังรออนุมัติ (ใช้ CARFINN ส่งได้จริงไปก่อน) · อนุมัติแล้วสลับ env เป็น PROPFINN" },
      { p: "mid", t: "ตั้งค่า ADMIN_NOTIFY_EMAIL บน Cloud Run", d: "ถ้ายังไม่ตั้ง → ทีมงานไม่ได้รับอีเมลแจ้งเตือน (ดูสถานะจริงในการ์ด 'สถานะความพร้อมระบบ' ด้านบน)" },
      { p: "mid", t: "ผูกโดเมนจริง (Phase 2)", d: "Backend/DB ย้ายมา GCP ครบแล้ว (ก.ค. 2026) · เหลือผูกโดเมนจริง + อัปเดต env (EMAIL_SITE_URL/ADMIN_URL/ALLOWED_ORIGINS) · งาน SEO/sitemap ทำพร้อมรอบนี้" },
      { p: "low", t: "OTP เก็บใน memory → max-instances 1", d: "ตั้ง min-instances 1 แล้ว (ตัด cold start) แต่ max ยังเป็น 1 เพราะ OTP อยู่ใน memory · ถ้าทราฟฟิกโตจนต้องสเกล >1 ต้องย้าย OTP ไป DB ก่อน" },
    ];

    // Tech Stack + เวอร์ชันจริง (จาก package.json / index.html)
    const techStack = [
      { cat: "หน้าบ้าน", items: "React 18.3.1 (production build) · Frontend คอมไพล์ JSX ด้วย esbuild ตอน deploy · Admin ใช้ Babel Standalone" },
      { cat: "Backend API", items: "Node.js · Fastify 5.10 · TypeScript 5.4 · Docker · Cloud Run min-instances 1 (ตัด cold start)" },
      { cat: "ฐานข้อมูล", items: "Cloud SQL — PostgreSQL 17 + PostGIS · pg 8.11" },
      { cat: "ยืนยันตัวตน", items: "Firebase Auth (JS SDK 10.12 · REST verify — ไม่ใช้ firebase-admin)" },
      { cat: "จัดเก็บไฟล์", items: "Google Cloud Storage (@google-cloud/storage 7.x) · เอกสารใหญ่ upload ตรงเข้า GCS (signed URL)" },
      { cat: "บริการภายนอก", items: "Gmail API · ThaiBulkSMS v2 · Google Maps · Cloud Translation v2" },
    ];

    // โดเมน / DNS — ปัจจุบัน → แผนโดเมนจริง (Phase 2)
    const dnsRows = [
      { name: "เว็บหน้าบ้าน", cur: "propfinn-web.web.app", host: "Firebase Hosting", plan: "โดเมนจริง (รอผูก Phase 2)" },
      { name: "หลังบ้าน Admin", cur: "propfinn-admin.web.app", host: "Firebase Hosting", plan: "subdomain เช่น admin.xxx" },
      { name: "Backend API", cur: "propfinn-api-2dzrmnwhga-as.a.run.app", host: "Google Cloud Run", plan: "custom domain เช่น api.xxx" },
    ];

    // Roadmap ย้ายสู่ GCP (Phase 1 ปัจจุบัน → Phase 2)
    const roadmap = [
      { part: "Frontend", now: "Firebase Hosting ✓", next: "ย้ายจาก Vercel แล้ว (มิ.ย. 2026)" },
      { part: "Backend", now: "Google Cloud Run ✓", next: "ย้ายแล้ว (มิ.ย. 2026)" },
      { part: "Database", now: "Cloud SQL (PostgreSQL 17 + PostGIS) ✓", next: "ย้ายจาก Supabase แล้ว (ก.ค. 2026)" },
      { part: "Storage", now: "Google Cloud Storage", next: "GCS + CDN (ใช้ต่อได้เลย)" },
      { part: "Auth", now: "Firebase Auth", next: "Firebase Auth (ใช้ต่อได้เลย)" },
    ];

    // เกณฑ์คิดเกรดความเสี่ยงทรัพย์ (ค่า default — จริงอ่านจาก site_settings key='risk_grade_config')
    const riskFactors = [
      { f: "LTV", sub: "วงเงินที่ต้องการ ÷ มูลค่าประเมิน (ไม่มี → ใช้ราคาขาย)", w: 40, c: "≤ 50% → 1  ·  ≤ 70% → 2  ·  > 70% → 3  ·  (ไม่มีค่า → 2)" },
      { f: "ทำเล", sub: "ระดับความเสี่ยงจากจังหวัด (แอดมิน override ได้)", w: 30, c: "low → 1  ·  medium → 2  ·  high → 3  ·  (ไม่อยู่ในแมพ → 3)" },
      { f: "เอกสาร", sub: "จำนวนเอกสารสิทธิ์ที่ยังขาด", w: 20, c: "ขาด 0 → 1  ·  ขาด ≤ 2 → 2  ·  ขาด > 2 → 3" },
      { f: "ระยะเวลา", sub: "อายุสัญญา/ดีล (ปี)", w: 10, c: "≤ 1 ปี → 1  ·  ≤ 3 ปี → 2  ·  > 3 ปี → 3  ·  (ไม่มี → 2)" },
    ];
    const riskGrades = [
      { g: "A", r: "≤ 1.40", c: "#15976A", t: "เสี่ยงต่ำสุด — ปลอดภัย" },
      { g: "B", r: "1.41 – 1.80", c: "#15976A", t: "เสี่ยงต่ำ" },
      { g: "C", r: "1.81 – 2.20", c: "#B5860B", t: "ปานกลาง" },
      { g: "D", r: "2.21 – 2.60", c: "#D97706", t: "ค่อนข้างเสี่ยง" },
      { g: "E", r: "> 2.60", c: "#D8567A", t: "เสี่ยงสูงสุด" },
    ];

    const services = [
      { name: "Firebase Hosting", sub: "Frontend", icon: "ph-fire", color: "#FFCA28", desc: "เว็บหน้าบ้าน (React 18 · static)", url: "propfinn-web.web.app", account: "GitHub: watcharaphong-carfinn", group: "frontend" },
      { name: "Firebase Hosting", sub: "Admin Panel", icon: "ph-fire", color: "#FFCA28", desc: "หลังบ้าน Admin (React 18 · static)", url: "propfinn-admin.web.app", account: "GitHub: watcharaphong-carfinn", group: "frontend" },
      { name: "Cloud Run", sub: "Backend API", icon: "ph-cloud", color: "#4285F4", desc: "Node.js + Fastify 5 + TypeScript (Docker) · asia-southeast1 · min-instances 1 (ตัด cold start) · max 1 (OTP ใน memory)", url: "propfinn-api-2dzrmnwhga-as.a.run.app", account: "Google: watcharaphong.s@carfinn.com", group: "backend" },
      { name: "Cloud SQL", sub: "Database", icon: "ph-database", color: "#4285F4", desc: "PostgreSQL 17 + PostGIS · เชื่อมผ่าน Cloud SQL socket · asia-southeast1", url: "propfinn-marketplace:asia-southeast1:propfinn-db", account: "Google: watcharaphong.s@carfinn.com", group: "data" },
      { name: "Firebase", sub: "Authentication", icon: "ph-fire", color: "#FFCA28", desc: "Google Login / Auth", url: "propfinn-marketplace", account: "watcharaphong.s@carfinn.com", group: "data" },
      { name: "Google Cloud", sub: "Storage", icon: "ph-cloud", color: "#4285F4", desc: "รูปภาพทรัพย์ (public) + เอกสารสิทธิ์/สินเชื่อ (private+signed URL) · เอกสารใหญ่อัปตรงเข้า GCS · bucket: propfinn_storage", url: "propfinn-marketplace", account: "watcharaphong.s@carfinn.com", group: "data" },
      { name: "Google Maps", sub: "Maps & Places", icon: "ph-map-trifold", color: "#34A853", desc: "แผนที่/ปักหมุดทรัพย์ (Maps JS + Places + Embed)", url: "console.cloud.google.com", account: "watcharaphong.s@carfinn.com", group: "data" },
      { name: "Google Translate", sub: "Translation", icon: "ph-globe-hemisphere-west", color: "#4285F4", desc: "แปล EN/ZH อัตโนมัติ (Cloud Translation v2)", url: "translation.googleapis.com", account: "watcharaphong.s@carfinn.com", group: "data" },
      { name: "Gmail API", sub: "Email", icon: "ph-envelope", color: "#EA4335", desc: "อีเมลแจ้งเตือน (Gmail API · Google Workspace · ส่งแทน noreply@carfinn.com)", url: "gmail.googleapis.com", account: "watcharaphong.s@carfinn.com", group: "data" },
      { name: "ThaiBulkSMS", sub: "SMS OTP", icon: "ph-device-mobile", color: "#2D6FF7", desc: "ยืนยันเบอร์ OTP + แจ้ง SMS (ThaiBulkSMS v2 · ต้องตั้ง Sender Name ที่อนุมัติ)", url: "api-v2.thaibulksms.com", account: "Carfinn account", group: "data" },
      { name: "GitHub", sub: "Source Code", icon: "ph-git-branch", color: "#24292E", desc: "Version Control + CI/CD", url: "github.com/watcharaphong-carfinn/Propfinn-Marketplace", account: "watcharaphong-carfinn", group: "ops" },
    ];

    const accounts = [
      { name: "GitHub: watcharaphong-carfinn", services: "Source code + auto-deploy (GitHub Action → Firebase Hosting)", color: "#24292E" },
      { name: "Google: watcharaphong.s@carfinn.com", services: "Firebase Hosting (Frontend+Admin), Cloud Run (Backend API), Cloud SQL (Database), Firebase Auth, Cloud Storage, Google Maps, Cloud Translation, Gmail API — project: propfinn-marketplace", color: "#4285F4" },
    ];

    const body = (
      <>
        {!embedded && <div className="page-header">
          <h1><i className="ph ph-buildings" style={{marginRight:8,color:'#4A6079'}}></i>โครงสร้างระบบ</h1>
          <span className="page-sub">Propfinn Marketplace — สถาปัตยกรรมระบบ</span>
        </div>}

        {/* Config Health — สถานะความพร้อมระบบ (ดึงสดจาก backend) — วางบนสุดเพื่อเห็นปัญหาทันที */}
        <h2 style={{marginTop: 4, marginBottom: 16, fontSize: 18, fontWeight: 700}}><i className="ph ph-heartbeat" style={{marginRight:8,color:'#4A6079'}}></i>สถานะความพร้อมระบบ</h2>
        <div className="card">
          {cfg === null ? <div style={{padding: 20, color: "#6B7280"}}>กำลังโหลด...</div>
          : cfg === false ? <div style={{padding: 20, color: "#D8567A"}}>โหลดสถานะไม่สำเร็จ</div>
          : (() => {
            const e = cfg.email || {}, sm = cfg.sms || {}, st = cfg.storage || {};
            const rows = [
              { ok: cfg.database, label: "ฐานข้อมูล (PostgreSQL)", note: cfg.database ? "เชื่อมต่อพร้อมใช้งาน" : "ยังไม่ตั้ง DATABASE_URL" },
              { ok: cfg.firebase, label: "ยืนยันตัวตน (Firebase Auth)", note: cfg.firebase ? "พร้อมใช้งาน" : "ยังไม่ตั้ง FIREBASE_WEB_API_KEY" },
              { ok: st.ok, label: "จัดเก็บไฟล์ (Google Cloud Storage)", note: st.ok ? ("bucket: " + (st.bucket || "-")) : "ยังไม่ตั้ง GCS_*" },
              { ok: e.gmail_ready, label: "อีเมล (Gmail API)", note: e.gmail_ready ? ("ส่งจาก " + (e.from || "-")) : "ยังไม่ตั้ง Gmail API" },
              { ok: !!e.notify_email, warn: !e.notify_email, label: "อีเมลแจ้งทีมงาน (ADMIN_NOTIFY_EMAIL)", note: e.notify_email ? "ตั้งค่าแล้ว" : "ยังไม่ตั้ง → ทีมไม่ได้รับเมลแจ้งเตือน" },
              { ok: sm.ok && !sm.demo, warn: sm.ok && sm.demo, label: "SMS OTP (ThaiBulkSMS)", note: !sm.ok ? "ยังไม่ตั้ง credentials" : sm.demo ? "โหมด Demo — รออนุมัติ Sender Name" : ("Sender: " + sm.sender) },
              { ok: cfg.translate, label: "แปลภาษาอัตโนมัติ (Cloud Translation)", note: cfg.translate ? "พร้อมใช้งาน" : "ยังไม่ตั้งค่า" },
            ];
            return (<div>
              {rows.map((r, i) => (
                <div key={i} style={{display: "flex", alignItems: "center", gap: 12, padding: "11px 16px", borderTop: i ? "1px solid var(--border,#E8ECF3)" : "none"}}>
                  <span style={{fontSize: 16}}>{r.ok ? <i className="ph ph-check-circle" style={{color:'#15976A'}}></i> : r.warn ? <i className="ph ph-warning-circle" style={{color:'#B5860B'}}></i> : <i className="ph ph-x-circle" style={{color:'#D8567A'}}></i>}</span>
                  <div style={{flex: 1}}>
                    <div style={{fontWeight: 600, fontSize: 13.5}}>{r.label}</div>
                    <div style={{fontSize: 12, color: r.ok ? "#6B7280" : r.warn ? "#9A7400" : "#D8567A"}}>{r.note}</div>
                  </div>
                </div>
              ))}
              {e.last_error && <div style={{padding: "10px 16px", borderTop: "1px solid var(--border,#E8ECF3)", fontSize: 12, color: "#D8567A"}}>อีเมลล่าสุดที่ผิดพลาด: {e.last_error.subject} — {e.last_error.error}</div>}
            </div>);
          })()}
        </div>

        {/* Architecture Diagram */}
        <h2 style={{marginTop: 32, marginBottom: 16, fontSize: 18, fontWeight: 700}}><i className="ph ph-buildings" style={{marginRight:8,color:'#4A6079'}}></i>สถาปัตยกรรมระบบ</h2>
        <div className="infra-diagram card">
          <div className="infra-diagram-inner">
            {/* Users */}
            <div className="infra-row">
              <div className="infra-node infra-user">
                <div className="infra-node-icon"><i className="ph ph-users-three"></i></div>
                <div className="infra-node-name">Users</div>
              </div>
            </div>

            <div className="infra-arrow">▼</div>

            {/* Frontend Layer */}
            <div className="infra-label">Frontend Layer</div>
            <div className="infra-row">
              <div className="infra-node" style={{borderColor: "#FFCA28"}}>
                <div className="infra-node-icon"><i className="ph ph-fire"></i></div>
                <div className="infra-node-name">Firebase Hosting</div>
                <div className="infra-node-sub">Frontend</div>
              </div>
              <div className="infra-node" style={{borderColor: "#FFCA28"}}>
                <div className="infra-node-icon"><i className="ph ph-fire"></i></div>
                <div className="infra-node-name">Firebase Hosting</div>
                <div className="infra-node-sub">Admin Panel</div>
              </div>
            </div>

            <div className="infra-arrow">▼</div>

            {/* Backend Layer */}
            <div className="infra-label">Backend Layer</div>
            <div className="infra-row">
              <div className="infra-node infra-backend" style={{borderColor: "#4285F4"}}>
                <div className="infra-node-icon"><i className="ph ph-cloud"></i></div>
                <div className="infra-node-name">Cloud Run</div>
                <div className="infra-node-sub">Node.js + Fastify</div>
              </div>
            </div>

            <div className="infra-arrow-split">
              <span>▼</span><span>▼</span><span>▼</span>
            </div>

            {/* Data Layer */}
            <div className="infra-label">Data & Services Layer</div>
            <div className="infra-row">
              <div className="infra-node" style={{borderColor: "#4285F4"}}>
                <div className="infra-node-icon"><i className="ph ph-database"></i></div>
                <div className="infra-node-name">Cloud SQL</div>
                <div className="infra-node-sub">PostgreSQL</div>
              </div>
              <div className="infra-node" style={{borderColor: "#FFCA28"}}>
                <div className="infra-node-icon"><i className="ph ph-fire"></i></div>
                <div className="infra-node-name">Firebase</div>
                <div className="infra-node-sub">Auth</div>
              </div>
              <div className="infra-node" style={{borderColor: "#4285F4"}}>
                <div className="infra-node-icon"><i className="ph ph-cloud"></i></div>
                <div className="infra-node-name">Google Cloud</div>
                <div className="infra-node-sub">Storage</div>
              </div>
              <div className="infra-node" style={{borderColor: "#34A853"}}>
                <div className="infra-node-icon"><i className="ph ph-map-trifold"></i></div>
                <div className="infra-node-name">Google Maps</div>
                <div className="infra-node-sub">Maps & Places</div>
              </div>
              <div className="infra-node" style={{borderColor: "#4285F4"}}>
                <div className="infra-node-icon"><i className="ph ph-globe-hemisphere-west"></i></div>
                <div className="infra-node-name">Google Translate</div>
                <div className="infra-node-sub">EN / ZH</div>
              </div>
              <div className="infra-node" style={{borderColor: "#EA4335"}}>
                <div className="infra-node-icon"><i className="ph ph-envelope"></i></div>
                <div className="infra-node-name">Gmail API</div>
                <div className="infra-node-sub">Email</div>
              </div>
              <div className="infra-node" style={{borderColor: "#2D6FF7"}}>
                <div className="infra-node-icon"><i className="ph ph-device-mobile"></i></div>
                <div className="infra-node-name">ThaiBulkSMS</div>
                <div className="infra-node-sub">SMS OTP</div>
              </div>
            </div>

            {/* Ops Layer */}
            <div className="infra-label" style={{marginTop: 24}}>Operations</div>
            <div className="infra-row">
              <div className="infra-node infra-small" style={{borderColor: "#24292E"}}>
                <div className="infra-node-icon"><i className="ph ph-git-branch"></i></div>
                <div className="infra-node-name">GitHub</div>
              </div>
            </div>
          </div>
        </div>

        {/* Services Table */}
        <h2 style={{marginTop: 32, marginBottom: 16, fontSize: 18, fontWeight: 700}}><i className="ph ph-list-checks" style={{marginRight:8,color:'#4A6079'}}></i>บริการทั้งหมด</h2>
        <div className="card">
          <div className="table-wrap">
            <table className="table">
              <thead><tr><th>Service</th><th>หน้าที่</th><th>URL / Project</th><th>Account</th></tr></thead>
              <tbody>{services.map((s, i) => (
                <tr key={i}>
                  <td><span className="infra-badge" style={{background: s.color, color: "#fff"}}><i className={'ph '+s.icon} style={{marginRight:5}}></i>{s.name}</span> <span style={{color: "#6B7280", fontSize: 12}}>{s.sub}</span></td>
                  <td>{s.desc}</td>
                  <td style={{fontSize: 12, fontFamily: "monospace", color: "#2A6BE0"}}>{s.url}</td>
                  <td style={{fontSize: 13}}>{s.account}</td>
                </tr>
              ))}</tbody>
            </table>
          </div>
        </div>

        {/* Tech Stack */}
        <h2 style={{marginTop: 32, marginBottom: 16, fontSize: 18, fontWeight: 700}}><i className="ph ph-desktop" style={{marginRight:8,color:'#4A6079'}}></i>Tech Stack & เวอร์ชัน</h2>
        <div className="card">
          <div className="table-wrap">
            <table className="table">
              <tbody>{techStack.map((r, i) => (
                <tr key={i}>
                  <td style={{fontWeight: 600, whiteSpace: "nowrap"}}>{r.cat}</td>
                  <td style={{fontSize: 13}}>{r.items}</td>
                </tr>
              ))}</tbody>
            </table>
          </div>
        </div>

        {/* Domain / DNS */}
        <h2 style={{marginTop: 32, marginBottom: 16, fontSize: 18, fontWeight: 700}}><i className="ph ph-globe-hemisphere-west" style={{marginRight:8,color:'#4A6079'}}></i>โดเมน / DNS</h2>
        <div className="card">
          <div className="table-wrap">
            <table className="table">
              <thead><tr><th>ส่วน</th><th>URL ปัจจุบัน</th><th>โฮสต์</th><th>แผนโดเมนจริง (Phase 2)</th></tr></thead>
              <tbody>{dnsRows.map((r, i) => (
                <tr key={i}>
                  <td style={{fontWeight: 600, whiteSpace: "nowrap"}}>{r.name}</td>
                  <td style={{fontFamily: "monospace", fontSize: 12, color: "#2A6BE0"}}>{r.cur}</td>
                  <td style={{fontSize: 13}}>{r.host}</td>
                  <td style={{fontSize: 12.5, color: "#6B7280"}}>{r.plan}</td>
                </tr>
              ))}</tbody>
            </table>
          </div>
        </div>

        {/* การแจ้งเตือนผู้สนใจ — อีเมล vs SMS */}
        <h2 style={{marginTop: 32, marginBottom: 6, fontSize: 18, fontWeight: 700}}><i className="ph ph-envelope-open" style={{marginRight:8,color:'#4A6079'}}></i>การแจ้งเตือนผู้สนใจทรัพย์ (อีเมล / SMS)</h2>
        <p style={{margin: "0 0 16px", fontSize: 13, color: "#6B7280"}}>หลักการ: มีอีเมลในระบบ (สมาชิก) → ส่งอีเมล · มีแค่เบอร์ (คนนอกระบบ) → ส่ง SMS · การลงทุน (ขายฝาก/จำนอง) ต้อง login + ยืนยันตัวตน (KYC) ก่อน · ทุกเคสแจ้งทีมงานเสมอ</p>
        <div className="card">
          <div className="table-wrap">
            <table className="table">
              <thead><tr><th>หมวดทรัพย์</th><th>คนในระบบ (login)</th><th>คนนอกระบบ (ไม่ login)</th><th>แจ้งทีมงาน</th></tr></thead>
              <tbody>
                <tr>
                  <td><b>ขายฝาก</b> <span style={{color:"#6B7280",fontSize:12}}>· ลงทุน</span></td>
                  <td><span className="infra-badge" style={{background:"#DCE9FC",color:"#1F58C4"}}><i className="ph ph-envelope" style={{marginRight:4}}></i>อีเมล</span> <span style={{fontSize:12,color:"#6B7280"}}>ผ่าน KYC → เมลยืนยันถึงนักลงทุน</span></td>
                  <td><span style={{fontSize:12.5,color:"#9A3412"}}><i className="ph ph-lock" style={{marginRight:4}}></i>กดสนใจไม่ได้ — ต้อง login + KYC ก่อน</span></td>
                  <td style={{color:"#15976A",fontWeight:700}}>✓</td>
                </tr>
                <tr>
                  <td><b>จำนอง</b> <span style={{color:"#6B7280",fontSize:12}}>· ลงทุน</span></td>
                  <td><span className="infra-badge" style={{background:"#DCE9FC",color:"#1F58C4"}}><i className="ph ph-envelope" style={{marginRight:4}}></i>อีเมล</span> <span style={{fontSize:12,color:"#6B7280"}}>ผ่าน KYC → เมลยืนยันถึงนักลงทุน</span></td>
                  <td><span style={{fontSize:12.5,color:"#9A3412"}}><i className="ph ph-lock" style={{marginRight:4}}></i>กดสนใจไม่ได้ — ต้อง login + KYC ก่อน</span></td>
                  <td style={{color:"#15976A",fontWeight:700}}>✓</td>
                </tr>
                <tr>
                  <td><b>ขายขาด</b> <span style={{color:"#6B7280",fontSize:12}}>· ทรัพย์ฝากขาย</span></td>
                  <td><span className="infra-badge" style={{background:"#DCE9FC",color:"#1F58C4"}}><i className="ph ph-envelope" style={{marginRight:4}}></i>อีเมล</span> <span style={{fontSize:12,color:"#6B7280"}}>กดได้เลย (ใช้บัญชี ไม่ต้อง OTP) → เมลยืนยันถึงผู้ซื้อ</span></td>
                  <td><span className="infra-badge" style={{background:"#DBF1E7",color:"#15976A"}}><i className="ph ph-device-mobile" style={{marginRight:4}}></i>SMS</span> <span style={{fontSize:12,color:"#6B7280"}}>กรอกเบอร์ + OTP → SMS ยืนยัน <i style={{color:"#B5860B"}}>(รออนุมัติ Sender Name)</i></span></td>
                  <td style={{color:"#15976A",fontWeight:700}}>✓</td>
                </tr>
              </tbody>
            </table>
          </div>
          <div style={{padding:"10px 16px",fontSize:12,color:"#6B7280",borderTop:"1px solid var(--border,#E8ECF3)"}}>สถานะ: อีเมล (สมาชิก) + แจ้งทีมงาน ใช้งานจริงแล้ว · SMS สำหรับขายขาด-คนนอกระบบ + หน้าติดตามสถานะ (/track) อยู่ระหว่างพัฒนา (รออนุมัติ Sender Name จาก ThaiBulkSMS เพื่อออกจากโหมด Demo)</div>
        </div>

        {/* Risk Grade — วิธีคิดเกรดความเสี่ยงทรัพย์ */}
        <h2 style={{marginTop: 32, marginBottom: 6, fontSize: 18, fontWeight: 700}}><i className="ph ph-gauge" style={{marginRight:8,color:'#4A6079'}}></i>วิธีคิดเกรดความเสี่ยงทรัพย์ (Risk Grade)</h2>
        <p style={{margin: "0 0 16px", fontSize: 13, color: "#6B7280"}}>ระบบให้คะแนน 4 ปัจจัย (1 = เสี่ยงต่ำ, 3 = เสี่ยงสูง) แล้วถ่วงน้ำหนักรวมเป็นคะแนน 1.00–3.00 → แปลงเป็นเกรด A–E · น้ำหนักและเกณฑ์ทั้งหมดปรับได้จาก <code style={{background:"#F3F5F9",padding:"1px 6px",borderRadius:5,fontSize:12}}>site_settings</code> โดยไม่ต้องแก้โค้ด (ตัวเลขด้านล่างคือค่าเริ่มต้น)</p>
        <div className="card">
          <div className="table-wrap">
            <table className="table">
              <thead><tr><th>ปัจจัย</th><th style={{width:70,textAlign:"center"}}>น้ำหนัก</th><th>เกณฑ์ให้คะแนน (1–3)</th></tr></thead>
              <tbody>{riskFactors.map((r, i) => (
                <tr key={i}>
                  <td><div style={{fontWeight:700,fontSize:13.5}}>{r.f}</div><div style={{fontSize:11.5,color:"#6B7280"}}>{r.sub}</div></td>
                  <td style={{textAlign:"center"}}><span style={{fontWeight:800,fontSize:15,color:"#2A6BE0"}}>{r.w}%</span></td>
                  <td style={{fontSize:12.5,fontFamily:"monospace",color:"#334155"}}>{r.c}</td>
                </tr>
              ))}</tbody>
            </table>
          </div>
          <div style={{padding:"14px 16px",borderTop:"1px solid var(--border,#E8ECF3)",fontSize:13.5,color:"#334155"}}>
            <b>สูตร:</b>&nbsp; score = (LTV×40 + ทำเล×30 + เอกสาร×20 + ระยะเวลา×10) ÷ 100 &nbsp;→&nbsp; ได้ค่า 1.00 – 3.00
          </div>
        </div>

        {/* แถบเกรด A–E (คะแนนยิ่งต่ำ = ยิ่งปลอดภัย) */}
        <div style={{display:"flex",flexWrap:"wrap",gap:10,marginTop:14}}>
          {riskGrades.map((r, i) => (
            <div key={i} style={{flex:"1 1 150px",border:"1px solid var(--border,#E8ECF3)",borderRadius:12,padding:"12px 14px",display:"flex",alignItems:"center",gap:12}}>
              <span style={{width:38,height:38,borderRadius:10,background:r.c,color:"#fff",fontWeight:800,fontSize:18,display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>{r.g}</span>
              <div><div style={{fontSize:12.5,fontFamily:"monospace",fontWeight:700,color:"#334155"}}>{r.r}</div><div style={{fontSize:11.5,color:"#6B7280"}}>{r.t}</div></div>
            </div>
          ))}
        </div>

        {/* กฎพิเศษ + ตัวอย่าง */}
        <div className="card" style={{marginTop:14,padding:16}}>
          <div style={{fontWeight:700,fontSize:13.5,marginBottom:8}}><i className="ph ph-warning" style={{marginRight:6,color:"#B5860B"}}></i>กฎพิเศษ</div>
          <ul style={{margin:0,paddingLeft:20,fontSize:13,color:"#334155",lineHeight:1.7}}>
            <li>LTV ใช้ <b>มูลค่าประเมิน</b> เป็นตัวหาร ถ้าไม่กรอกจะ fallback ไปใช้ <b>ราคาขาย</b> แทน</li>
            <li><b>ขาดโฉนด (deed)</b> = เด้งเป็นคะแนน <b>3 ทันที</b> ไม่ว่าเอกสารอื่นครบแค่ไหน (critical document)</li>
            <li>แอดมิน <b>override ทำเลได้</b> — กดปรับ low/medium/high ทับค่าที่ระบบเดาจากจังหวัด</li>
          </ul>
          <div style={{marginTop:12,paddingTop:12,borderTop:"1px dashed var(--border,#E8ECF3)",fontSize:13,color:"#334155"}}>
            <b>ตัวอย่าง:</b> คอนโด LTV 60% (→2), ทำเล medium (→2), เอกสารครบ (→1), term 2 ปี (→2)<br/>
            <span style={{fontFamily:"monospace",fontSize:12.5,color:"#2A6BE0"}}>score = (2×40 + 2×30 + 1×20 + 2×10) ÷ 100 = 1.80 → เกรด B</span>
          </div>
          <div style={{marginTop:10,fontSize:11.5,color:"#6B7280"}}>อ้างอิงโค้ด: <code style={{background:"#F3F5F9",padding:"1px 6px",borderRadius:5}}>backend/src/services/risk.service.ts</code></div>
        </div>

        {/* แมพความเสี่ยงทำเล — โชว์รายชื่อ + แก้ไขได้ */}
        <h2 style={{marginTop: 32, marginBottom: 6, fontSize: 18, fontWeight: 700}}><i className="ph ph-map-pin-line" style={{marginRight:8,color:'#4A6079'}}></i>แมพความเสี่ยงทำเล (จังหวัด → ระดับ)</h2>
        <p style={{margin: "0 0 16px", fontSize: 13, color: "#6B7280"}}>กำหนดว่าจังหวัดไหนเสี่ยง <b>ต่ำ (1)</b> / <b>กลาง (2)</b> — จังหวัดที่ไม่อยู่ในลิสต์จะเป็น <b>สูง (3)</b> อัตโนมัติ · เลือกจังหวัดแล้วกดปุ่มระดับเพื่อย้าย จากนั้นกด "บันทึกแมพ" มีผลกับการคำนวณเกรดทันที (แอดมินยัง override รายทรัพย์ได้เหมือนเดิม)</p>
        <window.LocationRiskEditor />

        {/* นำเข้าผังเมืองทั้งประเทศ */}
        <h2 style={{marginTop: 32, marginBottom: 6, fontSize: 18, fontWeight: 700}}><i className="ph ph-download-simple" style={{marginRight:8,color:'#4A6079'}}></i>นำเข้าข้อมูลผังเมือง (ทั้งประเทศ)</h2>
        <p style={{margin: "0 0 16px", fontSize: 13, color: "#6B7280"}}>ดึงโพลิกอนผังเมืองจากกรมโยธาฯ (DPT) มาเก็บใน PostGIS ของเราทีเดียวทุกจังหวัด → หลังจากนี้ทรัพย์ทุกที่ที่มีพิกัด กด "ดึงอัตโนมัติ" จะเจอผังเมืองทันที (ทำครั้งเดียว · กทม.ใช้ระบบ BMA แยก)</p>
        <window.ZoningImportAll />

        {/* Accounts */}
        <h2 style={{marginTop: 32, marginBottom: 16, fontSize: 18, fontWeight: 700}}><i className="ph ph-key" style={{marginRight:8,color:'#4A6079'}}></i>บัญชีที่ใช้</h2>
        <div className="infra-accounts">
          {accounts.map((a, i) => (
            <div className="infra-account-card card" key={i}>
              <div className="infra-account-dot" style={{background: a.color}} />
              <div>
                <div style={{fontWeight: 600, fontSize: 14}}>{a.name}</div>
                <div style={{color: "#6B7280", fontSize: 13, marginTop: 4}}>{a.services}</div>
              </div>
            </div>
          ))}
        </div>

        {/* Cost */}
        <h2 style={{marginTop: 32, marginBottom: 16, fontSize: 18, fontWeight: 700}}><i className="ph ph-currency-circle-dollar" style={{marginRight:8,color:'#4A6079'}}></i>ค่าใช้จ่ายรายเดือน</h2>
        <div className="card" style={{padding: 24}}>
          <div className="table-wrap">
            <table className="table">
              <thead><tr><th>Service</th><th>Plan</th><th>ค่าใช้จ่าย</th></tr></thead>
              <tbody>
                <tr><td>Firebase Hosting (x2)</td><td>Free</td><td style={{color: "#15976A", fontWeight: 700}}>$0</td></tr>
                <tr><td>Cloud Run (Backend)</td><td>Pay-per-use · scale-to-zero</td><td style={{color: "#15976A", fontWeight: 700}}>~$0 (ยังไม่มีคนใช้)</td></tr>
                <tr><td>Cloud SQL (Database)</td><td>PostgreSQL 17 · แชร์คอร์ (ประมาณ)</td><td style={{color: "#F59E0B", fontWeight: 700}}>~$9–10 / เดือน**</td></tr>
                <tr><td>Firebase Auth</td><td>Free tier</td><td style={{color: "#15976A", fontWeight: 700}}>$0</td></tr>
                <tr><td>Google Cloud Storage</td><td>Free 5GB</td><td style={{color: "#15976A", fontWeight: 700}}>$0</td></tr>
                <tr><td>Google Maps Platform</td><td>Free credit $200/เดือน</td><td style={{color: "#15976A", fontWeight: 700}}>$0*</td></tr>
                <tr><td>Google Translate</td><td>จ่ายตามตัวอักษร</td><td style={{color: "#F59E0B", fontWeight: 700}}>~$20 / 1M ตัวอักษร</td></tr>
                <tr><td>Email (Gmail API)</td><td>Free (Google Workspace)</td><td style={{color: "#15976A", fontWeight: 700}}>$0</td></tr>
                <tr><td>ThaiBulkSMS</td><td>จ่ายตามจริง</td><td style={{color: "#F59E0B", fontWeight: 700}}>~0.25฿ / SMS</td></tr>
                <tr style={{background: "#F0FDF4"}}><td colSpan={2} style={{fontWeight: 700}}>รวมค่าคงที่ (Cloud SQL · ไม่รวมที่จ่ายตามใช้งาน: Cloud Run · SMS · แปลภาษา)</td><td style={{fontWeight: 800, fontSize: 18, color: "#15976A"}}>~$9–10/เดือน</td></tr>
              </tbody>
            </table>
          </div>
          <div style={{marginTop: 12, fontSize: 12.5, color: "#6B7280"}}>* Google Maps มี free credit $200/เดือน — การใช้งานระดับนี้ปกติ $0 (ต้องผูกบัตรเครดิตไว้ที่ Google Cloud)</div>
          <div style={{marginTop: 4, fontSize: 12.5, color: "#6B7280"}}>** Cloud SQL คิดตามขนาด instance (tier) — ตัวเลขเป็นประมาณการของ instance แบบเล็ก (แชร์คอร์) · ตรวจค่าจริงได้ที่ Cloud Console → SQL → propfinn-db</div>
        </div>

        {/* Environment Variables */}
        <h2 style={{marginTop: 32, marginBottom: 6, fontSize: 18, fontWeight: 700}}><i className="ph ph-gear" style={{marginRight:8,color:'#4A6079'}}></i>Environment Variables ที่ระบบใช้</h2>
        <p style={{margin: "0 0 16px", fontSize: 13, color: "#6B7280"}}>รายชื่อตัวแปรที่ต้องตั้งบน Cloud Run (Backend) — แสดงเฉพาะชื่อ ไม่เปิดเผยค่า · ใช้อ้างอิงตอนย้าย/ตั้งเซิร์ฟเวอร์ใหม่</p>
        <div className="infra-accounts">
          {envGroups.map((g, i) => (
            <div className="infra-account-card card" key={i} style={{alignItems: "flex-start"}}>
              <div>
                <div style={{fontWeight: 700, fontSize: 13.5, marginBottom: 8}}>{g.group}</div>
                <div style={{display: "flex", flexWrap: "wrap", gap: 6}}>
                  {g.vars.map(v => <span key={v} style={{fontFamily: "monospace", fontSize: 12, background: "#F3F5F9", border: "1px solid #E2E8F2", borderRadius: 6, padding: "3px 8px", color: "#334155"}}>{v}</span>)}
                </div>
              </div>
            </div>
          ))}
        </div>

        {/* Database Tables */}
        <h2 style={{marginTop: 32, marginBottom: 16, fontSize: 18, fontWeight: 700}}><i className="ph ph-database" style={{marginRight:8,color:'#4A6079'}}></i>ตารางฐานข้อมูลหลัก</h2>
        <div className="card">
          <div className="table-wrap">
            <table className="table">
              <thead><tr><th>ตาราง</th><th>หน้าที่</th></tr></thead>
              <tbody>{dbTables.map((r, i) => (
                <tr key={i}>
                  <td style={{fontFamily: "monospace", fontSize: 12.5, color: "#2A6BE0", whiteSpace: "nowrap"}}>{r.t}</td>
                  <td style={{fontSize: 13}}>{r.d}</td>
                </tr>
              ))}</tbody>
            </table>
          </div>
        </div>

        {/* Roadmap ย้ายสู่ GCP */}
        <h2 style={{marginTop: 32, marginBottom: 16, fontSize: 18, fontWeight: 700}}><i className="ph ph-rocket-launch" style={{marginRight:8,color:'#4A6079'}}></i>Roadmap ย้ายสู่ Google Cloud (Phase 2)</h2>
        <div className="card">
          <div className="table-wrap">
            <table className="table">
              <thead><tr><th>ส่วน</th><th>ตอนนี้ (Phase 1)</th><th>เป้าหมาย (Phase 2)</th></tr></thead>
              <tbody>{roadmap.map((r, i) => (
                <tr key={i}>
                  <td style={{fontWeight: 600, whiteSpace: "nowrap"}}>{r.part}</td>
                  <td style={{fontSize: 13, color: "#6B7280"}}>{r.now}</td>
                  <td style={{fontSize: 13, color: "#0F7A4D", fontWeight: 600}}>{r.next} →</td>
                </tr>
              ))}</tbody>
            </table>
          </div>
        </div>

        {/* Pending / Tech debt */}
        <h2 style={{marginTop: 32, marginBottom: 16, fontSize: 18, fontWeight: 700}}><i className="ph ph-push-pin" style={{marginRight:8,color:'#4A6079'}}></i>สิ่งที่ค้าง / ต้องทำก่อนขยายระบบ</h2>
        <div className="card">
          {pending.map((r, i) => (
            <div key={i} style={{display: "flex", alignItems: "flex-start", gap: 12, padding: "12px 16px", borderTop: i ? "1px solid var(--border,#E8ECF3)" : "none"}}>
              <span style={{fontSize: 11, fontWeight: 700, color: "#fff", background: r.p === "high" ? "#D8567A" : "#B5860B", borderRadius: 6, padding: "3px 9px", whiteSpace: "nowrap", marginTop: 1}}>{r.p === "high" ? "สำคัญ" : "ควรทำ"}</span>
              <div style={{flex: 1}}>
                <div style={{fontWeight: 600, fontSize: 13.5}}>{r.t}</div>
                <div style={{fontSize: 12, color: "#6B7280", marginTop: 2}}>{r.d}</div>
              </div>
            </div>
          ))}
        </div>

        <div style={{marginTop: 16, color: "#6B7280", fontSize: 13}}>อัพเดตล่าสุด: {new Date().toLocaleDateString('th-TH', {year:'numeric',month:'long',day:'numeric'})}</div>
      </>
    );
    return embedded ? body : <div className="page">{body}</div>;
  }

  window.InfraPage = InfraPage;

  // ===== เมนู "โครงสร้างระบบ" = สถาปัตยกรรม & บริการ อย่างเดียว =====
  //   (แท็บ "สิทธิ์การใช้งาน" ย้ายไปอยู่ใต้เมนู "จัดการทีมงาน" แล้ว)
  function SystemHub(props) {
    return <window.InfraPage {...props} />;
  }
  window.SystemHub = SystemHub;
})();
