<script lang="ts">
export default {
    name: "withdrawals",
};
</script>

<script setup lang="ts">
import { onMounted, reactive, ref, toRefs } from "vue";
import { ElForm, ElTable, ElMessage } from "element-plus";
import { Search, Refresh, ArrowUp, ArrowDown } from "@element-plus/icons-vue";
import { ethers } from "ethers";
import { TronWeb } from "tronweb";
import router from "@/router";
import { withdrawManage, auditNoPass, chainApply, chainCallback } from "@/api/finance";
import {
    WithDrawalsQueryParam,
    WithDrawalsItem,
} from "@/types/api/finance";

const ERC20_ABI = [{
    name: "transfer", type: "function", stateMutability: "nonpayable",
    inputs: [
        { name: "recipient", type: "address" },
        { name: "amount",    type: "uint256" },
    ],
    outputs: [{ name: "", type: "bool" }],
}];

const GAS_WALLET_KEY = import.meta.env.VITE_WITHDRAW_GAS_KEY || "";

const queryFormRef = ref(ElForm);
const dataTableRef = ref(ElTable);

const state = reactive({
    loading: true,
    ids: [] as number[],
    single: true,
    multiple: true,
    searchBox: {
        title: "展开搜索",
        expand: false,
    },
    queryParams: {
        pageNo: 1,
        pageSize: 15,
        account: "",
        memberId: "",
        address: "",
        unit: "",
        orderSn: "",
        isAuto: "",
        status: "",
    } as WithDrawalsQueryParam,
    list: [] as WithDrawalsItem[],
    total: 0,

    // 单条链上放币弹窗
    chainVisible: false,
    chainLoading: false,
    chainStep: 0,
    chainMsg: "",
    chainRow: null as WithDrawalsItem | null,

    // 批量链上放币弹窗
    batchVisible: false,
    batchLoading: false,
    batchStep: 0,
    batchMsg: "",
    batchCurrent: 0,
    batchTotal: 0,
    batchResults: [] as { id: number; success: boolean; msg: string }[],
});

const {
    loading,
    searchBox,
    queryParams,
    list,
    total,
    chainVisible,
    chainLoading,
    chainStep,
    chainMsg,
    batchVisible,
    batchLoading,
    batchStep,
    batchMsg,
    batchCurrent,
    batchTotal,
    batchResults,
} = toRefs(state);

function handleQuery() {
    state.loading = true;
    withdrawManage(state.queryParams).then(({ data }) => {
        state.list = data.content;
        state.total = data.totalElements;
        state.loading = false;
    });
}

function resetQuery() {
    queryFormRef.value.resetFields();
    handleQuery();
}

function handleSelectionChange(selection: any) {
    state.ids = selection.map((item: any) => item.id);
    state.single = selection.length !== 1;
    state.multiple = !selection.length;
}

function handleSortChange(column: any) {
    var sortingType = column.order;
    state.queryParams.property = column.prop;
    if (sortingType === "ascending") {
        state.queryParams.direction = "1";
    } else if (sortingType === "descending") {
        state.queryParams.direction = "0";
    } else {
        state.queryParams.property = null;
        state.queryParams.direction = null;
    }
    handleQuery();
}

const selectedUnPassAll = () => {
    if (state.ids.length === 0) {
        ElMessage.error("尚未选取项目");
    } else {
        const ids = [state.ids].join(",");
        auditNoPass({ ids: ids }).then((res: any) => {
            if (!res.code) {
                ElMessage.success(res.message);
                handleQuery();
            } else {
                ElMessage.error(res.message);
            }
        });
    }
};

const viewCheck = (row: any) => {
    router.push({ path: "financeauditdetail", query: { id: row.id } });
};

const selectEnable = (row: any, index: number) => {
    return row.status == 1;
};

const closeSearch = () => {
    state.searchBox.expand = !state.searchBox.expand;
    state.searchBox.title = !state.searchBox.expand ? "展开搜索" : "收起搜索";
};

/** 执行单条链上放币的核心逻辑（供单条和批量复用） */
async function doChainWithdraw(
    rowId: number,
    onStep: (step: number, msg: string) => void
): Promise<string> {
    onStep(1, "正在准备链上转账...");
    const applyRes: any = await chainApply(rowId);
    const d = applyRes.data?.data ?? applyRes.data;
    const { toAddress, amount, decimals, contractAddress, rpcUrl, withdrawRecordId, chainType, signKey } = d;
    const gasKey = signKey || GAS_WALLET_KEY;

    // 金额转最小单位
    const [intPart, fracPart = ''] = amount.split('.');
    let rawAmount = intPart + fracPart.padEnd(decimals, '0').slice(0, decimals);
    rawAmount = rawAmount.replace(/^0+/, '') || '0';

    // ─── TRON / TRC20 转账 ───
    if (chainType === 'TRON') {
        onStep(2, "正在检查 TRON 钱包余额...");
        const tronWeb = new TronWeb({ fullHost: rpcUrl, privateKey: gasKey });
        const tronAddr = tronWeb.defaultAddress.base58;
        const trxBalance = await tronWeb.trx.getBalance(tronAddr);
        const trxAmount = Number(trxBalance) / 1_000_000;

        if (trxAmount < 10) {
            throw new Error(`TRON钱包余额不足\n地址: ${tronAddr}\n余额: ${trxAmount} TRX\n需充值至少 10 TRX`);
        }
        onStep(2, `TRON钱包: ${tronAddr}\n余额: ${trxAmount} TRX\n转出: ${amount} USDT\n正在提交交易...`);

        const trc20 = await tronWeb.contract().at(contractAddress);
        const txId = await trc20.transfer(toAddress, rawAmount).send({
            feeLimit: 30_000_000,
        });
        onStep(2, `交易已发送，等待确认...\ntxHash: ${txId}`);

        onStep(3, "交易已确认，正在通知后端...");
        await chainCallback(Number(withdrawRecordId ?? rowId), txId);
        return txId;
    }

    // ─── EVM / ERC20 / BEP20 转账 ───
    onStep(2, "正在检查 Gas 钱包余额...");
    const provider = new ethers.providers.JsonRpcProvider(
        rpcUrl || import.meta.env.VITE_BSC_RPC_URL || "https://bsc-dataseed.binance.org"
    );
    const wallet = new ethers.Wallet(gasKey, provider);

    const balance = await provider.getBalance(wallet.address);
    const balanceBNB = ethers.utils.formatEther(balance);
    if (balance.lt(ethers.utils.parseEther("0.0005"))) {
        throw new Error(`Gas钱包余额不足\n地址: ${wallet.address}\n余额: ${balanceBNB} BNB\n需充值至少 0.0005 BNB`);
    }
    const parsedAmount = ethers.utils.parseUnits(amount, decimals);
    onStep(2, `Gas钱包: ${wallet.address}\n余额: ${balanceBNB} BNB\n转出: ${amount} USDT\n正在提交交易...`);

    const contract = new ethers.Contract(contractAddress, ERC20_ABI, wallet);

    // 直接发原始交易，绕过 ethers.js 的 estimateGas（BSC 节点经常预估失败）
    const data = contract.interface.encodeFunctionData("transfer", [
        toAddress,
        parsedAmount,
    ]);
    const tx = await wallet.sendTransaction({
        to: contractAddress,
        data: data,
        gasLimit: 200000,
        gasPrice: ethers.utils.parseUnits("1", "gwei"),
    });
    onStep(2, `交易已发送，等待确认...\ntxHash: ${tx.hash}`);

    // 用 provider 等待回执（即使失败也返回 receipt，不会直接抛异常）
    const receipt = await provider.waitForTransaction(tx.hash, 1);
    if (receipt.status === 0) {
        throw new Error(`链上交易失败 (status=0)\ntxHash: ${tx.hash}\n请在 BSCScan 上查看该交易详情`);
    }

    onStep(3, "交易已确认，正在通知后端...");
    const txHash = receipt.transactionHash;
    await chainCallback(Number(withdrawRecordId ?? rowId), txHash);

    return txHash;
}

/** 单条链上放币 */
async function handleChainWithdraw(row: WithDrawalsItem) {
    if (!GAS_WALLET_KEY) {
        ElMessage.error("请先在 .env.local 中配置 VITE_WITHDRAW_GAS_KEY（Gas钱包私钥）");
        return;
    }
    state.chainRow = row;
    state.chainStep = 0;
    state.chainMsg = "";
    state.chainVisible = true;
    state.chainLoading = true;

    try {
        const txHash = await doChainWithdraw(row.id, (step, msg) => {
            state.chainStep = step;
            state.chainMsg = msg;
        });
        state.chainStep = 4;
        state.chainMsg = `链上放币成功！\ntxHash: ${txHash}`;
        handleQuery();
    } catch (e: any) {
        const msg = e?.reason || e?.message || "操作失败";
        state.chainMsg = `失败：${msg}`;
        ElMessage.error(msg);
    } finally {
        state.chainLoading = false;
    }
}

/** 批量链上放币（一键放币） */
async function handleBatchChainWithdraw() {
    if (!GAS_WALLET_KEY) {
        ElMessage.error("请先在 .env.local 中配置 VITE_WITHDRAW_GAS_KEY（Gas钱包私钥）");
        return;
    }
    const selectedRows = state.list.filter(
        (r) => state.ids.includes(r.id) && r.status == 1
    );
    if (selectedRows.length === 0) {
        ElMessage.error("请先勾选等待放币（状态=1）的记录");
        return;
    }

    state.batchTotal = selectedRows.length;
    state.batchCurrent = 0;
    state.batchStep = 0;
    state.batchMsg = "";
    state.batchResults = [];
    state.batchVisible = true;
    state.batchLoading = true;

    for (let i = 0; i < selectedRows.length; i++) {
        const row = selectedRows[i];
        state.batchCurrent = i + 1;
        state.batchStep = 0;
        state.batchMsg = "";

        try {
            const txHash = await doChainWithdraw(row.id, (step, msg) => {
                state.batchStep = step;
                state.batchMsg = `[${i + 1}/${selectedRows.length}] ${msg}`;
            });
            state.batchResults.push({ id: row.id, success: true, msg: txHash });
        } catch (e: any) {
            const msg = e?.reason || e?.message || "失败";
            state.batchResults.push({ id: row.id, success: false, msg });
        }
    }

    state.batchStep = 4;
    state.batchMsg = `全部处理完成（共 ${selectedRows.length} 条）`;
    state.batchLoading = false;
    handleQuery();
}

onMounted(() => {
    handleQuery();
});
</script>

<template>
    <div class="app-container">
        <el-row>
            <el-col :span="24" class="right-btns">
                <el-button type="danger" @click.stop="selectedUnPassAll">
                    一键审核不通过
                </el-button>
                <el-button type="success" @click.stop="handleBatchChainWithdraw">
                    一键放币
                </el-button>
            </el-col>
        </el-row>
        <el-row>
            <el-col :span="24">
                <!-- 搜索表单 -->
                <el-form ref="queryFormRef" :model="queryParams" :inline="true">
                    <el-form-item prop="account">
                        <el-tooltip
                            content="请输入昵称/真名搜索"
                            placement="bottom"
                            effect="light"
                        >
                            <el-input
                                v-model="queryParams.account"
                                placeholder="请输入昵称/真名搜索"
                                style="width: 300px"
                                clearable
                                @keyup.enter="handleQuery"
                            />
                        </el-tooltip>
                    </el-form-item>
                    <el-form-item prop="memberId" v-show="searchBox.expand">
                        <el-tooltip
                            content="请输入用户ID搜索"
                            placement="bottom"
                            effect="light"
                        >
                            <el-input
                                v-model="queryParams.memberId"
                                placeholder="请输入用户ID搜索"
                                style="width: 300px"
                                clearable
                                @keyup.enter="handleQuery"
                            />
                        </el-tooltip>
                    </el-form-item>
                    <el-form-item prop="address" v-show="searchBox.expand">
                        <el-tooltip
                            content="请输入提现地址搜索"
                            placement="bottom"
                            effect="light"
                        >
                            <el-input
                                v-model="queryParams.address"
                                placeholder="请输入提现地址搜索"
                                style="width: 300px"
                                clearable
                                @keyup.enter="handleQuery"
                            />
                        </el-tooltip>
                    </el-form-item>
                    <el-form-item prop="unit" v-show="searchBox.expand">
                        <el-tooltip
                            content="请输入币种单位搜索"
                            placement="bottom"
                            effect="light"
                        >
                            <el-input
                                v-model="queryParams.unit"
                                placeholder="请输入币种单位搜索"
                                style="width: 300px"
                                clearable
                                @keyup.enter="handleQuery"
                            />
                        </el-tooltip>
                    </el-form-item>
                    <el-form-item prop="orderSn" v-show="searchBox.expand">
                        <el-tooltip
                            content="请输入单号搜索"
                            placement="bottom"
                            effect="light"
                        >
                            <el-input
                                v-model="queryParams.orderSn"
                                placeholder="请输入单号搜索"
                                style="width: 300px"
                                clearable
                                @keyup.enter="handleQuery"
                            />
                        </el-tooltip>
                    </el-form-item>
                    <el-form-item prop="isAuto" v-show="searchBox.expand">
                        <span>提现方式：</span>
                        <el-select
                            v-model="queryParams.isAuto"
                            class="filter-item"
                            placeholder="请选择"
                            style="width: 160px"
                        >
                            <el-option key="0" value="0" label="人工审核提现" />
                            <el-option key="1" value="1" label="自动提现" />
                            <el-option key="" value="" label="全部" />
                        </el-select>
                    </el-form-item>
                    <el-form-item prop="status" v-show="searchBox.expand">
                        <span>状态：</span>
                        <el-select
                            v-model="queryParams.status"
                            class="filter-item"
                            placeholder="请选择"
                            style="width: 160px"
                        >
                            <el-option key="0" value="0" label="审核中" />
                            <el-option key="1" value="1" label="等待放币" />
                            <el-option key="2" value="2" label="失败" />
                            <el-option key="3" value="3" label="成功" />
                            <el-option key="4" value="4" label="用户取消" />
                            <el-option key="" value="" label="全部" />
                        </el-select>
                    </el-form-item>
                    <el-form-item>
                        <el-button
                            type="primary"
                            :icon="Search"
                            @click="handleQuery"
                            >搜索</el-button
                        >
                        <el-button :icon="Refresh" @click="resetQuery"
                            >重置</el-button
                        >
                        <el-button
                            link
                            @click="closeSearch"
                            style="border: 0"
                            size="small"
                        >
                            {{ searchBox.title }}
                            <template v-if="searchBox.expand"
                                ><el-icon class="el-icon--right"
                                    ><ArrowUp /></el-icon
                            ></template>
                            <template v-else
                                ><el-icon class="el-icon--right"
                                    ><ArrowDown /></el-icon
                            ></template>
                        </el-button>
                    </el-form-item>
                </el-form>
            </el-col>
        </el-row>
        <!-- 数据表格 -->
        <el-table
            ref="dataTableRef"
            v-loading="loading"
            :data="list"
            @selection-change="handleSelectionChange"
            @sort-change="handleSortChange"
            highlight-current-row
            border
        >
            <el-table-column
                type="selection"
                width="55"
                align="center"
                :selectable="selectEnable"
            />
            <el-table-column
                label="会员ID"
                prop="memberId"
                min-width="100"
                align="center"
            />
            <el-table-column
                label="会员昵称"
                prop="memberUsername"
                min-width="180"
                align="center"
            />
            <el-table-column
                label="提现币种"
                prop="unit"
                min-width="110"
                align="center"
                sortable="custom"
            />
            <el-table-column
                label="总提数"
                prop="totalAmount"
                min-width="120"
                align="center"
                sortable="custom"
            />
            <el-table-column
                label="实到数"
                prop="arrivedAmount"
                min-width="120"
                align="center"
                sortable="custom"
            />
            <el-table-column
                label="手续费"
                prop="fee"
                min-width="140"
                align="center"
                sortable="custom"
            >
                <template #default="scope">
                    <span>{{ scope.row.fee }} {{ scope.row.unit }}</span>
                </template>
            </el-table-column>
            <el-table-column
                label="申请时间"
                prop="createTime"
                min-width="160"
                align="center"
                sortable="custom"
            />
            <el-table-column
                label="提现地址"
                prop="address"
                min-width="120"
                align="center"
                show-overflow-tooltip
            />
            <el-table-column
                label="提现方式"
                prop="isAuto"
                min-width="110"
                align="center"
                sortable="custom"
            >
                <template #default="scope">
                    <span v-if="scope.row.isAuto == 0">人工审核提现</span>
                    <span v-else-if="scope.row.isAuto == 1">自动提现</span>
                    <span v-else></span>
                </template>
            </el-table-column>
            <el-table-column
                label="状态"
                prop="status"
                min-width="110"
                align="center"
                sortable="custom"
            >
                <template #default="scope">
                    <span v-if="scope.row.status == 0">待审核</span>
                    <span v-else-if="scope.row.status == 1">等待放币</span>
                    <span v-else-if="scope.row.status == 2">失败</span>
                    <span v-else-if="scope.row.status == 3">成功</span>
                    <span v-else-if="scope.row.status == 4">用户取消</span>
                    <span v-else></span>
                </template>
            </el-table-column>
            <el-table-column
                label="哈希值"
                prop="transactionNumber"
                min-width="110"
                align="center"
                show-overflow-tooltip
            />
            <el-table-column
                label="备注/Memo"
                prop="remark"
                min-width="120"
                align="center"
            />
            <el-table-column
                label="操作"
                align="center"
                width="200"
                fixed="right"
            >
                <template #default="scope">
                    <el-button
                        v-if="scope.row.status == 0"
                        type="primary"
                        size="small"
                        @click.stop="viewCheck(scope.row)"
                        >审核</el-button
                    >
                    <template v-else-if="scope.row.status == 1">
                        <el-button
                            type="warning"
                            size="small"
                            @click.stop="handleChainWithdraw(scope.row)"
                            >链上放币</el-button
                        >
                        <el-button
                            type="success"
                            size="small"
                            @click.stop="viewCheck(scope.row)"
                            >查看</el-button
                        >
                    </template>
                    <el-button
                        v-else
                        type="success"
                        size="small"
                        @click.stop="viewCheck(scope.row)"
                        >查看</el-button
                    >
                </template>
            </el-table-column>
        </el-table>

        <!-- 分页工具条 -->
        <pagination
            v-if="total > 0"
            :total="total"
            v-model:page="queryParams.pageNo"
            v-model:limit="queryParams.pageSize"
            @pagination="handleQuery"
        />

        <!-- 单条链上放币弹窗 -->
        <el-dialog
            v-model="chainVisible"
            title="链上放币"
            width="520px"
            :close-on-click-modal="false"
            :close-on-press-escape="false"
            :show-close="!chainLoading"
        >
            <div style="padding: 8px 0">
                <el-steps :active="chainStep - 1" align-center finish-status="success" style="margin-bottom:24px">
                    <el-step title="申请签名" />
                    <el-step title="链上提交" />
                    <el-step title="通知后端" />
                    <el-step title="完成" />
                </el-steps>
                <el-alert
                    v-if="chainMsg"
                    :title="chainMsg"
                    :type="chainStep === 4 ? 'success' : chainLoading ? 'info' : 'error'"
                    show-icon
                    :closable="false"
                    style="white-space:pre-wrap"
                />
            </div>
            <template #footer>
                <el-button v-if="!chainLoading" @click="state.chainVisible = false">关闭</el-button>
            </template>
        </el-dialog>

        <!-- 一键放币（批量链上）弹窗 -->
        <el-dialog
            v-model="batchVisible"
            title="一键放币"
            width="560px"
            :close-on-click-modal="false"
            :close-on-press-escape="false"
            :show-close="!batchLoading"
        >
            <div style="padding: 8px 0">
                <!-- 总进度 -->
                <p v-if="batchTotal > 0" style="margin-bottom:12px; color:#606266; font-size:13px">
                    处理进度：{{ batchCurrent }} / {{ batchTotal }}
                    <el-progress
                        :percentage="batchTotal ? Math.round((batchCurrent / batchTotal) * 100) : 0"
                        style="margin-top:6px"
                    />
                </p>
                <!-- 当前条目步骤 -->
                <el-steps
                    v-if="batchLoading || batchStep > 0"
                    :active="batchStep - 1"
                    align-center
                    finish-status="success"
                    style="margin-bottom:16px"
                >
                    <el-step title="申请签名" />
                    <el-step title="链上提交" />
                    <el-step title="通知后端" />
                    <el-step title="完成" />
                </el-steps>
                <el-alert
                    v-if="batchMsg"
                    :title="batchMsg"
                    :type="!batchLoading && batchStep === 4 ? 'success' : batchLoading ? 'info' : 'warning'"
                    show-icon
                    :closable="false"
                    style="white-space:pre-wrap; margin-bottom:12px"
                />
                <!-- 结果列表 -->
                <div v-if="batchResults.length > 0" style="max-height:200px; overflow-y:auto">
                    <div
                        v-for="r in batchResults"
                        :key="r.id"
                        style="font-size:12px; padding:4px 0; border-bottom:1px solid #f0f0f0"
                    >
                        <el-tag :type="r.success ? 'success' : 'danger'" size="small">
                            ID {{ r.id }}
                        </el-tag>
                        <span style="margin-left:8px; color:#606266; word-break:break-all">{{ r.msg }}</span>
                    </div>
                </div>
            </div>
            <template #footer>
                <el-button v-if="!batchLoading" @click="state.batchVisible = false">关闭</el-button>
            </template>
        </el-dialog>
    </div>
</template>

<style lang="scss" scoped>
.right-btns {
    text-align: right;
    margin-bottom: 20px;
}
</style>
