import { useMemo, useState } from "react";
import { listCoinLedger } from "@/features/operations/api";
import { AdminFilterResetButton, AdminListBody, AdminListToolbar } from "@/shared/ui/AdminListLayout.jsx";
import { AdminUserIdentity } from "@/shared/ui/AdminUserIdentity.jsx";
import { DataState } from "@/shared/ui/DataState.jsx";
import { DataTable } from "@/shared/ui/DataTable.jsx";
import { SideDrawer } from "@/shared/ui/SideDrawer.jsx";
import { usePaginatedQuery } from "@/shared/hooks/usePaginatedQuery.js";
import { TimeRangeFilter } from "@/shared/ui/TimeRangeFilter.jsx";
import { TimeText } from "@/shared/ui/TimeText.jsx";
import { createOptionsColumnFilter, createUserIdentityColumnFilter } from "@/shared/ui/tableFilters.js";
import { emptyUserIdentityFilter, isUserIdentityFilterEmpty, userIdentityFilterParams } from "@/shared/ui/userIdentityFilter.js";
import styles from "@/features/operations/operations.module.css";

const pageSize = 50;

const coinLedgerBizTypeOptions = [
    { label: "人工入账", value: "manual_credit" },
    { label: "礼物扣费", value: "gift_debit" },
    { label: "私聊礼物扣费", value: "direct_gift_debit" },
    { label: "机器人礼物扣费", value: "robot_gift_debit" },
    { label: "币商转账", value: "coin_seller_transfer" },
    { label: "任务奖励", value: "task_reward" },
    { label: "幸运礼物奖励", value: "lucky_gift_reward" },
    { label: "转盘抽奖扣费", value: "wheel_draw_debit" },
    { label: "转盘奖励", value: "wheel_reward" },
    { label: "房间流水奖励", value: "room_turnover_reward" },
    { label: "邀请活动奖励", value: "invite_activity_reward" },
    { label: "开业活动奖励", value: "agency_opening_reward" },
    { label: "工资兑换金币", value: "salary_exchange_to_coin" },
    { label: "Google 充值", value: "google_play_recharge" },
    { label: "MifaPay 充值", value: "mifapay" },
    { label: "V5Pay 充值", value: "v5pay" },
    { label: "USDT 充值", value: "usdt_trc20" },
    { label: "游戏入账", value: "game_credit" },
    { label: "游戏扣费", value: "game_debit" },
    { label: "游戏退款", value: "game_refund" },
    { label: "游戏冲正", value: "game_reverse" },
    { label: "主播工资结算", value: "host_salary_settlement" },
    { label: "CP 解除费用", value: "cp_breakup_fee" },
    { label: "VIP 购买", value: "vip_purchase" },
    { label: "VIP 发放", value: "vip_grant" },
    { label: "资源发放", value: "resource_grant" },
    { label: "资源回收", value: "resource_grant_revoke" },
    { label: "资源商店购买", value: "resource_shop_purchase" },
    { label: "团队工资结算", value: "team_salary_settlement" },
];

const coinLedgerBizTypeLabels = Object.fromEntries(
    coinLedgerBizTypeOptions.map((option) => [option.value, option.label]),
);

const columns = [
    {
        key: "user",
        label: "用户",
        width: "minmax(260px, 1.35fr)",
        render: (entry) => <UserCell entry={entry} />,
    },
    {
        key: "amount",
        label: "数量",
        width: "minmax(120px, 0.65fr)",
        render: (entry) => <AmountValue entry={entry} />,
    },
    {
        key: "bizType",
        label: "类型",
        width: "minmax(150px, 0.8fr)",
        render: (entry) => bizTypeLabel(entry.bizType),
    },
    {
        key: "balance",
        label: "余额",
        width: "minmax(120px, 0.65fr)",
        render: (entry) => formatNumber(entry.availableAfter),
    },
    {
        key: "createdAtMs",
        label: "时间",
        width: "minmax(170px, 0.85fr)",
        render: (entry) => <TimeText value={entry.createdAtMs} />,
    },
];

const hiddenMetadataKeys = new Set(["presentation_json", "resource_snapshot_json"]);

const metadataLabels = {
    amount: "数量",
    app_code: "App",
    applied_at_ms: "入账时间",
    asset_type: "资产类型",
    available_delta: "可用变化",
    balance_after: "余额",
    billing_receipt_id: "账单 ID",
    charge_amount: "扣费数量",
    charge_asset_type: "扣费资产",
    coin_amount: "金币数量",
    coin_price: "单价",
    coin_spent: "消耗金币",
    counts_as_seller_recharge: "计入币商充值",
    cycle_key: "周期",
    evidence_ref: "凭证",
    game_id: "游戏 ID",
    gift_count: "礼物数量",
    gift_id: "礼物 ID",
    gift_name: "礼物名称",
    heat_value: "热度",
    operator_user_id: "操作人",
    op_type: "操作类型",
    paid_amount_micro: "支付金额",
    paid_currency_code: "支付币种",
    payment_ref: "支付凭证",
    platform_code: "游戏平台",
    price_version: "价格版本",
    provider_order_id: "游戏订单",
    provider_round_id: "游戏局号",
    reason: "原因",
    recharge_currency_code: "充值币种",
    recharge_policy_coin_amount: "策略金币",
    recharge_policy_id: "充值策略 ID",
    recharge_policy_usd_minor_amount: "策略 USD 金额",
    recharge_policy_version: "充值策略版本",
    recharge_usd_minor: "充值 USD 金额",
    room_id: "房间 ID",
    seller_asset_type: "币商资产",
    seller_balance_after: "币商余额",
    seller_region_id: "币商区域",
    seller_user_id: "币商用户",
    sender_user_id: "赠送人",
    sort_order: "排序",
    stock_type: "进货类型",
    target_asset_type: "目标资产",
    target_balance_after: "接收方余额",
    target_region_id: "接收方区域",
    target_user_id: "接收用户",
    task_id: "任务 ID",
    task_type: "任务类型",
    user_id: "用户 ID",
};

export function CoinLedgerTable({ lockedUser = null, userId = "" }) {
    const fixedUserId = String(userId || lockedUser?.userId || "").trim();
    const [page, setPage] = useState(1);
    const [selectedEntry, setSelectedEntry] = useState(null);
    const [bizType, setBizType] = useState("");
    const [userFilter, setUserFilter] = useState(emptyUserIdentityFilter);
    const [timeRange, setTimeRange] = useState({ endMs: "", startMs: "" });

    const filters = useMemo(
        () => ({
            biz_type: bizType,
            end_at_ms: timeRange.endMs || "",
            start_at_ms: timeRange.startMs || "",
            ...userIdentityFilterParams(userFilter),
            user_id: fixedUserId || userFilter.userId,
        }),
        [bizType, fixedUserId, timeRange.endMs, timeRange.startMs, userFilter],
    );
    const query = usePaginatedQuery({
        errorMessage: "获取金币流水失败",
        fetcher: listCoinLedger,
        filters,
        page,
        pageSize,
        queryKey: ["coin-ledger", filters, page],
    });
    const data = query.data || { items: [], total: 0, page, pageSize };
    const items = data.items || [];
    const total = data.total || 0;
    const hasMutableFilters = Boolean(!isUserIdentityFilterEmpty(userFilter) || bizType || timeRange.startMs || timeRange.endMs);

    const changeBizType = (value) => {
        setBizType(value);
        setPage(1);
    };
    const changeUserFilter = (value) => {
        setUserFilter(value);
        setPage(1);
    };
    const changeTimeRange = (nextRange) => {
        setTimeRange(nextRange);
        setPage(1);
    };
    const resetFilters = () => {
        setBizType("");
        setUserFilter(emptyUserIdentityFilter);
        setTimeRange({ endMs: "", startMs: "" });
        setPage(1);
    };
    const closeDetail = () => {
        setSelectedEntry(null);
    };

    const tableColumns = columns
        .filter((column) => !(column.key === "user" && fixedUserId))
        .map((column) => {
            if (column.key === "user") {
                return {
                    ...column,
                    filter: createUserIdentityColumnFilter({
                        value: userFilter,
                        onChange: changeUserFilter,
                    }),
                };
            }
            if (column.key === "bizType") {
                return {
                    ...column,
                    filter: createOptionsColumnFilter({
                        emptyLabel: "全部",
                        options: coinLedgerBizTypeOptions,
                        placeholder: "流水类型",
                        value: bizType,
                        onChange: changeBizType,
                    }),
                };
            }
            return column;
        });

    return (
        <div className={styles.ledgerTableShell}>
            <AdminListToolbar
                filters={
                    <>
                        <TimeRangeFilter value={timeRange} onChange={changeTimeRange} />
                        <AdminFilterResetButton disabled={!hasMutableFilters} onClick={resetFilters} />
                    </>
                }
            />
            <DataState error={query.error} loading={query.loading} onRetry={query.reload}>
                <AdminListBody>
                    <DataTable
                        columns={tableColumns}
                        getRowProps={(entry) => coinLedgerRowProps(entry, setSelectedEntry)}
                        items={items}
                        minWidth={fixedUserId ? "620px" : "900px"}
                        pagination={
                            total > 0
                                ? {
                                      page,
                                      pageSize: data.pageSize || pageSize,
                                      total,
                                      onPageChange: setPage,
                                  }
                                : undefined
                        }
                        rowKey={coinLedgerRowKey}
                    />
                </AdminListBody>
            </DataState>
            <CoinLedgerDetailDrawer entry={selectedEntry} open={Boolean(selectedEntry)} onClose={closeDetail} />
        </div>
    );
}

function coinLedgerRowKey(entry) {
    return entry.entryId || entry.transactionId || `${entry.userId || "user"}-${entry.createdAtMs || "time"}`;
}

function coinLedgerRowProps(entry, onOpen) {
    const user = entry.user || {};
    const userLabel = user.username || user.displayUserId || user.userId || entry.userId || "用户";
    return {
        "aria-label": `查看 ${userLabel} 的金币流水详情`,
        className: styles.clickableRow,
        role: "button",
        tabIndex: 0,
        onClick: () => onOpen(entry),
        onKeyDown: (event) => {
            if (event.key === "Enter" || event.key === " ") {
                event.preventDefault();
                onOpen(entry);
            }
        },
    };
}

function CoinLedgerDetailDrawer({ entry, onClose, open }) {
    const metadata = metadataObject(entry?.metadata);
    const contextRows = entry ? businessContextRows(entry, metadata) : [];
    const usedMetadataKeys = new Set(contextRows.flatMap((row) => row.metadataKeys || []));
    const metadataRows = metadataDetailRows(metadata, usedMetadataKeys);
    const user = entry?.user || {};

    return (
        <SideDrawer open={open} title="流水详情" width="wide" onClose={onClose}>
            {entry ? (
                <>
                    <header className={styles.detailHero}>
                        <AdminUserIdentity
                            openInAppUserDetail
                            user={{ ...user, userId: user.userId || entry.userId }}
                            size="large"
                        />
                        <AmountValue entry={entry} />
                    </header>

                    <DetailSection
                        items={[
                            detailRow("交易 ID", entry.transactionId),
                            detailRow("命令 ID", entry.commandId),
                            detailRow("外部单号", entry.externalRef),
                            detailRow("流水 ID", entry.entryId),
                            detailRow("业务类型", bizTypeLabel(entry.bizType)),
                            detailRow("方向", directionLabel(entry.direction)),
                            detailRow("发生时间", <TimeText value={entry.createdAtMs} />),
                        ]}
                        title="交易信息"
                    />

                    <DetailSection
                        items={[
                            detailRow("流水数量", formatSignedAmount(entry)),
                            detailRow("可用变化", formatSignedDelta(entry.availableDelta)),
                            detailRow("可用余额", formatNumber(entry.availableAfter)),
                        ]}
                        title="金额变化"
                    />

                    <DetailSection items={contextRows} title="业务上下文" />
                    <DetailSection items={metadataRows} title="扩展明细" />
                </>
            ) : null}
        </SideDrawer>
    );
}

function UserCell({ entry }) {
    const user = entry.user || {};
    return <AdminUserIdentity openInAppUserDetail user={{ ...user, userId: user.userId || entry.userId }} />;
}

function AmountValue({ entry }) {
    const expense = entry.direction === "expense";
    return (
        <span className={`${styles.amount} ${expense ? styles.amountExpense : styles.amountIncome}`}>
            {formatSignedAmount(entry)}
        </span>
    );
}

function DetailSection({ items, title }) {
    const visibleItems = items.filter((item) => hasDetailValue(item.value));
    if (!visibleItems.length) {
        return null;
    }
    return (
        <section className={styles.detailSection}>
            <h3 className={styles.detailSectionTitle}>{title}</h3>
            <div className={styles.detailGrid}>
                {visibleItems.map((item) => (
                    <DetailItem key={item.label} label={item.label} value={item.value} />
                ))}
            </div>
        </section>
    );
}

function DetailItem({ label, value }) {
    return (
        <div className={styles.detailItem}>
            <span className={styles.detailLabel}>{label}</span>
            <div className={styles.detailValue}>{displayDetailValue(value)}</div>
        </div>
    );
}

function businessContextRows(entry, metadata) {
    if (entry.bizType === "gift_debit") {
        return compactRows([
            metadataRow("礼物名称", metadata, ["gift_name", "giftName"]),
            metadataRow("礼物 ID", metadata, ["gift_id", "giftId"]),
            metadataRow("礼物数量", metadata, ["gift_count", "giftCount"]),
            metadataRow("赠送给", metadata, ["target_user_id", "targetUserId"], entry.counterpartyUserId),
            metadataRow("赠送人", metadata, ["sender_user_id", "senderUserId"], entry.userId),
            metadataRow("房间 ID", metadata, ["room_id", "roomId"], entry.roomId),
            metadataRow("消耗金币", metadata, ["coin_spent", "coinSpent", "charge_amount", "chargeAmount"]),
            metadataRow("热度", metadata, ["heat_value", "heatValue"]),
            metadataRow("账单 ID", metadata, ["billing_receipt_id", "billingReceiptId"]),
            metadataRow("价格版本", metadata, ["price_version", "priceVersion"]),
        ]);
    }

    if (String(entry.bizType || "").startsWith("game_")) {
        return compactRows([
            metadataRow("游戏 ID", metadata, ["game_id", "gameId"]),
            metadataRow("游戏平台", metadata, ["platform_code", "platformCode"]),
            metadataRow("游戏订单", metadata, ["provider_order_id", "providerOrderId"], entry.externalRef),
            metadataRow("游戏局号", metadata, ["provider_round_id", "providerRoundId"]),
            metadataRow("游戏操作", metadata, ["op_type", "opType"]),
            metadataRow("游戏房间", metadata, ["room_id", "roomId"], entry.roomId),
            metadataRow("游戏金币", metadata, ["coin_amount", "coinAmount"]),
        ]);
    }

    if (entry.bizType === "coin_seller_transfer") {
        return compactRows([
            metadataRow("币商用户", metadata, ["seller_user_id", "sellerUserId"]),
            metadataRow("接收用户", metadata, ["target_user_id", "targetUserId"], entry.counterpartyUserId),
            metadataRow("转账金额", metadata, ["amount"]),
            metadataRow("原因", metadata, ["reason"]),
            metadataRow("币商余额", metadata, ["seller_balance_after", "sellerBalanceAfter"]),
            metadataRow("接收方余额", metadata, ["target_balance_after", "targetBalanceAfter"]),
            metadataRow("充值策略 ID", metadata, ["recharge_policy_id", "rechargePolicyId"]),
            metadataRow("充值币种", metadata, ["recharge_currency_code", "rechargeCurrencyCode"]),
        ]);
    }

    return compactRows([
        metadataRow(
            "关联用户",
            metadata,
            ["target_user_id", "targetUserId", "seller_user_id", "sellerUserId"],
            entry.counterpartyUserId,
        ),
        metadataRow("房间 ID", metadata, ["room_id", "roomId"], entry.roomId),
        metadataRow("任务 ID", metadata, ["task_id", "taskId"]),
        metadataRow("任务类型", metadata, ["task_type", "taskType"]),
        metadataRow("周期", metadata, ["cycle_key", "cycleKey"]),
        metadataRow("原因", metadata, ["reason"]),
        metadataRow("操作人", metadata, ["operator_user_id", "operatorUserId"]),
        metadataRow("凭证", metadata, ["evidence_ref", "evidenceRef"]),
    ]);
}

function metadataDetailRows(metadata, usedMetadataKeys) {
    return Object.entries(metadata)
        .filter(([key, value]) => !usedMetadataKeys.has(key) && !hiddenMetadataKeys.has(key) && hasDetailValue(value))
        .map(([key, value]) => detailRow(metadataLabel(key), normalizeMetadataValue(value), [key]));
}

function metadataRow(label, metadata, keys, fallback) {
    return detailRow(label, firstValue(valueFromMetadata(metadata, keys), fallback), keys);
}

function detailRow(label, value, metadataKeys = []) {
    return { label, metadataKeys, value };
}

function compactRows(rows) {
    return rows.filter((row) => hasDetailValue(row.value));
}

function valueFromMetadata(metadata, keys) {
    for (const key of keys) {
        if (hasDetailValue(metadata[key])) {
            return metadata[key];
        }
    }
    return undefined;
}

function firstValue(...values) {
    return values.find((value) => hasDetailValue(value));
}

function metadataObject(value) {
    if (!value || typeof value !== "object" || Array.isArray(value)) {
        return {};
    }
    return value;
}

function normalizeMetadataValue(value) {
    if (typeof value !== "string") {
        return value;
    }
    const trimmed = value.trim();
    if (!trimmed || (trimmed[0] !== "{" && trimmed[0] !== "[")) {
        return value;
    }
    try {
        return JSON.parse(trimmed);
    } catch {
        return value;
    }
}

function displayDetailValue(value) {
    if (!hasDetailValue(value)) {
        return "-";
    }
    if (typeof value === "object") {
        return <pre className={styles.detailCode}>{JSON.stringify(value, null, 2)}</pre>;
    }
    return String(value);
}

function hasDetailValue(value) {
    return value === 0 || value === false || Boolean(value);
}

function formatSignedAmount(entry) {
    const sign = entry.direction === "expense" ? "-" : "+";
    const amount = hasDetailValue(entry.amount) ? entry.amount : Math.abs(Number(entry.availableDelta || 0));
    return `${sign}${formatNumber(amount)}`;
}

function formatSignedDelta(value) {
    if (!hasDetailValue(value)) {
        return "-";
    }
    const numberValue = Number(value);
    if (Number.isNaN(numberValue)) {
        return String(value);
    }
    return `${numberValue > 0 ? "+" : ""}${formatNumber(numberValue)}`;
}

function formatNumber(value) {
    if (value === 0 || value) {
        return Number(value).toLocaleString("zh-CN");
    }
    return "-";
}

function directionLabel(value) {
    const labels = {
        expense: "支出",
        income: "收入",
    };
    return labels[value] || value || "-";
}

function metadataLabel(key) {
    return metadataLabels[key] || key;
}

function bizTypeLabel(value) {
    return coinLedgerBizTypeLabels[value] || value || "-";
}
