import {
    APPLICATION_STATUS,
    FINANCE_OPERATIONS,
    WALLET_IDENTITIES,
    operationAllowsZeroRechargeAmount,
} from "./constants.js";

export function buildApplicationPayload(form) {
    const operation = stringValue(form.operation);
    const payload = {
        appCode: stringValue(form.appCode),
        coinAmount: numberValue(form.coinAmount),
        credentialImageUrl: stringValue(form.credentialImageUrl),
        credentialText: stringValue(form.credentialText),
        operation,
        rechargeAmount: numberValue(form.rechargeAmount),
        targetUserId: stringValue(form.targetUserId),
        walletIdentity: requiresWalletIdentity(operation) ? stringValue(form.walletIdentity) : "",
    };

    return payload;
}

export function validateApplicationPayload(payload) {
    if (!payload.appCode) {
        return "请选择 APP";
    }
    if (!payload.operation) {
        return "请选择操作内容";
    }
    if (!payload.targetUserId) {
        return "请填写目标用户 ID";
    }
    if (!Number.isFinite(payload.coinAmount) || payload.coinAmount <= 0) {
        return "请填写大于 0 的金币数量";
    }
    const allowsZeroRechargeAmount = operationAllowsZeroRechargeAmount(payload.operation);
    if (
        !Number.isFinite(payload.rechargeAmount) ||
        payload.rechargeAmount < 0 ||
        (!allowsZeroRechargeAmount && payload.rechargeAmount <= 0)
    ) {
        return allowsZeroRechargeAmount ? "请填写不小于 0 的充值金额" : "请填写大于 0 的充值金额";
    }
    if (requiresWalletIdentity(payload.operation) && !payload.walletIdentity) {
        return "请选择钱包身份";
    }
    if (!payload.credentialImageUrl && !payload.credentialText) {
        return "请上传凭证图片或填写凭证文字";
    }
    return "";
}

export function normalizeApplication(item = {}) {
    return {
        appCode: stringValue(item.appCode ?? item.app_code),
        appName: stringValue(item.appName ?? item.app_name),
        applicantName: stringValue(
            item.applicantName ?? item.applicant_name ?? item.applicantAccount ?? item.applicant_account,
        ),
        applicantUserId: item.applicantUserId ?? item.applicant_user_id,
        auditedAtMs: numberOrNull(item.auditedAtMs ?? item.audited_at_ms),
        auditorName: stringValue(item.auditorName ?? item.auditor_name ?? item.auditorAccount ?? item.auditor_account),
        auditorUserId: item.auditorUserId ?? item.auditor_user_id,
        auditRemark: stringValue(item.auditRemark ?? item.audit_remark),
        coinAmount: numberValue(item.coinAmount ?? item.coin_amount),
        createdAtMs: numberOrNull(item.createdAtMs ?? item.created_at_ms),
        credentialImageUrl: stringValue(item.credentialImageUrl ?? item.credential_image_url),
        credentialText: stringValue(item.credentialText ?? item.credential_text),
        id: item.id ?? item.applicationId ?? item.application_id,
        operation: stringValue(item.operation),
        rechargeAmount: numberValue(item.rechargeAmount ?? item.recharge_amount),
        status: stringValue(item.status) || "pending",
        targetUserId: stringValue(item.targetUserId ?? item.target_user_id),
        walletIdentity: stringValue(item.walletIdentity ?? item.wallet_identity),
    };
}

export function normalizeApplicationPage(data = {}) {
    const items = Array.isArray(data.items) ? data.items : [];
    return {
        items: items.map(normalizeApplication),
        page: Number(data.page || 1),
        pageSize: Number(data.pageSize ?? data.page_size ?? items.length),
        total: Number(data.total ?? items.length),
    };
}

export function normalizeWithdrawalApplication(item = {}) {
    return {
        appCode: stringValue(item.appCode ?? item.app_code),
        appName: stringValue(item.appName ?? item.app_name),
        approvedAtMs: numberOrNull(item.approvedAtMs ?? item.approved_at_ms),
        approverName: stringValue(
            item.approverName ?? item.approver_name ?? item.approverAccount ?? item.approver_account,
        ),
        approverUserId: item.approverUserId ?? item.approver_user_id,
        auditImageUrl: stringValue(item.auditImageUrl ?? item.audit_image_url),
        auditRemark: stringValue(item.auditRemark ?? item.audit_remark),
        auditTransactionId: stringValue(item.auditTransactionId ?? item.audit_transaction_id),
        createdAtMs: numberOrNull(item.createdAtMs ?? item.created_at_ms),
        freezeTransactionId: stringValue(item.freezeTransactionId ?? item.freeze_transaction_id),
        id: item.id ?? item.withdrawalApplicationId ?? item.withdrawal_application_id,
        salaryAssetType: stringValue(item.salaryAssetType ?? item.salary_asset_type),
        status: stringValue(item.status),
        updatedAtMs: numberOrNull(item.updatedAtMs ?? item.updated_at_ms),
        userId: stringValue(item.userId ?? item.user_id),
        withdrawAddress: stringValue(item.withdrawAddress ?? item.withdraw_address),
        withdrawAmount: numberValue(item.withdrawAmount ?? item.withdraw_amount),
        withdrawAmountMinor: numberValue(item.withdrawAmountMinor ?? item.withdraw_amount_minor),
        withdrawMethod: stringValue(item.withdrawMethod ?? item.withdraw_method),
    };
}

export function normalizeWithdrawalApplicationPage(data = {}) {
    const items = Array.isArray(data.items) ? data.items : [];
    return {
        items: items.map(normalizeWithdrawalApplication),
        page: Number(data.page || 1),
        pageSize: Number(data.pageSize ?? data.page_size ?? items.length),
        total: Number(data.total ?? items.length),
    };
}

export function normalizeRechargeBill(item = {}) {
    return {
        appCode: stringValue(item.appCode ?? item.app_code),
        appName: stringValue(item.appName ?? item.app_name),
        billAmountMinor: numberOrNull(item.billAmountMinor ?? item.bill_amount_minor),
        billAmountText: stringValue(
            item.billAmountText ?? item.bill_amount_text ?? item.billAmount ?? item.bill_amount,
        ),
        coinAmount: numberValue(item.coinAmount ?? item.coin_amount),
        commandId: stringValue(item.commandId ?? item.command_id),
        createdAtMs: numberOrNull(item.createdAtMs ?? item.created_at_ms),
        currencyCode: stringValue(item.currencyCode ?? item.currency_code) || "USD",
        exchangeCoinAmount: numberValue(item.exchangeCoinAmount ?? item.exchange_coin_amount),
        exchangeUsdMinorAmount: numberValue(item.exchangeUsdMinorAmount ?? item.exchange_usd_minor_amount),
        externalRef: stringValue(item.externalRef ?? item.external_ref),
        id: stringValue(item.id ?? item.transactionId ?? item.transaction_id),
        providerAmountMinor: numberOrNull(item.providerAmountMinor ?? item.provider_amount_minor),
        rechargeType: stringValue(item.rechargeType ?? item.recharge_type),
        status: stringValue(item.status),
        taxDeductionMinor: numberOrNull(
            item.taxDeductionMinor ??
                item.tax_deduction_minor ??
                item.thirdPartyTaxDeductionMinor ??
                item.third_party_tax_deduction_minor,
        ),
        taxDeductionText: stringValue(
            item.taxDeductionText ??
                item.tax_deduction_text ??
                item.thirdPartyTaxDeduction ??
                item.third_party_tax_deduction,
        ),
        taxRate: numberOrNull(item.taxRate ?? item.tax_rate ?? item.thirdPartyTaxRate ?? item.third_party_tax_rate),
        transactionId: stringValue(item.transactionId ?? item.transaction_id),
        usdMinorAmount: numberValue(item.usdMinorAmount ?? item.usd_minor_amount),
        userPaidAmountMicro: numberOrNull(
            item.userPaidAmountMicro ?? item.user_paid_amount_micro ?? item.paidAmountMicro ?? item.paid_amount_micro,
        ),
        userPaidAmountMinor: numberOrNull(
            item.userPaidAmountMinor ??
                item.user_paid_amount_minor ??
                item.paidAmountMinor ??
                item.paid_amount_minor ??
                item.providerAmountMinor ??
                item.provider_amount_minor,
        ),
        userPaidText: stringValue(
            item.userPaidText ??
                item.user_paid_text ??
                item.userPaidAmount ??
                item.user_paid_amount ??
                item.paidAmount ??
                item.paid_amount,
        ),
    };
}

export function normalizeRechargeBillPage(data = {}) {
    const rawItems = Array.isArray(data.items) ? data.items : Array.isArray(data.bills) ? data.bills : [];
    return {
        items: rawItems.map(normalizeRechargeBill),
        page: Number(data.page || 1),
        pageSize: Number(data.pageSize ?? data.page_size ?? rawItems.length),
        total: Number(data.total ?? rawItems.length),
    };
}

export function operationLabel(value, operations = FINANCE_OPERATIONS) {
    return operations.find((item) => item.value === value)?.label || value || "-";
}

export function rechargeTypeLabel(value) {
    if (value === "coin_seller_transfer") {
        return "币商充值";
    }
    if (value === "google_play_recharge") {
        return "谷歌充值";
    }
    return value || "-";
}

export function statusLabel(value) {
    return APPLICATION_STATUS.find(([status]) => status === value)?.[1] || value || "-";
}

export function walletIdentityLabel(value) {
    return WALLET_IDENTITIES.find(([identity]) => identity === value)?.[1] || value || "-";
}

export function formatAmount(value) {
    const number = Number(value);
    if (!Number.isFinite(number)) {
        return "-";
    }
    return number.toLocaleString("zh-CN", { maximumFractionDigits: 2 });
}

export function formatTime(ms) {
    const value = Number(ms);
    if (!Number.isFinite(value) || value <= 0) {
        return "-";
    }
    return new Intl.DateTimeFormat("zh-CN", {
        day: "2-digit",
        hour: "2-digit",
        hourCycle: "h23",
        minute: "2-digit",
        month: "2-digit",
        timeZone: "Asia/Shanghai",
        year: "numeric",
    }).format(value);
}

export function formatUsdMinor(value, currency = "USD") {
    const number = Number(value);
    if (!Number.isFinite(number)) {
        return "-";
    }
    return `${currency || "USD"} ${(number / 100).toLocaleString("zh-CN", {
        maximumFractionDigits: 2,
        minimumFractionDigits: 2,
    })}`;
}

export function formatMicroMoney(value, currency = "USD") {
    const number = Number(value);
    if (!Number.isFinite(number)) {
        return "-";
    }
    return `${currency || "USD"} ${(number / 1_000_000).toLocaleString("zh-CN", {
        maximumFractionDigits: 6,
        minimumFractionDigits: 2,
    })}`;
}

export function formatPercent(value) {
    const number = Number(value);
    if (!Number.isFinite(number)) {
        return "";
    }
    const percent = number > 1 ? number : number * 100;
    return `${percent.toLocaleString("zh-CN", { maximumFractionDigits: 4 })}%`;
}

export function requiresWalletIdentity(operation) {
    return FINANCE_OPERATIONS.some((item) => item.value === operation && item.requiresWalletIdentity);
}

function numberValue(value) {
    if (value === "" || value === null || value === undefined) {
        return Number.NaN;
    }
    return Number(value);
}

function numberOrNull(value) {
    const nextValue = Number(value);
    return Number.isFinite(nextValue) ? nextValue : null;
}

function stringValue(value) {
    return String(value ?? "").trim();
}
