// 金币银行弹窗业务模块，替代 toolbar 中的银行内联脚本。

import { escapeHtml } from "./html.js";

// 排行榜页码、排序与绑定标记需要跨打开/关闭弹窗保持一致。
let bankRankPage = 1;
let bankRankSort = "desc";
let bankModalEventsBound = false;

/**
 * 获取 CSRF Token。
 *
 * @returns {string}
 */
function csrf() {
    return document.querySelector('meta[name="csrf-token"]')?.content ?? "";
}

/**
 * 设置元素显示状态。
 *
 * @param {string} id 元素 ID
 * @param {string} display CSS display 值
 * @returns {void}
 */
function setDisplay(id, display) {
    const element = document.getElementById(id);
    if (element) {
        element.style.display = display;
    }
}

/**
 * 切换银行弹窗 Tab，并在首次进入排行榜时加载数据。
 *
 * @param {string} tabName Tab 名称
 * @returns {void}
 */
export function switchBankTab(tabName) {
    document.getElementById("bank-tabbtn-account")?.classList.remove("active");
    document.getElementById("bank-tabbtn-ranking")?.classList.remove("active");
    setDisplay("bank-view-account", "none");
    setDisplay("bank-view-ranking", "none");

    document.getElementById(`bank-tabbtn-${tabName}`)?.classList.add("active");
    setDisplay(`bank-view-${tabName}`, "flex");

    const rankingList = document.getElementById("bank-ranking-list");
    if (tabName === "ranking" && bankRankPage === 1 && rankingList?.innerHTML.includes("加载中")) {
        void fetchBankRanking(1);
    }
}

/**
 * 打开银行弹窗并刷新账户资金信息。
 *
 * @returns {void}
 */
export function openBankModal() {
    setDisplay("bank-modal", "flex");
    switchBankTab("account");
    void bankLoadInfo();
}

/**
 * 关闭银行弹窗。
 *
 * @returns {void}
 */
export function closeBankModal() {
    setDisplay("bank-modal", "none");
}

/**
 * 执行存款或取款操作。
 *
 * @param {"deposit"|"withdraw"|string} type 操作类型
 * @returns {Promise<void>}
 */
export async function bankAction(type) {
    if (!["deposit", "withdraw"].includes(type)) {
        return;
    }

    const inputEl = document.getElementById(`bank-${type}-input`);
    const btnEl = document.getElementById(`bank-${type}-btn`);
    if (!(inputEl instanceof HTMLInputElement) || !(btnEl instanceof HTMLButtonElement)) {
        return;
    }

    const amount = Number.parseInt(inputEl.value, 10);
    if (!amount || amount <= 0) {
        bankShowMsg("请输入有效的金额", false);
        return;
    }

    // 提交期间禁用按钮，避免连续点击重复发起同一笔存取款请求。
    btnEl.disabled = true;
    try {
        const response = await fetch(`/bank/${type}`, {
            method: "POST",
            headers: {
                "X-CSRF-TOKEN": csrf(),
                "Content-Type": "application/json",
                Accept: "application/json",
            },
            body: JSON.stringify({ amount }),
        });
        const data = await response.json();
        bankShowMsg(data.message, data.status === "success");

        if (data.status === "success") {
            inputEl.value = "";
            await bankLoadInfo();

            // 如果用户正停留在排行榜页，存取款成功后同步刷新当前页余额排名。
            if (document.getElementById("bank-view-ranking")?.style.display !== "none") {
                await fetchBankRanking(bankRankPage);
            }
        }
    } catch (error) {
        bankShowMsg("网络异常，请稍后重试", false);
    }

    btnEl.disabled = false;
}

/**
 * 获取当前用户资金与最近流水，并同步 chatContext 金币缓存。
 *
 * @returns {Promise<void>}
 */
export async function bankLoadInfo() {
    try {
        const response = await fetch("/bank", {
            headers: {
                Accept: "application/json",
            },
        });
        const data = await response.json();
        if (data.status !== "success") {
            return;
        }

        const cashDisplay = document.getElementById("bank-jjb-display");
        const bankDisplay = document.getElementById("bank-bank-display");
        if (cashDisplay) {
            cashDisplay.textContent = Number(data.jjb || 0).toLocaleString();
        }
        if (bankDisplay) {
            bankDisplay.textContent = Number(data.bank_jjb || 0).toLocaleString();
        }

        if (window.chatContext) {
            // 同步全局金币缓存，供聊天室其他金币展示或后续购买逻辑读取最新余额。
            window.chatContext.myGold = data.jjb;
            window.chatContext.bankGold = data.bank_jjb;
        }

        renderBankLogs(Array.isArray(data.logs) ? data.logs : []);
    } catch (error) {
        const list = document.getElementById("bank-logs-list");
        if (list) {
            list.innerHTML = '<div style="text-align:center;color:#ef4444;font-size:12px;padding:30px 0;">加载失败</div>';
        }
    }
}

/**
 * 渲染最近资金流水。
 *
 * @param {Array<Record<string, unknown>>} logs 流水记录
 * @returns {void}
 */
function renderBankLogs(logs) {
    const list = document.getElementById("bank-logs-list");
    if (!list) {
        return;
    }

    if (logs.length === 0) {
        list.innerHTML = '<div style="text-align:center;color:#9db3d4;font-size:12px;padding:30px 0;">暂无记录</div>';
        return;
    }

    list.innerHTML = logs.map((log) => {
        const isDeposit = log.type === "deposit";
        const className = isDeposit ? "bank-log-deposit" : "bank-log-withdraw";
        const sign = isDeposit ? "+ 存入" : "- 取出";
        const createdAt = String(log.created_at || "").replace("T", " ").substring(0, 16);

        return `<div class="bank-log-item">
            <span class="${className}">${sign} ${Number(log.amount || 0).toLocaleString()} 金币</span>
            <span style="color:#64748b;">余额: <strong style="color:#334155">${Number(log.balance_after || 0).toLocaleString()}</strong></span>
            <span style="color:#94a3b8;">${escapeHtml(createdAt)}</span>
        </div>`;
    }).join("");
}

/**
 * 显示银行操作结果提示。
 *
 * @param {string} message 提示内容
 * @param {boolean} success 是否成功
 * @returns {void}
 */
export function bankShowMsg(message, success) {
    const element = document.getElementById("bank-op-msg");
    if (!element) {
        return;
    }

    element.textContent = message;
    element.style.background = success ? "#f0fdf4" : "#fef2f2";
    element.style.border = success ? "1px solid #bbf7d0" : "1px solid #fecaca";
    element.style.color = success ? "#16a34a" : "#ef4444";
    element.style.display = "block";
    // 连续存取款时清理上一次隐藏任务，避免旧 timer 把新提示提前隐藏。
    clearTimeout(element._t);
    element._t = setTimeout(() => {
        element.style.display = "none";
    }, 3000);
}

/**
 * 切换排行榜排序并回到第一页。
 *
 * @returns {void}
 */
export function toggleBankRankSort() {
    bankRankSort = bankRankSort === "desc" ? "asc" : "desc";

    const button = document.getElementById("bank-rank-sort-btn");
    if (button) {
        button.textContent = bankRankSort === "desc" ? "降序 ↓" : "升序 ↑";
    }

    void fetchBankRanking(1);
}

/**
 * 拉取并渲染存款排行榜。
 *
 * @param {number} page 页码
 * @returns {Promise<void>}
 */
export async function fetchBankRanking(page) {
    if (page < 1) {
        return;
    }

    const listEl = document.getElementById("bank-ranking-list");
    if (!listEl) {
        return;
    }

    listEl.innerHTML = '<div style="text-align:center; color:#9db3d4; font-size:12px; padding:30px 0;">加载中...</div>';

    try {
        const response = await fetch(`/bank/ranking?page=${page}&sort=${bankRankSort}`, {
            headers: {
                Accept: "application/json",
            },
        });
        const data = await response.json();

        if (data.status !== "success") {
            return;
        }

        bankRankPage = data.pagination.current_page;
        const pageInfo = document.getElementById("bank-rank-page-info");
        if (pageInfo) {
            pageInfo.textContent = `${bankRankPage} / ${data.pagination.last_page}`;
        }
        syncRankingButtons(data.pagination.last_page);

        if (!Array.isArray(data.ranking) || data.ranking.length === 0) {
            listEl.innerHTML = '<div style="text-align:center; color:#9db3d4; font-size:12px; padding:30px 0;">暂无数据</div>';
            return;
        }

        listEl.innerHTML = data.ranking.map((user, index) => renderRankingRow(user, index)).join("");
    } catch (error) {
        listEl.innerHTML = '<div style="text-align:center; color:#ef4444; font-size:12px; padding:30px 0;">拉取失败</div>';
    }
}

/**
 * 同步排行榜分页按钮状态。
 *
 * @param {number} lastPage 最后一页页码
 * @returns {void}
 */
function syncRankingButtons(lastPage) {
    const prevButton = document.getElementById("bank-rank-prev");
    const nextButton = document.getElementById("bank-rank-next");
    if (!(prevButton instanceof HTMLButtonElement) || !(nextButton instanceof HTMLButtonElement)) {
        return;
    }

    prevButton.disabled = bankRankPage <= 1;
    prevButton.style.opacity = bankRankPage <= 1 ? "0.5" : "1";
    nextButton.disabled = bankRankPage >= lastPage;
    nextButton.style.opacity = bankRankPage >= lastPage ? "0.5" : "1";
}

/**
 * 渲染排行榜单行；前三名样式只在降序第一页生效。
 *
 * @param {Record<string, unknown>} user 用户排行数据
 * @param {number} index 当前页索引
 * @returns {string}
 */
function renderRankingRow(user, index) {
    // 排行榜接口每页 20 条，这里用当前页和页内索引还原全局名次。
    const absoluteRank = (bankRankPage - 1) * 20 + index + 1;
    let rankClass = "";
    if (bankRankSort === "desc" && bankRankPage === 1) {
        if (absoluteRank === 1) {
            rankClass = "bank-rank-top1";
        } else if (absoluteRank === 2) {
            rankClass = "bank-rank-top2";
        } else if (absoluteRank === 3) {
            rankClass = "bank-rank-top3";
        }
    }

    const avatarUrl = escapeHtml(resolveSafeBankAvatarUrl(user.headfaceUrl));
    const username = escapeHtml(user.username || "");
    const sexSymbol = user.sex === "女" ? "♀" : "♂";

    return `<div class="bank-rank-item">
        <div class="bank-rank-num ${rankClass}">${absoluteRank}</div>
        <img src="${avatarUrl}" onerror="this.src='/images/headface/1.gif'" style="width:32px; height:32px; border-radius:50%; object-fit:cover; border:1px solid #d0e4f5;">
        <div>
            <div style="font-weight:bold; color:#1e3a8a;">${username} <span style="font-size:12px;">${sexSymbol}</span></div>
        </div>
        <div class="bank-rank-val">
            🏦 ${Number(user.bank_jjb || 0).toLocaleString()}
        </div>
    </div>`;
}

/**
 * 规整排行榜头像地址，避免任意 URL 直接进入 img src。
 *
 * @param {unknown} value 头像地址
 * @returns {string}
 */
function resolveSafeBankAvatarUrl(value) {
    const url = String(value || "");

    if (url.startsWith("/images/headface/") || url.startsWith("/storage/")) {
        return url;
    }

    return "/images/headface/1.gif";
}

/**
 * 从分页文本中解析当前页码。
 *
 * @returns {number}
 */
function resolveCurrentRankPage() {
    const pageInfo = document.getElementById("bank-rank-page-info")?.textContent || "1 / 1";
    const currentPage = Number.parseInt(pageInfo.split("/")[0]?.trim() || "1", 10);

    return Number.isInteger(currentPage) && currentPage > 0 ? currentPage : 1;
}

/**
 * 绑定银行弹窗按钮和遮罩关闭事件。
 *
 * @returns {void}
 */
export function bindBankControls() {
    if (bankModalEventsBound || typeof document === "undefined") {
        return;
    }

    bankModalEventsBound = true;
    document.addEventListener("click", (event) => {
        if (!(event.target instanceof Element)) {
            return;
        }

        const tabButton = event.target.closest("[data-bank-tab]");
        if (tabButton) {
            event.preventDefault();
            switchBankTab(tabButton.getAttribute("data-bank-tab") || "");
            return;
        }

        if (event.target.closest("[data-bank-modal-close]")) {
            event.preventDefault();
            closeBankModal();
            return;
        }

        const actionButton = event.target.closest("[data-bank-action]");
        if (actionButton) {
            event.preventDefault();
            void bankAction(actionButton.getAttribute("data-bank-action") || "");
            return;
        }

        if (event.target.closest("[data-bank-rank-sort]")) {
            event.preventDefault();
            toggleBankRankSort();
            return;
        }

        const pageButton = event.target.closest("[data-bank-rank-page-delta]");
        if (pageButton) {
            event.preventDefault();
            const delta = Number.parseInt(pageButton.getAttribute("data-bank-rank-page-delta") || "0", 10);
            void fetchBankRanking(resolveCurrentRankPage() + delta);
            return;
        }

        const modal = event.target.closest("#bank-modal");
        // 点击遮罩关闭，只响应最外层背景，避免内容区误关。
        if (modal && event.target === modal) {
            closeBankModal();
        }
    });
}
