import { historyMoreUrl } from "../bd-static/shared.js"; const API_BASE_URL = "https://jvapi.haiyihy.com"; const labels = { en: { bd_leader_center: "BD Leader Center", my_available_salary: "My available salary", my_salary_link: "Details", bd_policy_link: "BD policy", agency_list_link: "Agency list", bd_list_link: "BD List", invite_become_agent: "Invite to become agent", invite_become_BD: "Invite to become BD", bank_cards_link: "Bank cards", send_welcome_gift: "Send welcome gift", bd_salary: "BD salary", bd_leader_history: "BD Leader history", total_income: "Total income", previous_period_income: "Previous period income", agency_number: "Agency number", bd_number: "BD number", team_salary: "Team salary", team_top_up: "Team top up", bd_income_salary: "BD income salary", bd_income_top_up: "BD income top up", user_id_prefix: "ID: ", salary: "Salary", recharge: "Recharge", host: "Host", agencies: "Agencies", total_team_salary: "Total team salary", more: "More", in_progress: "In Progress", pending: "Pending", completed: "Completed", out_of_account: "Out of account", failed_to_load_balance: "Failed to load balance. Please try again.", failed_to_load_history: "Failed to load history. Please try again.", request_not_available: "Request failed. Please try again." }, ar: {}, tr: {}, bn: {} }; ["ar", "tr", "bn"].forEach((lang) => { labels[lang] = { ...labels.en }; }); let commonHeaders = { authorization: "Bearer undefined", "req-app-intel": "version=1.0.0;build=1;model=SM-G9550;sysVersion=9;channel=Google", "req-client": "Android", "req-imei": "8fa54d728ab449e04f9292329ed44bda", "req-lang": "id-ID", "req-sys-origin": "origin=ATYOU;originChild=ATYOU", "req-version": "V2", "req-zone": "Asia/Shanghai" }; const state = { lang: resolveLanguage(), balanceTotal: {}, userInfo: null, teamInfo: null, identityInfo: null, identity: "BD_LEADER", modalMode: "", historyType: "bd", bdHistory: {}, bdLeaderHistory: {}, historyMore: {} }; function resolveLanguage() { const params = new URLSearchParams(window.location.search); const hashQuery = window.location.hash.includes("?") ? window.location.hash.split("?")[1] : ""; const hashParams = new URLSearchParams(hashQuery); const lang = params.get("lang") || hashParams.get("lang") || navigator.language || "en"; if (lang.startsWith("ar")) return "ar"; if (lang.startsWith("tr")) return "tr"; if (lang.startsWith("bn")) return "bn"; return "en"; } function t(key) { return labels[state.lang]?.[key] || labels.en[key] || key; } function setLanguage() { document.documentElement.lang = state.lang; document.documentElement.dir = state.lang === "ar" ? "rtl" : "ltr"; document.querySelector("[data-action='language']").textContent = state.lang.toUpperCase(); document.querySelectorAll("[data-i18n]").forEach((node) => { node.textContent = t(node.dataset.i18n); }); } function setIcons() { const icon = (body) => `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(` ${body} `)}`; const iconMap = { policy: icon(` `), bank: icon(` `), gift: icon(` `), invite: icon(` `), arrow: icon(` `), salary: icon(` `) }; document.querySelectorAll("[data-icon]").forEach((img) => { img.src = iconMap[img.dataset.icon] || ""; }); } function splitHeaderPairs(value) { const result = {}; if (!value) return result; value.split(";").forEach((item) => { const index = item.indexOf("="); if (index > -1) result[item.slice(0, index)] = item.slice(index + 1); }); return result; } function parseAccessOrigin(raw) { const data = JSON.parse(raw); const appIntel = splitHeaderPairs(data["Req-App-Intel"]); const sysOrigin = splitHeaderPairs(data["Req-Sys-Origin"]); return { reqLang: data["Req-Lang"], authorization: data.Authorization, buildVersion: appIntel.build, appVersion: appIntel.version, appChannel: appIntel.channel, reqImei: appIntel["Req-Imei"], sysOrigin: sysOrigin.origin, sysOriginChild: sysOrigin.child }; } function setHeadersFromApp(headers) { const next = {}; if (headers.authorization) next.authorization = headers.authorization; if (headers.reqLang) next["req-lang"] = headers.reqLang; if (headers.appVersion || headers.buildVersion || headers.appChannel) { const intel = []; if (headers.appVersion) intel.push(`version=${headers.appVersion}`); if (headers.buildVersion) intel.push(`build=${headers.buildVersion}`); if (headers.appChannel) intel.push(`channel=${headers.appChannel}`); next["req-app-intel"] = intel.join(";"); } if (headers.reqImei) next["req-imei"] = headers.reqImei; if (headers.sysOrigin) { const origin = [`origin=${headers.sysOrigin}`]; if (headers.sysOriginChild) origin.push(`child=${headers.sysOriginChild}`); next["req-sys-origin"] = origin.join(";"); } commonHeaders = { ...commonHeaders, ...next }; } function isMobileDevice() { return /Android|iPad|iPhone|iPod/.test(navigator.userAgent); } function isAppEnvironment() { return Boolean(window.app || window.webkit || window.FlutterPageControl || window.FlutterApp); } function requestAccessOrigin() { return new Promise((resolve) => { window.renderData = resolve; window.getIosAccessOriginParam = resolve; if (!isAppEnvironment()) { setHeadersFromApp({ authorization: "", reqLang: state.lang, appVersion: "1.0.0", buildVersion: "1", appChannel: "Web", reqImei: "H5-STATIC", sysOrigin: "LIKEI", sysOriginChild: "LIKEI" }); resolve(null); return; } let attempt = 0; const poll = () => { attempt += 1; if (window.app && typeof window.app.getAccessOrigin === "function") { resolve(window.app.getAccessOrigin()); return; } if (attempt < 50) { window.setTimeout(poll, 100); return; } if (window.FlutterApp && typeof window.FlutterApp.postMessage === "function") { window.FlutterApp.postMessage("requestAccessOrigin"); } }; if (isMobileDevice() || isAppEnvironment()) { poll(); } else { resolve(null); } }); } async function connectToApp() { const raw = await requestAccessOrigin(); if (!raw) return { success: true, environment: "browser" }; setHeadersFromApp(parseAccessOrigin(raw)); return { success: true, environment: "app" }; } async function apiGet(path) { const response = await fetch(`${API_BASE_URL}${path}`, { method: "GET", headers: commonHeaders }); const data = await response.json().catch(() => ({})); if (!response.ok || data.status === false) { const error = new Error(data.errorMsg || data.message || `Request failed: ${response.status}`); error.response = data; throw error; } return data; } async function fetchUserProfile() { const result = await apiGet("/team/member/profile"); if (result.status && result.body) state.userInfo = result.body; } async function fetchTeamInfo() { try { const result = await apiGet("/team/entry"); if (result.status && result.body) state.teamInfo = result.body.teamProfile || result.body; } catch (error) { state.teamInfo = null; console.debug("BD leader team info unavailable:", error); } } async function fetchIdentity() { const result = await apiGet("/app/h5/identity"); if (result.status && result.body) state.identityInfo = result.body; } async function fetchBalanceTotal() { const result = await apiGet("/wallet/salary-account/balance/total"); if (result.status && result.body) state.balanceTotal = result.body || {}; } async function fetchBDHistoryMore(billBelong) { const endpoint = historyMoreUrl("/team/bd/history/more", billBelong); if (!endpoint) throw new Error(t("request_not_available")); const result = await apiGet(endpoint); if (result.status && result.body) state.historyMore = result.body || {}; } async function fetchBDLeaderHistoryMore(billBelong) { const endpoint = historyMoreUrl("/team/bd/leader/history/more", billBelong); if (!endpoint) throw new Error(t("request_not_available")); const result = await apiGet(endpoint); if (result.status && result.body) state.historyMore = result.body || {}; } function setIdentity(identity) { state.identity = identity; localStorage.setItem("identity", JSON.stringify({ identity })); } function clearPayee() { try { sessionStorage.removeItem("payee"); localStorage.removeItem("payee"); } catch (error) { console.debug("Payee cache clear skipped:", error); } } function formatMoney(value) { if (value === null || value === undefined || value === "") return "0"; const number = Number(value); if (Number.isNaN(number)) return String(value); return Number.isInteger(number) ? String(number) : number.toFixed(2); } function normalizeStatus(status) { if (status === "UNPAID" || status === "In Progress" || status === t("in_progress")) return t("in_progress"); if (status === "Pending" || status === t("pending")) return t("pending"); if (status === "SETTLED" || status === "PAY_OUT" || status === "Completed" || status === t("completed")) return t("completed"); if (status === "HANG_UP" || status === "Out of account" || status === "Out Of Account" || status === t("out_of_account")) return t("out_of_account"); return status || ""; } function statusClass(status) { const value = normalizeStatus(status); if (value === t("completed")) return "is-completed"; if (value === t("pending")) return "is-pending"; if (value === t("out_of_account")) return "is-out"; return "is-progress"; } function navigateTo(target) { const url = new URL(target, window.location.origin); const currentLang = new URLSearchParams(window.location.search).get("lang"); if (currentLang && !url.searchParams.has("lang")) url.searchParams.set("lang", currentLang); window.location.href = `${url.pathname}${url.search}${url.hash}`; } function closePage() { if (window.history.length > 1) { window.history.back(); return; } if (window.app && typeof window.app.closePage === "function") { window.app.closePage(); return; } if (window.FlutterPageControl && typeof window.FlutterPageControl.postMessage === "function") { window.FlutterPageControl.postMessage("close_page"); } } function renderBalance() { document.getElementById("availableBalance").textContent = `$${formatMoney(state.balanceTotal.availableBalance || 0)}`; } function historySource() { return state.historyType === "bd" ? state.bdHistory : state.bdLeaderHistory; } function historyTitle() { return state.historyType === "bd" ? t("bd_salary") : t("bd_leader_history"); } function renderHistorySheet() { const data = historySource(); document.getElementById("historyTitle").textContent = historyTitle(); document.getElementById("historyTotalIncome").textContent = formatMoney(data.totalIncome || 0); document.getElementById("historyPreviousIncome").textContent = formatMoney(data.previousPeriodIncome || 0); const list = document.getElementById("historyList"); list.innerHTML = ""; const items = data.incomeDetails || []; items.forEach((item) => list.appendChild(createHistoryItem(item))); } function createHistoryItem(item) { const card = document.createElement("article"); card.className = `salary-item ${statusClass(item.statusText)}`; const status = document.createElement("div"); status.className = "status-background"; status.textContent = normalizeStatus(item.statusText); card.appendChild(status); const content = document.createElement("div"); content.className = "salary-item-content"; if (state.historyType === "bd") { content.append( textLine(item.billTitle || ""), textLine(`${t("agency_number")}: ${item.agencyNumber || 0}`), pairLine(`${t("team_salary")}: $${item.teamSalaryAmount || 0}`, `${t("bd_income_salary")}: $${item.bdIncomeSalary || item.settlementSalary || 0} (${item.bdRatioSalary || item.commissionRate || 0}%)`), pairLine(`${t("team_top_up")}: $${item.teamRechargeAmount || 0}`, `${t("bd_income_top_up")}: $${item.bdIncomeRecharge || item.settlementSalary || 0} (${item.bdRatioRecharge || item.commissionRate || 0}%)`) ); } else { content.append( textLine(item.billTitle || ""), pairLine(`${t("bd_number")}: ${item.bdNumber || 0}`, `${t("team_salary")}: $${item.teamSalaryAmount || 0}`) ); } card.appendChild(content); if (normalizeStatus(item.statusText) === t("completed")) { const more = document.createElement("button"); more.type = "button"; more.className = "more-bt"; more.textContent = t("more"); more.addEventListener("click", () => showHistoryMore(item.billBelong)); card.appendChild(more); } return card; } function textLine(text) { const node = document.createElement("div"); node.textContent = text; return node; } function pairLine(left, right) { const node = document.createElement("div"); node.className = "pair-line"; const leftNode = document.createElement("div"); const rightNode = document.createElement("div"); leftNode.textContent = left; rightNode.textContent = right; node.append(leftNode, rightNode); return node; } async function showHistoryMore(billBelong) { try { if (state.historyType === "bd") { await fetchBDHistoryMore(billBelong); } else { await fetchBDLeaderHistoryMore(billBelong); } state.modalMode = "details"; renderModal(); } catch (error) { console.warn("BD leader history more failed:", error); showToast(error.response?.errorMsg || error.message || t("failed_to_load_history")); } } function renderDetailsSheet() { const data = state.historyMore || {}; document.getElementById("detailsPeriod").textContent = data.period || ""; const summary = document.getElementById("detailsSummary"); summary.innerHTML = ""; if (state.historyType === "bd") { summary.append( textLine(`${t("team_top_up")}: $${data.teamTotalRecharge || 0}`), textLine(`${t("total_team_salary")}: $${data.teamTotalSalary || 0}`) ); } else { summary.append( textLine(`${t("team_salary")}: $${data.teamSalary || 0}`), textLine(`${t("bd_number")}: ${data.bdNumber || 0}`) ); } const list = document.getElementById("memberDetails"); list.innerHTML = ""; (data.memberDetails || []).forEach((item) => { const card = document.createElement("article"); card.className = "member-item"; const img = document.createElement("img"); img.src = state.historyType === "bd" ? item.userAvatar || "" : item.bdUserAvatar || ""; img.alt = ""; img.addEventListener("error", () => { img.removeAttribute("src"); }); const info = document.createElement("div"); info.className = "member-info"; info.append( textLine(state.historyType === "bd" ? item.userName || "" : item.bdUserName || ""), textLine(`${t("user_id_prefix")}${item.account || ""}`) ); const metrics = document.createElement("div"); metrics.className = "member-metrics"; metrics.append(textLine(`${t("salary")}: $${item.salary || 0}`)); if (state.historyType === "bd") { metrics.append(textLine(`${t("recharge")}: $${item.recharge || 0}`), textLine(`${t("host")}: ${item.hostCount || 0}`)); } else { metrics.append(textLine(`${t("agencies")}: ${item.agencyCount || 0}`)); } card.append(img, info, metrics); list.appendChild(card); }); } function renderModal() { const mask = document.getElementById("maskLayer"); const history = document.getElementById("historySheet"); const details = document.getElementById("detailsSheet"); const showHistory = state.modalMode === "history"; const showDetails = state.modalMode === "details"; mask.hidden = !showHistory && !showDetails; history.hidden = !showHistory; details.hidden = !showDetails; if (showHistory) renderHistorySheet(); if (showDetails) renderDetailsSheet(); } function closeModal() { state.modalMode = ""; state.historyMore = {}; renderModal(); } function showToast(message) { const toast = document.getElementById("toast"); toast.textContent = message; toast.hidden = false; window.clearTimeout(showToast.timer); showToast.timer = window.setTimeout(() => { toast.hidden = true; }, 2500); } function bindEvents() { document.querySelector("[data-action='back']").addEventListener("click", closePage); document.querySelector("[data-action='language']").addEventListener("click", () => navigateTo("/language")); document.querySelectorAll("[data-route]").forEach((node) => { node.addEventListener("click", () => navigateTo(node.dataset.route)); }); document.querySelector("[data-action='sendGift']").addEventListener("click", () => navigateTo("/bd-item-distribution")); document.querySelector("[data-action='closeModal']").addEventListener("click", closeModal); } async function initializePageData() { const tasks = [fetchUserProfile(), fetchTeamInfo(), fetchIdentity()]; await Promise.allSettled(tasks); } async function init() { setLanguage(); setIcons(); bindEvents(); renderBalance(); clearPayee(); setIdentity("BD_LEADER"); try { await connectToApp(); await initializePageData(); await fetchBalanceTotal(); } catch (error) { console.warn("BD leader center initialization failed:", error); showToast(error.response?.errorMsg || error.message || t("failed_to_load_balance")); } finally { renderBalance(); } } init();