/* =========================================================
   ZA-FARM-KH — Gmail OTP Service
   Reseller system: buys from upstream API, sells to users
   ========================================================= */

const API_BASE = window.location.hostname === "localhost"
  ? "http://localhost:3000/zapi"
  : "/zapi";

const GMAIL_SERVICE = {
  id: "gmail_otp",
  title: "Gmail OTP",
  price: 0.055,
  duration: "6 នាទី",
  stock: 0
};

const PHONE_SERVICE_US = {
  id: "phone_sms_us",
  title: "Phone SMS 🇺🇸",
  price: 0.032,
  duration: "20 នាទី",
  stock: 9999
};

const PHONE_SERVICE_KH = {
  id: "phone_sms_kh",
  title: "Phone SMS 🇰🇭",
  price: 0.032,
  duration: "20 នាទី",
  stock: 9999
};

let currentService = GMAIL_SERVICE;

let orders = [];
let user = JSON.parse(localStorage.getItem("zafarm_user") || "null");
let token = localStorage.getItem("zafarm_token");

/* ---------- Init ---------- */
document.addEventListener("DOMContentLoaded", async () => {
  initTheme();
  initMobileMenu();
  initLiveTime();

  if (!token) {
    const balEl = document.getElementById("userBalance");
    if (balEl) balEl.textContent = "Guest";
    const logoutBtn = document.getElementById("logoutBtn");
    if (logoutBtn) {
      logoutBtn.innerHTML = `<span style="font-size:13px;font-weight:700;color:var(--gold);">🔑 Login</span>`;
      logoutBtn.onclick = () => { window.location.href = "/login"; };
    }
    await loadServices();
    bindBuyButton();
    bindModal();
    loadOnlineCount();
    return;
  }

  renderBalance();
  await loadUser(); // 🟢 Fetch latest user info (balance) from server
  await loadServices();
  await loadOrders();
  bindQuickBuy();
  bindBuyButton();
  bindModal();
  bindLogout();
  bindRefresh();
  showAdminLink();
  loadOnlineCount();
});

/* ---------- Theme ---------- */
function initTheme() {
  // Gold theme only — no dark mode
  document.documentElement.removeAttribute("data-theme");
  const toggle = document.getElementById("themeToggle");
  if (toggle) toggle.style.display = "none";
}

/* ---------- Mobile Menu ---------- */
function initMobileMenu() {
  const btn = document.getElementById("menuToggle");
  const sidebar = document.getElementById("sidebar");
  if (btn && sidebar) {
    btn.addEventListener("click", () => sidebar.classList.toggle("open"));
    document.addEventListener("click", (e) => {
      if (!sidebar.contains(e.target) && !btn.contains(e.target)) {
        sidebar.classList.remove("open");
      }
    });
  }
}

/* ---------- Live Time ---------- */
function initLiveTime() {
  const el = document.getElementById("liveTime");
  if (!el) return;
  function update() {
    const now = new Date();
    el.textContent = now.toLocaleTimeString("en-US", { hour12: false });
  }
  update();
  setInterval(update, 1000);
}

/* ---------- Balance ---------- */
function renderBalance() {
  const bal = user ? (user.balance || 0).toFixed(3) : "0.000";
  const el = document.getElementById("userBalance");
  const mob = document.getElementById("mobileBalance");
  if (el) el.textContent = "$" + bal;
  if (mob) mob.textContent = "$" + bal;
}

/* ---------- Load User ---------- */
async function loadUser() {
  if (!token) return;
  try {
    const res = await fetch(`${API_BASE}/auth/me`, {
      headers: { Authorization: `Bearer ${token}` }
    });
    if (res.ok) {
      const data = await res.json();
      if (data.user) {
        user = data.user;
        localStorage.setItem("zafarm_user", JSON.stringify(user));
        renderBalance();
      }
    }
  } catch (err) {
    // Silently fail if user can't be fetched
  }
}

let stockTimer = null;

/* ---------- Admin Link ---------- */
function showAdminLink() {
  const u = JSON.parse(localStorage.getItem("zafarm_user") || "null");
  if (u && u.role === "admin") {
    const link = document.getElementById("adminNavLink");
    if (link) link.style.display = "";
    const ordersLink = document.getElementById("adminOrdersLink");
    if (ordersLink) ordersLink.style.display = "";
  }
}

/* ---------- Load Services ---------- */
async function loadServices() {
  try {
    const res = await fetch(`${API_BASE}/services`);
    if (res.ok) {
      const data = await res.json();
      const gmail = data.find(s => s.id === "gmail_otp" || s.id === "fb_gmail_otp");
      if (gmail) {
        GMAIL_SERVICE.stock = gmail.stock;
        GMAIL_SERVICE.price = gmail.price || 0.055;
      }
    }
  } catch { /* use defaults */ }
  updateStockDisplay();

  // Auto-refresh stock every 30 seconds (realtime from upstream)
  if (stockTimer) clearTimeout(stockTimer);
  stockTimer = setTimeout(loadServices, 30000);
}

function updateStockDisplay() {
  const el = document.getElementById("gmailStock");
  if (el) {
    el.textContent = GMAIL_SERVICE.stock;
  }
  const btn = document.getElementById("quickBuyBtn");
  const modalBtn = document.getElementById("buyGmailBtn");
  if (btn) btn.disabled = GMAIL_SERVICE.stock === 0;
  if (modalBtn) modalBtn.disabled = GMAIL_SERVICE.stock === 0;
}

let isCheckingOtp = false;

/* ---------- Load Orders ---------- */
async function loadOrders() {
  try {
    const res = await fetch(`${API_BASE}/orders`, {
      headers: { Authorization: `Bearer ${token}` },
    });
    if (res.ok) {
      orders = await res.json();
      localStorage.setItem("zafarm_orders", JSON.stringify(orders));
    } else throw new Error();
  } catch {
    orders = JSON.parse(localStorage.getItem("zafarm_orders") || "[]");
  }
  
  if (!isCheckingOtp) {
    renderOrders();
  }
  renderStats();
}

function renderStats() {
  const t = document.getElementById("totalOrders");
  const s = document.getElementById("successOrders");
  const p = document.getElementById("pendingOrders");
  if (t) t.textContent = orders.length;
  if (s) s.textContent = orders.filter(o => o.status === "success").length;
  if (p) p.textContent = orders.filter(o => o.status === "pending").length;
}

// 🛡️ XSS Protection — escape HTML entities before rendering
function escapeHtml(str) {
  if (typeof str !== "string") return "";
  const map = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#x27;" };
  return str.replace(/[&<>"']/g, c => map[c]);
}

// 🛡️ Escape for HTML attributes (data-copy, etc.)
function escapeAttr(str) {
  if (typeof str !== "string") return "";
  return str.replace(/[&<>"'`=/]/g, c => "&#" + c.charCodeAt(0) + ";");
}

function renderOrders() {
  const list = document.getElementById("ordersList");
  const empty = document.getElementById("emptyOrders");
  if (!list) return;

  if (orders.length === 0) {
    list.innerHTML = "";
    if (empty) { list.appendChild(empty); empty.style.display = "block"; }
    return;
  }

  if (empty) empty.style.display = "none";

  list.innerHTML = orders.map(o => {
    const mail      = o.items?.[0]?.mail || "—";
    const otp       = o.items?.[0]?.otp  || "";
    const hasOtp    = otp && otp !== "" && otp !== "រង់ចាំ..." && otp !== "expired";
    const isPending = o.status === "pending";
    const isSuccess = o.status === "success";
    const hasUpstream = o.items?.[0]?.upstreamOrderId;
    const safeStatus = escapeHtml(o.status || "");
    const safeId = escapeAttr(o.id || "");

    return `
    <div class="order-card">
      <div class="order-top">
        <span class="order-status ${safeStatus}">${safeStatus === "success" ? "✅ ជោគជ័យ" : safeStatus === "pending" ? "⏳ pending" : "❌ failed"}</span>
        <span class="order-time">${o.createdAt ? timeAgo(o.createdAt) : ""}</span>
      </div>
      <div class="order-mail-row">
        <span class="order-mail-label">📧 Gmail:</span>
        <span class="order-mail-value">${escapeHtml(mail)}</span>
        <button class="order-btn copy-flash-btn" data-copy="${escapeAttr(mail)}" title="Copy Gmail">📋</button>
      </div>
      <div class="order-otp-row">
        <span class="order-otp-label">🔑 OTP:</span>
        <span class="order-otp-value ${hasOtp ? "has-code" : ""}" id="otp-val-${safeId}">
          ${hasOtp ? escapeHtml(otp) : (isPending ? "កំពុងរង់ចាំ..." : "—")}
        </span>
        ${hasOtp ? `<button class="order-btn otp-copy-btn" data-copy="${escapeAttr(otp)}" data-order="${safeId}" title="Copy OTP ទៅ clipboard">⚡ Copy</button>` : ""}
        ${isPending ? `<button class="order-btn check-btn" data-order="${safeId}">ឆែក OTP</button>` : ""}
        ${isSuccess && hasUpstream ? `<button class="order-btn recheck-btn" data-order="${safeId}" title="ឆែក OTP ម្ដងទៀតសម្រាប់ account ថ្មី">🔄 Re-check</button>` : ""}
      </div>
      <div class="order-bottom">
        <span>$${(o.total || 0).toFixed(3)} • ${parseInt(o.qty) || 1} item</span>
      </div>
    </div>`;
  }).join("");

  // ── 1-click Copy flash (Gmail + OTP copy-flash-btn)
  list.querySelectorAll(".copy-flash-btn").forEach(btn => {
    btn.addEventListener("click", () => {
      navigator.clipboard.writeText(btn.dataset.copy).then(() => {
        const orig = btn.textContent;
        btn.textContent = "✓";
        btn.style.color = "var(--green)";
        btn.style.borderColor = "var(--green)";
        setTimeout(() => {
          btn.textContent = orig;
          btn.style.color = "";
          btn.style.borderColor = "";
        }, 1200);
      });
    });
  });

  // ── OTP 1-click Copy (⚡ Copy button — stays, flashes ✓)
  list.querySelectorAll(".otp-copy-btn").forEach(btn => {
    btn.addEventListener("click", () => {
      const otp = btn.dataset.copy;
      navigator.clipboard.writeText(otp).then(() => {
        const orig = btn.innerHTML;
        btn.innerHTML = "✓ Copied!";
        btn.style.color = "var(--green)";
        btn.style.borderColor = "var(--green)";
        btn.style.background = "rgba(74,222,128,.12)";
        setTimeout(() => {
          btn.innerHTML = orig;
          btn.style.color = "";
          btn.style.borderColor = "";
          btn.style.background = "";
        }, 1500);
      });
    });
  });

  // ── Check OTP (pending) + Re-check OTP (success) — shared handler
  async function doFetchOtp(btn, orderId, label, isAuto = false) {
    if (btn.classList.contains("loading")) return;
    btn.classList.add("loading");
    const origText = btn.innerHTML;
    btn.innerHTML = `<svg class="spinner" viewBox="0 0 50 50" style="width:16px;height:16px;animation:rotate 2s linear infinite;"><circle class="path" cx="25" cy="25" r="20" fill="none" stroke="currentColor" stroke-width="5" stroke-linecap="round" style="animation:dash 1.5s ease-in-out infinite;"></circle></svg> ឆែក...`;

    isCheckingOtp = true;
    try {
      const res = await fetch(`${API_BASE}/orders/${orderId}/fetch-otp`, {
        method: "POST",
        headers: { Authorization: `Bearer ${token}` },
      });
      const data = await res.json();
      const newOtp = data.items?.[0]?.otp || "";
      const hasNew = newOtp && newOtp !== "" && newOtp !== "expired";

      if (hasNew) {
        // Update OTP display in-place
        const valEl = document.getElementById(`otp-val-${orderId}`);
        if (valEl) {
          valEl.textContent = newOtp;
          valEl.classList.add("has-code");
        }
        // Update copy button data
        const copyBtn = btn.previousElementSibling;
        if (copyBtn && copyBtn.classList.contains("otp-copy-btn")) {
          copyBtn.dataset.copy = newOtp;
        }
        if (!isAuto) {
          showToast(`✅ OTP: ${newOtp} — Copied!`);
          navigator.clipboard.writeText(newOtp).catch(() => {});
        }
        
        // Update memory so UI doesn't lose state
        const idx = orders.findIndex(o => String(o.id) === String(orderId));
        if (idx !== -1) {
          orders[idx].status = "success";
          if (!orders[idx].items) orders[idx].items = [{}];
          orders[idx].items[0].otp = newOtp;
          localStorage.setItem("zafarm_orders", JSON.stringify(orders));
          renderStats();
        }
      } else if (data.status === "failed") {
        if (!isAuto) showToast("OTP ផុតកំណត់ — ប្រាក់ត្រូវបានបង្វិលចូលវិញ!", true);
        await loadUser(); // Fetch updated balance after refund
        isCheckingOtp = false; // Allow re-render for failed order
        await loadOrders(); 
        return; // Early return to avoid touching btn
      } else {
        if (!isAuto) showToast("⏳ កំពុងរង់ចាំ OTP ពីក្រុមហ៊ុន...");
      }
    } catch (err) {
      showToast("Error: " + (err.message || "server error"), true);
    } finally {
      isCheckingOtp = false;
      if (btn) {
        btn.classList.remove("loading");
        btn.innerHTML = origText;
      }
    }
  }

  list.querySelectorAll(".check-btn").forEach(btn => {
    btn.addEventListener("click", () => doFetchOtp(btn, btn.dataset.order, "ឆែក OTP"));
  });
  list.querySelectorAll(".recheck-btn").forEach(btn => {
    btn.addEventListener("click", () => doFetchOtp(btn, btn.dataset.order, "Re-check"));
  });

  // Auto-refresh if pending — every 5s
  if (orders.some(o => o.status === "pending")) {
    setTimeout(async () => {
      // Auto-check all pending orders directly from upstream
      const pendings = orders.filter(o => o.status === "pending");
      for (const p of pendings) {
        const btn = document.querySelector(`.check-btn[data-order="${p.id}"]`);
        if (btn && !btn.classList.contains("loading")) {
           doFetchOtp(btn, p.id, "ឆែក OTP", true);
        }
      }
      
      loadUser();
      loadOrders();
    }, 5000);
  }
}

function timeAgo(dateStr) {

  const diff = Date.now() - new Date(dateStr).getTime();
  const mins = Math.floor(diff / 60000);
  if (mins < 1) return "ឥឡូវ";
  if (mins < 60) return mins + "m";
  const hrs = Math.floor(mins / 60);
  if (hrs < 24) return hrs + "h";
  return Math.floor(hrs / 24) + "d";
}

/* ---------- Quick Buy (1-click) ---------- */
function bindQuickBuy() {
  const btn = document.getElementById("quickBuyBtn");
  if (!btn) return;
  btn.addEventListener("click", () => quickBuy());
}

async function quickBuy() {
  if (!token) {
    if (typeof showGuestAuthModal === "function") showGuestAuthModal();
    else window.location.href = "/login";
    return;
  }
  const btn = document.getElementById("quickBuyBtn");
  if (!btn || btn.disabled) return;

  const total = GMAIL_SERVICE.price;
  if (!user || (user.balance || 0) < total) {
    showToast("Balance មិនគ្រប់គ្រាន់ — ត្រូវការ $" + total.toFixed(3) + " សូមបញ្ចូលប្រាក់", true);
    return;
  }

  // Loading state
  const origHTML = btn.innerHTML;
  btn.disabled = true;
  btn.innerHTML = `<span class="quick-icon">⏳</span><span class="quick-text">កំពុងដំណើរការ...</span>`;

  try {
    const res = await fetch(`${API_BASE}/orders`, {
      method: "POST",
      headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
      body: JSON.stringify({ service: GMAIL_SERVICE.id, quantity: 1 }),
    });
    const data = await res.json();
    if (!res.ok) throw new Error(data.message);

    user.balance = data.newBalance;
    localStorage.setItem("zafarm_user", JSON.stringify(user));
    renderBalance();
    await loadServices();
    await loadOrders();

    const mail = data.order?.items?.[0]?.mail || "";
    showToast(`✅ Gmail: ${mail} — រង់ចាំ OTP...`);
  } catch (err) {
    showToast(err.message || "Error", true);
  } finally {
    btn.disabled = false;
    btn.innerHTML = origHTML;
  }
}

/* ---------- Buy (modal open) ---------- */
function bindBuyButton() {
  const btnGmail = document.getElementById("buyGmailBtn");
  if (btnGmail) btnGmail.addEventListener("click", () => openModal(GMAIL_SERVICE));
  
  const btnPhoneUs = document.getElementById("buyPhoneUsBtn");
  if (btnPhoneUs) btnPhoneUs.addEventListener("click", () => openModal(PHONE_SERVICE_US));
  
  const btnPhoneKh = document.getElementById("buyPhoneKhBtn");
  if (btnPhoneKh) btnPhoneKh.addEventListener("click", () => openModal(PHONE_SERVICE_KH));
}

function openModal(service) {
  if (!token) {
    if (typeof showGuestAuthModal === "function") showGuestAuthModal();
    else window.location.href = "/login";
    return;
  }
  currentService = service;
  if (currentService.stock === 0) { showToast("Stock អស់ហើយ", true); return; }
  
  // Update modal text based on service
  const modalTop = document.querySelector(".modal-top");
  if (modalTop) {
    if (service.id === 'phone_sms_us') {
      modalTop.innerHTML = `<div class="modal-emoji">📱</div><h3>Phone SMS 🇺🇸</h3><p>លេខអាមេរិក (US) សម្រាប់ Facebook • 20 នាទី</p>`;
    } else if (service.id === 'phone_sms_kh') {
      modalTop.innerHTML = `<div class="modal-emoji">📱</div><h3>Phone SMS 🇰🇭</h3><p>លេខខ្មែរ (KH) សម្រាប់ Facebook • 20 នាទី</p>`;
    } else {
      modalTop.innerHTML = `<div class="modal-emoji">📧</div><h3>Gmail OTP</h3><p>Facebook Verification • 6 នាទី</p>`;
    }
  }

  document.getElementById("modalQty").value = 1;
  document.getElementById("modalQty").max = currentService.stock;
  updateTotal();
  document.getElementById("buyModal").classList.add("show");
}

function closeModal() {
  document.getElementById("buyModal").classList.remove("show");
}

function updateTotal() {
  const qty = Math.max(1, parseInt(document.getElementById("modalQty").value || "1", 10));
  const total = (qty * currentService.price).toFixed(3);
  document.getElementById("modalTotal").textContent = "$" + total;
  document.getElementById("modalPrice").textContent = "$" + currentService.price.toFixed(3);
}

function bindModal() {
  const closeBtn = document.getElementById("closeModal");
  const overlay = document.getElementById("buyModal");
  const qtyInput = document.getElementById("modalQty");
  const confirmBtn = document.getElementById("confirmBuy");
  const minusBtn = document.getElementById("qtyMinus");
  const plusBtn = document.getElementById("qtyPlus");

  if (!closeBtn) return;
  closeBtn.addEventListener("click", closeModal);
  overlay.addEventListener("click", (e) => { if (e.target === overlay) closeModal(); });
  qtyInput.addEventListener("input", updateTotal);
  confirmBtn.addEventListener("click", confirmBuy);

  if (minusBtn) minusBtn.addEventListener("click", () => {
    const input = document.getElementById("modalQty");
    input.value = Math.max(1, parseInt(input.value) - 1);
    updateTotal();
  });
  if (plusBtn) plusBtn.addEventListener("click", () => {
    const input = document.getElementById("modalQty");
    input.value = Math.min(currentService.stock, parseInt(input.value) + 1);
    updateTotal();
  });
}

async function confirmBuy() {
  const confirmBtn = document.getElementById("confirmBuy");
  if (confirmBtn.disabled) return;
  
  const qty = Math.max(1, parseInt(document.getElementById("modalQty").value || "1", 10));
  const total = parseFloat((qty * currentService.price).toFixed(3));

  // Check balance locally first
  if (!user || (user.balance || 0) < total) {
    const needed = total;
    closeModal();
    if (typeof openDirectKhqrModal === "function") {
      openDirectKhqrModal(needed, `ទិញ ${qty} ${currentService.title} ($${total.toFixed(2)})`, async () => {
        await executeDirectServiceBuy(currentService.id, qty);
      });
    } else {
      showToast("Balance មិនគ្រប់គ្រាន់ — ត្រូវការ $" + total.toFixed(3) + " សូមបញ្ចូលប្រាក់", true);
    }
    return;
  }
  await executeDirectServiceBuy(currentService.id, qty);
}

async function executeDirectServiceBuy(serviceId, qty) {
  const confirmBtn = document.getElementById("confirmBuy");
  let origHTML = "បញ្ជាក់ការទិញ / Confirm Buy";
  if (confirmBtn) {
    origHTML = confirmBtn.innerHTML;
    confirmBtn.disabled = true;
    confirmBtn.innerHTML = `<svg class="spinner" viewBox="0 0 50 50" style="width:20px;height:20px;animation:rotate 2s linear infinite;margin-right:8px;vertical-align:middle;"><circle class="path" cx="25" cy="25" r="20" fill="none" stroke="currentColor" stroke-width="5" stroke-linecap="round" style="animation:dash 1.5s ease-in-out infinite;"></circle></svg> កំពុងដំណើរការ...`;
  }
  try {
    const res = await fetch(`${API_BASE}/orders`, {
      method: "POST",
      headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
      body: JSON.stringify({ service: serviceId, quantity: qty }),
    });
    const data = await res.json();
    if (!res.ok) throw new Error(data.message);

    user = JSON.parse(localStorage.getItem("zafarm_user") || '{}');
    if (data.newBalance !== undefined) {
      user.balance = data.newBalance;
      localStorage.setItem("zafarm_user", JSON.stringify(user));
    }
    closeModal();
    renderBalance();
    await loadServices();
    await loadOrders();
    showToast(`បានទិញជោគជ័យ ✅`);
  } catch (err) {
    showToast(err.message || "Error", true);
  } finally {
    if (confirmBtn) {
      confirmBtn.disabled = false;
      confirmBtn.innerHTML = origHTML;
    }
  }
}

function demoBuy(qty) {
  const total = parseFloat((qty * GMAIL_SERVICE.price).toFixed(3));
  if (!user) user = { balance: 5 };
  if (user.balance < total) { showToast("Balance មិនគ្រប់គ្រាន់ — ត្រូវការ $" + total.toFixed(3), true); return; }

  user.balance = parseFloat((user.balance - total).toFixed(3));
  localStorage.setItem("zafarm_user", JSON.stringify(user));

  const order = {
    id: Date.now(),
    service: GMAIL_SERVICE.id,
    qty, total,
    items: [{ mail: Math.random().toString(36).slice(2, 12) + "@gmail.com" }],
    status: "success",
    otp: "—",
    createdAt: new Date().toISOString(),
  };
  orders.unshift(order);
  localStorage.setItem("zafarm_orders", JSON.stringify(orders));

  closeModal();
  renderBalance();
  updateStockDisplay();
  renderOrders();
  renderStats();
  showToast(`បានទិញ ${qty} Gmail OTP ✅`);
}

/* ---------- Refresh ---------- */
function bindRefresh() {
  const btn = document.getElementById("refreshOrders");
  if (btn) btn.addEventListener("click", async () => {
    await loadOrders();
    showToast("Refreshed ✅");
  });
}

/* ---------- Logout ---------- */
function bindLogout() {
  const btn = document.getElementById("logoutBtn");
  if (btn) {
    btn.addEventListener("click", (e) => {
      e.preventDefault();
      localStorage.removeItem("zafarm_token");
      localStorage.removeItem("zafarm_user");
      window.location.href = "/login";
    });
  }
}


/* ---------- Toast ---------- */
function showToast(msg, isError = false) {
  const t = document.getElementById("toast");
  if (!t) return;
  // 🛡️ Use textContent to prevent XSS in toast messages
  t.textContent = msg;
  t.style.borderColor = isError ? "var(--red)" : "var(--primary)";
  t.classList.add("show");
  setTimeout(() => t.classList.remove("show"), 2500);
}

/* ---------- Online Count ---------- */
async function loadOnlineCount() {
  try {
    const res = await fetch(`${API_BASE}/online-count`);
    if (res.ok) {
      const data = await res.json();
      const el = document.getElementById("onlineCount");
      if (el) el.textContent = data.count;
    }
  } catch {}
  setTimeout(loadOnlineCount, 10000);
}
