// API helper
window.api = {
  baseUrl: window.ADMIN_CONFIG.apiUrl,

  async request(method, path, body) {
    const token = await window.firebaseAuth.currentUser?.getIdToken();
    const headers = {};
    if (token) headers['Authorization'] = `Bearer ${token}`;
    // ตั้ง Content-Type เฉพาะตอนมี body — กัน Fastify เด้ง 400 (empty json body) ตอน PUT/POST ไม่มี body
    if (body) headers['Content-Type'] = 'application/json';
    const res = await fetch(this.baseUrl + path, {
      method,
      headers,
      body: body ? JSON.stringify(body) : undefined,
    });
    if (!res.ok) {
      let msg = 'API Error: ' + res.status;
      try { const j = await res.json(); if (j && j.error) msg = j.error; } catch (_) {}
      throw new Error(msg);
    }
    return res.json();
  },

  get: (path) => window.api.request('GET', path),
  post: (path, body) => window.api.request('POST', path, body),
  put: (path, body) => window.api.request('PUT', path, body),
  delete: (path) => window.api.request('DELETE', path),

  // Admin APIs
  stats: () => window.api.get('/admin/stats'),
  listings: (status, kind, opts = {}) => {
    const q = new URLSearchParams();
    if (status) q.set('status', status);
    if (kind) q.set('kind', kind);
    q.set('page', opts.page || 1);
    q.set('limit', opts.limit || 20);
    if (opts.sortKey) q.set('sort_key', opts.sortKey);
    if (opts.sortDir) q.set('sort_dir', opts.sortDir);
    return window.api.get('/admin/listings?' + q.toString());
  },
  approveListing: (id) => window.api.put(`/admin/listings/${id}/approve`),
  setListingVisibility: (id, visible) => window.api.put(`/admin/listings/${id}/visibility`, { visible }),
  rejectListing: (id, reason) => window.api.put(`/admin/listings/${id}/reject`, { reason }),
  users: (role) => window.api.get(`/admin/users${role ? `?role=${role}` : ''}`),
  staffUsers: () => window.api.get('/admin/users?group=staff'),
  banUser: (id) => window.api.put(`/admin/users/${id}/ban`),
  unbanUser: (id) => window.api.put(`/admin/users/${id}/unban`),
  changeRole: (id, role) => window.api.put(`/admin/users/${id}/role`, { role }),
  pendingAgents: () => window.api.get('/admin/agents/pending'),
  allAgents: () => window.api.get('/admin/agents'),
  approveAgent: (id) => window.api.put(`/admin/agents/${id}/approve`),
  rejectAgent: (id, reason) => window.api.put(`/admin/agents/${id}/reject`, { reason }),
  privacyRequests: (status) => window.api.get(`/admin/privacy-requests${status ? `?status=${status}` : ''}`),
  updatePrivacyRequest: (id, data) => window.api.put(`/admin/privacy-requests/${id}`, data),
  anonymizePrivacyRequest: (id) => window.api.post(`/admin/privacy-requests/${id}/anonymize`),
  auditLogs: (qs) => window.api.get('/admin/audit-logs' + (qs ? '?' + qs : '')),
  emailLogs: (qs) => window.api.get('/admin/email-logs' + (qs ? '?' + qs : '')),
  adminActions: (qs) => window.api.get('/admin/admin-actions' + (qs ? '?' + qs : '')),
  articles: (status) => window.api.get(`/admin/articles${status ? `?status=${status}` : ''}`),
  createArticle: (data) => window.api.post('/admin/articles', data),
  updateArticle: (id, data) => window.api.put(`/admin/articles/${id}`, data),
  publishArticle: (id) => window.api.put(`/admin/articles/${id}/publish`),
  unpublishArticle: (id) => window.api.put(`/admin/articles/${id}/unpublish`),
  deleteArticle: (id) => window.api.delete(`/admin/articles/${id}`),
  articleCategories: () => window.api.get('/admin/articles/categories'),
  matchingLeads: (status) => window.api.get(`/admin/leads/matching${status ? `?status=${status}` : ''}`),
  updateLeadStatus: (id, status) => window.api.put(`/admin/leads/matching/${id}/status`, { status }),
  // ผลลัพธ์ดีลของลีด "ขอเงินทุน" — จบเป็น ขายฝาก/จำนอง/ไม่ได้ดีล ('' = ยังไม่สรุป)
  updateLeadOutcome: (id, deal_outcome) => window.api.put(`/admin/leads/matching/${id}/status`, { deal_outcome }),
  inquiries: () => window.api.get('/admin/leads/inquiries'),

  // ทรัพย์ที่คนภายนอกส่งเข้ามา (listing_submissions)
  submissions: (status) => window.api.get(`/admin/submissions${status ? `?status=${status}` : ''}`),
  submission: (id) => window.api.get(`/admin/submissions/${id}`),
  updateSubmission: (id, data) => window.api.put(`/admin/submissions/${id}`, data),
  approveSubmission: (id) => window.api.post(`/admin/submissions/${id}/approve`),
  rejectSubmission: (id, reason) => window.api.post(`/admin/submissions/${id}/reject`, { reason }),
  // ความสนใจจากนักลงทุน (lead โทรกลับ)
  investorInterest: (status) => window.api.get(`/admin/leads/investor-interest${status ? `?status=${status}` : ''}`),
  updateInterestStatus: (eventId, status) => window.api.put(`/admin/leads/investor-interest/${eventId}/status`, { status }),
  // ผู้สนใจซื้อทรัพย์ขายขาด (buyer_leads) — แยกจากฝั่งลงทุน
  buyerLeads: (status) => window.api.get(`/admin/leads/buyers${status ? `?status=${status}` : ''}`),
  updateBuyerStatus: (id, status) => window.api.put(`/admin/leads/buyers/${id}/status`, { status }),

  // CRM ติดตามงาน — รายชื่อทีมงาน + ตั้งผู้รับผิดชอบ/นัดติดตามถัดไป (kind = investor|buyer|matching)
  staff: () => window.api.get('/admin/staff'),
  updateLeadCrm: (kind, leadId, body) => window.api.put(`/admin/leads/${kind}/${leadId}/crm`, body),
  // มุมมองรายลูกค้า (Phase 2) — รวมทุกลีดของเบอร์เดียว + timeline
  customerLookup: (phone, userId) => window.api.get(`/admin/customers/lookup?phone=${encodeURIComponent(phone || '')}&user_id=${encodeURIComponent(userId || '')}`),

  // Report ผู้บริหาร (read-only)
  executiveReport: () => window.api.get('/admin/executive/report'),
  dealsReport: () => window.api.get('/admin/deals/report'),
  testEmail: () => window.api.post('/admin/executive/email-test'),
  emailStatus: () => window.api.get('/admin/executive/email-status'),
  systemConfig: () => window.api.get('/admin/system/config'),

  // Investors (อนุมัติ)
  investors: (status) => window.api.get(`/admin/investors${status ? `?status=${status}` : ''}`),
  approveInvestor: (userId) => window.api.put(`/admin/investors/${userId}/approve`),
  rejectInvestor: (userId, reason) => window.api.put(`/admin/investors/${userId}/reject`, { reason }),

  // นายหน้า (brokers)
  brokers: () => window.api.get('/admin/brokers'),
  createBroker: (data) => window.api.post('/admin/brokers', data),
  updateBroker: (id, data) => window.api.put(`/admin/brokers/${id}`, data),
  deleteBroker: (id) => window.api.delete(`/admin/brokers/${id}`),
  owners: () => window.api.get('/admin/owners'),
  createOwner: (data) => window.api.post('/admin/owners', data),
  updateOwner: (id, data) => window.api.put(`/admin/owners/${id}`, data),
  deleteOwner: (id) => window.api.delete(`/admin/owners/${id}`),

  // Risk grade (คำนวณสด + config)
  riskPreview: (data) => window.api.post('/admin/listings/risk-preview', data),
  riskConfig: () => window.api.get('/admin/listings/risk-config'),
  saveLocationRiskMap: (data) => window.api.post('/admin/listings/location-risk-map', data),
  zoning: (lat, lng) => window.api.get('/admin/zoning?lat=' + encodeURIComponent(lat) + '&lng=' + encodeURIComponent(lng)),
  zoningBulk: (data) => window.api.post('/admin/zoning/bulk', data),
  _PCODE: {'กรุงเทพมหานคร':'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'},
  provinceCodeOf: (name) => (name && window.api._PCODE[String(name).trim()]) || null,
  // เบราว์เซอร์ดึงผังเมืองจาก ArcGIS (DPT/BMA) เอง แล้วส่งเข้า backend เก็บ (Cloud Run ต่อ server รัฐไม่ได้ ECONNRESET)
  async importProvinceBrowser(code, onProgress) {
    code = String(code);
    const getJson = async (url) => { try { return await fetch(url).then(r => r.json()); } catch (e) { return null; } };
    let total = 0, posted = false;
    const send = async (batch) => {
      // ซอยเป็นก้อนเล็ก (กัน 413 Request Too Large ตอนโพลิกอนใหญ่ เช่นโคราช)
      for (let i = 0; i < batch.length; i += 20) {
        const part = batch.slice(i, i + 20);
        const r = await window.api.zoningBulk({ province_code: code, replace: !posted, features: part });
        total += (r && r.inserted) || 0; posted = true;
        if (onProgress) onProgress(total);
      }
    };
    if (code === '10') {
      // กทม. = BMA (ArcGIS ใหม่ → paginate ได้)
      const base = 'https://cityplangis.bangkok.go.th/arcgis/rest/services/bma/ComprehensivePlan/MapServer/11';
      let offset = 0;
      while (true) {
        const gj = await getJson(base + '/query?where=1%3D1&outFields=LUP_USE,LUP_ZONE&returnGeometry=true&outSR=4326&f=geojson&resultOffset=' + offset + '&resultRecordCount=200');
        const feats = (gj && gj.features) || [];
        if (!feats.length) break;
        await send(feats.filter(f => f.geometry).map(f => ({ pl_use: (f.properties || {}).LUP_USE, plan: (f.properties || {}).LUP_ZONE, geometry: f.geometry })));
        if (feats.length < 200) break;
        offset += 200;
      }
    } else {
      // ต่างจังหวัด = DPT (ArcGIS เก่า → ไม่มี pagination) · ดึงทุก layer PLLU_ ทีเดียว
      const meta = await getJson('https://dptgis.dpt.go.th/arcgis/rest/services/dds2/PLLU' + code + '/MapServer?f=json');
      const layers = ((meta && meta.layers) || []).filter(l => /^PLLU_/i.test(l.name || '')).map(l => l.id);
      if (!layers.length) return { code, inserted: 0, noService: true };
      for (const layer of layers) {
        const gj = await getJson('https://dptgis.dpt.go.th/arcgis/rest/services/dds2/PLLU' + code + '/MapServer/' + layer + '/query?where=1%3D1&outFields=PL_USE,PRJ_ID&returnGeometry=true&outSR=4326&f=geojson');
        const feats = (gj && gj.features) || [];
        await send(feats.filter(f => f.geometry).map(f => ({ pl_use: (f.properties || {}).PL_USE, plan: (f.properties || {}).PRJ_ID, geometry: f.geometry })));
      }
    }
    return { code, inserted: total };
  },
  nextListingCode: (kind) => window.api.get('/admin/listings/next-code' + (kind ? '?kind=' + kind : '')),

  // ── ราคาประเมินราชการ (กรมธนารักษ์ Open Data) ──
  // เบราว์เซอร์แอดมิน (IP ไทย) ยิง JSONP ตรงไป treasury เอง — Cloud Run ต่อ treasury ไม่ได้ (firewall drop IP ศูนย์ข้อมูล)
  // callback= เลี่ยง CORS · key ค้นหา = จังหวัด + ระวาง(UTMMAP1-4) + เลขที่ดิน(LAND_NO) → EVAPRICE (บาท/ตร.ว.)
  _LANDRES: {'กรุงเทพมหานคร':'00da1ca3-2c41-436d-a426-d0c06f8cae03','สมุทรปราการ':'9919be07-ecdd-4542-bd67-6d408691dbd0','นนทบุรี':'1385f623-15c9-4253-b659-093ace6840da','ปทุมธานี':'bb55833f-6dd0-491a-bbce-48a3301fb303','พระนครศรีอยุธยา':'6316d19b-2c3f-4dfc-90d7-10928af87254','อ่างทอง':'f17034db-c754-4034-8909-8f81ba301298','ลพบุรี':'9b55cd12-65a2-4c22-94ad-ba4ce04c1656','สิงห์บุรี':'325760c2-1820-4de6-9c35-dfd9ee169fe0','ชัยนาท':'af2a8836-4926-4484-b7a3-b50aef6cd490','สระบุรี':'706137e2-5ca9-468e-8ea4-d7545b4b7e31','ชลบุรี':'26af9fa1-75f5-442e-bf45-4aabbae47c6a','ระยอง':'79b27f64-e184-4e2b-8023-763f0bd3a4af','จันทบุรี':'4a730820-da49-4148-9502-5f58b6858ac4','ตราด':'f785919e-b315-4f7f-b07c-499e8ff81e30','ฉะเชิงเทรา':'038b5bbc-6c46-4edf-a8cc-b5334d1230bc','ปราจีนบุรี':'d3ee2c6f-b66b-424f-bfe0-ade07d4f3c2c','นครนายก':'02c7bd8a-a4a7-45d0-9cb2-1ec98336ab05','สระแก้ว':'88ce20ff-00d3-4a51-a1bd-1ba9ee049330','นครราชสีมา':'83e5b380-ec05-44d7-837c-49a1b48ac7a8','บุรีรัมย์':'8288f42e-efb7-4261-a28a-9572cace645a','สุรินทร์':'1519fdeb-0baf-4e76-9216-29eea28fce1e','ศรีสะเกษ':'c9e7e074-dcd7-49db-91c5-c12e4dfe4949','อุบลราชธานี':'81947d85-c1be-40c1-aef0-a36f06d30aef','ยโสธร':'8bd8d480-021e-4d01-9d58-7113f1fa0dca','ชัยภูมิ':'fb350eb4-8367-4ca8-aee2-e0db5779bcd5','อำนาจเจริญ':'1c471d41-b640-4de8-b313-fd2d93c50dac','บึงกาฬ':'947897cc-3fc9-483e-8946-9477fbfcb8b7','หนองบัวลำภู':'7da6e78f-0f53-4858-8256-b3d73c20782a','ขอนแก่น':'3578b078-f24b-4c1c-b2e9-c6f505cfe0df','อุดรธานี':'1d105c96-f26c-44e9-bee6-442d1d0e6b58','เลย':'0811da0f-0b90-449d-86bb-8d608d66c847','หนองคาย':'dc8b0dbc-4259-41cd-8435-9d12f9b6be0c','มหาสารคาม':'d1ff7fa8-4773-4f6b-87c4-358a11b057fe','ร้อยเอ็ด':'fb071e5f-dbd2-4cca-980a-48da7b2ebbb4','กาฬสินธุ์':'68ccc5bc-596a-4a96-acaf-d235ff27d67f','สกลนคร':'a665745d-65ec-46c6-a125-c302fa6336a2','นครพนม':'1478a0df-68c9-4baf-ab0a-740c6df054cb','มุกดาหาร':'ea9b7f0e-aadd-47ac-8821-3fba4a8cd4db','เชียงใหม่':'2cd4407a-a5f8-47ec-97a9-dc1dd5172a9f','ลำพูน':'1c88cc41-3da2-45c7-bdf5-fe9af73a33ec','ลำปาง':'d65c28ad-0edc-48bf-8525-2cb7f3dc28db','อุตรดิตถ์':'aae301fb-997e-4997-b3cc-a3fe566ba26e','แพร่':'5a52f5f3-9e5c-4e58-a8e1-7ec7785c4f75','น่าน':'ffe8100e-4cfe-412a-96f7-d15ca2470492','พะเยา':'c5e4d555-9856-4e7b-acd7-d271139f1af1','เชียงราย':'0e611e96-f7af-4a6c-93de-05f05708bd65','แม่ฮ่องสอน':'23cb3427-49d5-4de5-aa08-c8de4ae3b904','นครสวรรค์':'5c8d4983-0ab9-48df-b545-e6256ccd412a','อุทัยธานี':'1f4dd66c-0beb-4307-918f-5102ad50b195','กำแพงเพชร':'c5749905-f5fe-4636-8b54-0001e5c9e237','ตาก':'d3c6d354-24c8-4738-8b0c-4d461c124e26','สุโขทัย':'2b904747-c67a-4fd7-ae22-681275387dc3','พิษณุโลก':'bff3c676-501f-484d-a70f-927fe1d46b21','พิจิตร':'31ae0e47-097e-4630-92c3-2b8d796eb517','เพชรบูรณ์':'e4e9edf7-ed90-4233-bf08-833239a82533','ราชบุรี':'363aa212-3d48-4bf0-9234-de486ed6af76','กาญจนบุรี':'70d530dd-4b3e-41d8-8dd9-946c6d5b301a','สุพรรณบุรี':'b5a6e5cf-e26f-488b-82d1-2adb72a78897','นครปฐม':'16b9866c-c457-4845-8437-d6694bbe8338','สมุทรสาคร':'0355472e-c037-41bd-a34c-d6006d4dd79d','สมุทรสงคราม':'8f34bb38-cd6e-4363-9dc0-e8f8eab6311e','เพชรบุรี':'1c9b6536-69ee-4108-8f56-e0826925c04a','ประจวบคีรีขันธ์':'31568747-05dd-4fc7-95b8-a7a42320cbe7','นครศรีธรรมราช':'4136efec-81fa-4f40-a7dd-6d9b0aa20f98','กระบี่':'aa973aa6-469c-4ef2-ab41-50011ecd5a92','พังงา':'ffe71775-5a99-428f-9ccf-18cbaa091bbb','ภูเก็ต':'a4b60b8c-620c-4a6b-a4ec-d559558ec4f6','สุราษฎร์ธานี':'e7a4b00c-16bb-42d8-839c-1055fef4f374','ระนอง':'6fe04137-8ac6-4f76-b4d2-503a77487d19','ชุมพร':'83501b60-d63a-468f-9457-a41b753c87d6','สงขลา':'5e45fa23-62f1-44d9-9a15-af2ec2d99469','สตูล':'4a90c375-e785-44df-ae85-4e21e4c7500b','ตรัง':'ae8a931d-a0bf-4e6f-8f41-b8390ecdad01','พัทลุง':'dda17f2b-2241-4957-8e2f-72e7f15a4915','ปัตตานี':'7cb53c24-903a-4a67-81e3-23229bfccf10','ยะลา':'1364f03b-5bc1-44c9-825d-5c5b2c599b44','นราธิวาส':'871395c9-10b8-4b63-92eb-41eaec58bbc8'},
  jsonp(url, timeoutMs) {
    return new Promise((resolve, reject) => {
      const cb = '__lp_' + Math.random().toString(36).slice(2);
      const s = document.createElement('script');
      let done = false;
      const cleanup = () => { try { delete window[cb]; } catch (e) { window[cb] = undefined; } if (s.parentNode) s.parentNode.removeChild(s); };
      const timer = setTimeout(() => { if (!done) { done = true; cleanup(); reject(new Error('หมดเวลา')); } }, timeoutMs || 20000);
      window[cb] = (data) => { done = true; clearTimeout(timer); cleanup(); resolve(data); };
      s.onerror = () => { if (!done) { done = true; clearTimeout(timer); cleanup(); reject(new Error('โหลดไม่สำเร็จ')); } };
      s.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'callback=' + cb;
      document.head.appendChild(s);
    });
  },
  async landPrice(province, m1, m2, m3, m4, scale, landno) {
    const rid = window.api._LANDRES[String(province || '').trim()];
    if (!rid) return { found: false, reason: 'ไม่รู้จักจังหวัด "' + (province || '') + '"' };
    const filters = JSON.stringify({ UTMMAP1: String(m1), UTMMAP2: String(m2), UTMMAP3: String(m3), LAND_NO: String(landno) });
    const url = 'https://catalog.treasury.go.th/api/3/action/datastore_search?resource_id=' + rid + '&limit=100&filters=' + encodeURIComponent(filters);
    let data;
    try { data = await window.api.jsonp(url, 20000); }
    catch (e) { return { found: false, reason: 'ต่อกรมธนารักษ์ไม่ได้ (' + e.message + ')' }; }
    if (!data || !data.success) return { found: false, reason: 'กรมธนารักษ์ตอบผิดพลาด' };
    const recs = (data.result && data.result.records) || [];
    if (!recs.length) return { found: false, reason: 'ไม่พบแปลงนี้ — เช็คระวาง/เลขที่ดินอีกครั้ง' };
    const n4 = Number(m4);
    const rec = recs.find(r => Number(r.UTMMAP4) === n4 && (!scale || String(r.UTMSCALE) === String(scale)))
      || recs.find(r => Number(r.UTMMAP4) === n4)
      || recs[0];
    if (rec && rec.EVAPRICE != null)
      return { found: true, price_per_wa: Number(rec.EVAPRICE), scale: String(rec.UTMSCALE), candidates: recs.length, exact: Number(rec.UTMMAP4) === n4 };
    return { found: false, reason: 'ไม่พบราคาประเมิน', candidates: recs.length };
  },
};
