<?php
if (!defined('ABSPATH')) {
    exit;
}

add_action('admin_menu', 'pix_data_admin_menu', 8);
function pix_data_admin_menu(){
    add_menu_page(
        'PIX数据管理',
        'PIX数据管理',
        'manage_options',
        'pix-data-management',
        'pix_data_admin_overview_page',
        'dashicons-database-view',
        100
    );

    add_submenu_page(
        'pix-data-management',
        '数据概览',
        '数据概览',
        'manage_options',
        'pix-data-management',
        'pix_data_admin_overview_page'
    );
}

add_action('admin_menu', 'pix_data_admin_submenu', 12);
function pix_data_admin_submenu(){
    add_submenu_page(
        'pix-data-management',
        '订单管理',
        '订单管理',
        'manage_options',
        'ppo-admin-orders',
        'pix_data_admin_orders_page'
    );

    add_submenu_page(
        'pix-data-management',
        '资产调整',
        '资产调整',
        'manage_options',
        'ppo-wallet-adjust',
        'pix_data_admin_wallet_adjust_page'
    );

    add_submenu_page(
        'pix-data-management',
        '支付回调日志',
        '支付回调日志',
        'manage_options',
        'ppo-pay-notify-logs',
        'pix_data_admin_notify_logs_page'
    );

}

add_action('admin_post_pix_data_update_order', 'pix_data_handle_update_order');
add_action('admin_post_pix_data_delete_order', 'pix_data_handle_delete_order');
add_action('admin_post_pix_data_wallet_adjust', 'pix_data_handle_wallet_adjust');
add_action('admin_post_pix_data_export_orders', 'pix_data_handle_export_orders');

function pix_data_admin_overview_page(){
    if (!current_user_can('manage_options')) {
        wp_die('权限不足');
    }

    global $wpdb;
    $order_table = $wpdb->prefix . 'ppo_pay_order';
    $card_table = $wpdb->prefix . 'ppo_cards';
    $notify_table = $wpdb->prefix . 'ppo_pay_notify_log';

    $stats = array(
        'orders' => pix_data_table_exists($order_table) ? intval($wpdb->get_var("SELECT COUNT(*) FROM $order_table")) : 0,
        'paid_orders' => pix_data_table_exists($order_table) ? intval($wpdb->get_var("SELECT COUNT(*) FROM $order_table WHERE status = 1")) : 0,
        'cards' => pix_data_table_exists($card_table) ? intval($wpdb->get_var("SELECT COUNT(*) FROM $card_table")) : 0,
        'failed_logs' => pix_data_table_exists($notify_table) ? intval($wpdb->get_var("SELECT COUNT(*) FROM $notify_table WHERE success = 0")) : 0,
    );
    ?>
    <div class="wrap pix-data-admin">
        <h1>PIX数据管理</h1>
        <p>这里集中管理主题运营数据：卡密、订单、支付回调日志。</p>
        <div class="pix-data-cards">
            <?php pix_data_stat_card('订单总数', $stats['orders'], admin_url('admin.php?page=ppo-admin-orders')); ?>
            <?php pix_data_stat_card('已支付订单', $stats['paid_orders'], admin_url('admin.php?page=ppo-admin-orders&order_status=paid')); ?>
            <?php pix_data_stat_card('卡密总数', $stats['cards'], admin_url('admin.php?page=ppo-cards')); ?>
            <?php pix_data_stat_card('资产调整', '手动', admin_url('admin.php?page=ppo-wallet-adjust')); ?>
            <?php pix_data_stat_card('失败回调', $stats['failed_logs'], admin_url('admin.php?page=ppo-pay-notify-logs&success=0')); ?>
        </div>
    </div>
    <?php
    pix_data_admin_inline_style();
}

function pix_data_admin_wallet_adjust_page(){
    if (!current_user_can('manage_options')) {
        wp_die('权限不足');
    }

    $target_user_id = isset($_GET['user_id']) ? intval($_GET['user_id']) : 0;
    $target_user = $target_user_id > 0 ? get_userdata($target_user_id) : false;
    $cash_name = get_op('cash_name', '余额');
    $credit_name = get_op('credit_name', '积分');
    $current_balance = $target_user ? Credit::get_user_balance($target_user_id) : 0;
    $current_credit = $target_user ? Credit::get_user_credit($target_user_id) : 0;
    ?>
    <div class="wrap pix-data-admin">
        <h1>资产调整</h1>
        <p>管理员可在这里手动增加或扣减用户<?php echo esc_html($cash_name); ?>、<?php echo esc_html($credit_name); ?>。所有操作都会写入钱包流水，便于后续核对。</p>

        <?php if (!empty($_GET['adjusted'])): ?>
            <div class="notice notice-success is-dismissible"><p><?php echo esc_html(pix_data_wallet_adjust_notice()); ?></p></div>
        <?php endif; ?>
        <?php if (!empty($_GET['adjust_error'])): ?>
            <div class="notice notice-error is-dismissible"><p><?php echo esc_html(pix_data_wallet_adjust_error_message(sanitize_key($_GET['adjust_error']))); ?></p></div>
        <?php endif; ?>

        <div class="pix-wallet-adjust-layout">
            <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" class="pix-wallet-adjust-form">
                <?php wp_nonce_field('pix_data_wallet_adjust'); ?>
                <input type="hidden" name="action" value="pix_data_wallet_adjust">

                <div class="pix-order-panel">
                    <h2>调整信息</h2>
                    <table class="form-table">
                        <tr>
                            <th><label for="wallet_user_id">用户ID</label></th>
                            <td>
                                <input type="number" class="regular-text" id="wallet_user_id" name="user_id" min="1" value="<?php echo esc_attr($target_user_id ?: ''); ?>" required>
                                <p class="description">请输入需要调整资产的用户 ID。</p>
                            </td>
                        </tr>
                        <tr>
                            <th><label for="wallet_asset_type">资产类型</label></th>
                            <td>
                                <select id="wallet_asset_type" name="asset_type">
                                    <option value="cash"><?php echo esc_html($cash_name); ?></option>
                                    <option value="credit"><?php echo esc_html($credit_name); ?></option>
                                </select>
                            </td>
                        </tr>
                        <tr>
                            <th><label for="wallet_adjust_action">操作</label></th>
                            <td>
                                <select id="wallet_adjust_action" name="adjust_action">
                                    <option value="increase">增加</option>
                                    <option value="decrease">扣减</option>
                                </select>
                            </td>
                        </tr>
                        <tr>
                            <th><label for="wallet_amount">数量</label></th>
                            <td>
                                <input type="number" class="regular-text" id="wallet_amount" name="amount" min="0.01" step="0.01" required>
                                <p class="description">积分会按整数处理，余额保留 2 位小数。</p>
                            </td>
                        </tr>
                        <tr>
                            <th><label for="wallet_note">备注原因</label></th>
                            <td>
                                <textarea class="large-text" rows="4" id="wallet_note" name="note" required placeholder="例如：测试充值、客服补偿、活动奖励、异常扣回"></textarea>
                                <p class="description">备注会进入钱包流水，建议写清楚原因。</p>
                            </td>
                        </tr>
                    </table>
                    <?php submit_button('确认调整'); ?>
                </div>
            </form>

            <div class="pix-order-panel pix-wallet-adjust-user">
                <h2>用户当前资产</h2>
                <?php if ($target_user): ?>
                    <div class="pix-wallet-user-card">
                        <div class="pix-wallet-user-name"><?php echo esc_html($target_user->display_name); ?></div>
                        <div class="description">ID: <?php echo intval($target_user_id); ?> / <?php echo esc_html($target_user->user_email); ?></div>
                        <div class="pix-wallet-assets">
                            <div><span><?php echo esc_html($cash_name); ?></span><strong><?php echo esc_html(number_format(floatval($current_balance), 2)); ?></strong></div>
                            <div><span><?php echo esc_html($credit_name); ?></span><strong><?php echo esc_html(number_format_i18n(intval($current_credit))); ?></strong></div>
                        </div>
                    </div>
                <?php else: ?>
                    <p class="description">在 URL 后追加 <code>&user_id=用户ID</code> 可快速查看该用户当前资产。</p>
                <?php endif; ?>
            </div>
        </div>
    </div>
    <?php
    pix_data_admin_inline_style();
}

function pix_data_handle_wallet_adjust(){
    if (!current_user_can('manage_options')) {
        wp_die('权限不足');
    }

    check_admin_referer('pix_data_wallet_adjust');

    $user_id = isset($_POST['user_id']) ? intval($_POST['user_id']) : 0;
    $asset_type = isset($_POST['asset_type']) ? sanitize_key($_POST['asset_type']) : '';
    $adjust_action = isset($_POST['adjust_action']) ? sanitize_key($_POST['adjust_action']) : '';
    $amount = isset($_POST['amount']) ? floatval($_POST['amount']) : 0;
    $note = isset($_POST['note']) ? sanitize_textarea_field(wp_unslash($_POST['note'])) : '';

    $redirect_args = array('page' => 'ppo-wallet-adjust', 'user_id' => $user_id);
    if ($user_id <= 0 || !get_userdata($user_id)) {
        pix_data_wallet_adjust_redirect(array_merge($redirect_args, array('adjust_error' => 'user')));
    }

    if (!in_array($asset_type, array('cash', 'credit'), true)) {
        pix_data_wallet_adjust_redirect(array_merge($redirect_args, array('adjust_error' => 'asset')));
    }

    if (!in_array($adjust_action, array('increase', 'decrease'), true)) {
        pix_data_wallet_adjust_redirect(array_merge($redirect_args, array('adjust_error' => 'action')));
    }

    if ($amount <= 0) {
        pix_data_wallet_adjust_redirect(array_merge($redirect_args, array('adjust_error' => 'amount')));
    }

    if ($note === '') {
        pix_data_wallet_adjust_redirect(array_merge($redirect_args, array('adjust_error' => 'note')));
    }

    $change_amount = $adjust_action === 'decrease' ? -abs($amount) : abs($amount);
    if ($asset_type === 'credit') {
        $change_amount = $adjust_action === 'decrease' ? -abs(intval($amount)) : abs(intval($amount));
        if ($change_amount === 0) {
            pix_data_wallet_adjust_redirect(array_merge($redirect_args, array('adjust_error' => 'amount')));
        }
        $result = Credit::credit_change($user_id, $change_amount, array(
            'change_type' => 'admin_adjust_credit',
            'order_id' => 'ADMIN-' . current_time('timestamp'),
            'note' => $note,
        ));
    } else {
        $change_amount = round($change_amount, 2);
        $result = Credit::cash_change($user_id, $change_amount, array(
            'change_type' => 'admin_adjust_cash',
            'order_id' => 'ADMIN-' . current_time('timestamp'),
            'note' => $note,
        ));
    }

    if ($result === false) {
        pix_data_wallet_adjust_redirect(array_merge($redirect_args, array('adjust_error' => 'change')));
    }

    pix_data_wallet_adjust_redirect(array_merge($redirect_args, array(
        'adjusted' => 1,
        'asset' => $asset_type,
        'delta' => $change_amount,
        'after' => $result,
    )));
}

function pix_data_wallet_adjust_redirect($args){
    wp_redirect(add_query_arg($args, admin_url('admin.php')));
    exit;
}

function pix_data_wallet_adjust_notice(){
    $asset = isset($_GET['asset']) && $_GET['asset'] === 'credit' ? get_op('credit_name', '积分') : get_op('cash_name', '余额');
    $delta = isset($_GET['delta']) ? floatval($_GET['delta']) : 0;
    $after = isset($_GET['after']) ? sanitize_text_field(wp_unslash($_GET['after'])) : '';
    return sprintf('%s调整成功，变动：%s，当前值：%s。', $asset, $delta > 0 ? '+' . $delta : (string)$delta, $after);
}

function pix_data_wallet_adjust_error_message($code){
    $messages = array(
        'user' => '用户不存在，请确认用户ID。',
        'asset' => '资产类型不正确。',
        'action' => '操作类型不正确。',
        'amount' => '调整数量必须大于 0。',
        'note' => '请填写备注原因。',
        'change' => '调整失败，可能是余额/积分不足或流水写入失败。',
    );

    return isset($messages[$code]) ? $messages[$code] : '调整失败，请重试。';
}

function pix_data_stat_card($label, $value, $url){
    $display_value = is_numeric($value) ? number_format_i18n($value) : $value;
    ?>
    <a class="pix-data-card" href="<?php echo esc_url($url); ?>">
        <span><?php echo esc_html($label); ?></span>
        <strong><?php echo esc_html($display_value); ?></strong>
    </a>
    <?php
}

function pix_data_order_filters($source){
    global $wpdb;

    $source = is_array($source) ? $source : array();
    $where = array('1=1');

    $keyword = isset($source['s']) ? sanitize_text_field(wp_unslash($source['s'])) : '';
    if ($keyword !== '') {
        $like = '%' . $wpdb->esc_like($keyword) . '%';
        $where[] = $wpdb->prepare('(order_id LIKE %s OR pay_trade_no LIKE %s OR order_title LIKE %s OR product_title LIKE %s OR buyer_name LIKE %s OR buyer_email LIKE %s OR user_id = %d OR data_id = %d OR product_id = %d)', $like, $like, $like, $like, $like, $like, intval($keyword), intval($keyword), intval($keyword));
    }

    $order_type = isset($source['order_type']) ? sanitize_key($source['order_type']) : '';
    if ($order_type !== '') {
        $where[] = $wpdb->prepare('order_type = %s', $order_type);
    }

    $product_subtype = isset($source['product_subtype']) ? sanitize_key($source['product_subtype']) : '';
    if ($product_subtype !== '') {
        $where[] = $wpdb->prepare('product_subtype = %s', $product_subtype);
    }

    $pay_channel = isset($source['pay_channel']) ? sanitize_key($source['pay_channel']) : '';
    if ($pay_channel !== '') {
        if (in_array($pay_channel, array('card_auth', 'card_balance', 'card_credit'), true)) {
            $card_table = $wpdb->prefix . 'ppo_cards';
            if (pix_data_table_exists($card_table)) {
                $where[] = $wpdb->prepare(
                    "(pay_type_info = %s OR pay_type = %s OR pay_trade_no IN (SELECT code FROM $card_table WHERE type = %s))",
                    $pay_channel,
                    $pay_channel,
                    $pay_channel
                );
            } else {
                $where[] = $wpdb->prepare('(pay_type_info = %s OR pay_type = %s)', $pay_channel, $pay_channel);
            }
        } else {
            $where[] = $wpdb->prepare('pay_type_info = %s', $pay_channel);
        }
    }

    $order_status = isset($source['order_status']) ? sanitize_key($source['order_status']) : '';
    if ($order_status !== '') {
        if ($order_status === 'paid') {
            $where[] = 'status = 1';
        } elseif ($order_status === 'pending') {
            $where[] = 'status = 0';
        } elseif ($order_status === 'closed') {
            $where[] = $wpdb->prepare('order_status = %d', class_exists('PixOrder') ? PixOrder::STATUS_CLOSED : 3);
        } elseif ($order_status === 'cancel') {
            $where[] = $wpdb->prepare('order_status = %d', class_exists('PixOrder') ? PixOrder::STATUS_CANCEL : 2);
        }
    }

    $deleted = isset($source['deleted']) ? sanitize_key($source['deleted']) : '';
    if ($deleted === '1') {
        $where[] = 'deleted_at IS NOT NULL';
    } else {
        $where[] = 'deleted_at IS NULL';
        $deleted = '0';
    }

    $date_from = isset($source['date_from']) ? sanitize_text_field(wp_unslash($source['date_from'])) : '';
    if ($date_from !== '' && preg_match('/^\d{4}-\d{2}-\d{2}$/', $date_from)) {
        $where[] = $wpdb->prepare('create_time >= %s', $date_from . ' 00:00:00');
    } else {
        $date_from = '';
    }

    $date_to = isset($source['date_to']) ? sanitize_text_field(wp_unslash($source['date_to'])) : '';
    if ($date_to !== '' && preg_match('/^\d{4}-\d{2}-\d{2}$/', $date_to)) {
        $where[] = $wpdb->prepare('create_time <= %s', $date_to . ' 23:59:59');
    } else {
        $date_to = '';
    }

    $amount_min = isset($source['amount_min']) && $source['amount_min'] !== '' ? max(0, floatval($source['amount_min'])) : '';
    if ($amount_min !== '') {
        $where[] = $wpdb->prepare('CAST(total_price AS DECIMAL(20,4)) >= %f', $amount_min);
    }

    $amount_max = isset($source['amount_max']) && $source['amount_max'] !== '' ? max(0, floatval($source['amount_max'])) : '';
    if ($amount_max !== '') {
        $where[] = $wpdb->prepare('CAST(total_price AS DECIMAL(20,4)) <= %f', $amount_max);
    }

    return array(
        'where_sql' => implode(' AND ', $where),
        'keyword' => $keyword,
        'order_type' => $order_type,
        'product_subtype' => $product_subtype,
        'pay_channel' => $pay_channel,
        'order_status' => $order_status,
        'deleted' => $deleted,
        'date_from' => $date_from,
        'date_to' => $date_to,
        'amount_min' => $amount_min,
        'amount_max' => $amount_max,
    );
}

function pix_data_order_export_url($source){
    $allowed = array('s', 'order_type', 'product_subtype', 'pay_channel', 'order_status', 'deleted', 'date_from', 'date_to', 'amount_min', 'amount_max');
    $args = array('action' => 'pix_data_export_orders');

    foreach ($allowed as $key) {
        if (isset($source[$key]) && $source[$key] !== '') {
            $args[$key] = sanitize_text_field(wp_unslash($source[$key]));
        }
    }

    return wp_nonce_url(add_query_arg($args, admin_url('admin-post.php')), 'pix_data_export_orders');
}

function pix_data_handle_export_orders(){
    if (!current_user_can('manage_options')) {
        wp_die('权限不足');
    }

    check_admin_referer('pix_data_export_orders');

    global $wpdb;
    $table = $wpdb->prefix . 'ppo_pay_order';
    if (!pix_data_table_exists($table)) {
        wp_die('订单表不存在');
    }

    $filters = pix_data_order_filters($_GET);
    $where_sql = $filters['where_sql'];
    $orders = $wpdb->get_results("SELECT * FROM $table WHERE $where_sql ORDER BY ID DESC");

    $filename = 'pix-orders-' . date('Ymd-His') . '.csv';
    nocache_headers();
    header('Content-Type: text/csv; charset=UTF-8');
    header('Content-Disposition: attachment; filename="' . $filename . '"');

    $out = fopen('php://output', 'w');
    fputcsv($out, array(
        'ID',
        '订单号',
        '交易号',
        '订单标题',
        '商品标题',
        '商品ID',
        '订单类型',
        '细分类型',
        '买家ID',
        '买家名称',
        '买家邮箱',
        '支付渠道',
        '支付金额',
        '订单状态',
        '创建时间',
        '支付时间',
        '过期时间',
        '联系/收货信息',
        '授权码/卡密',
        '物流状态',
        '物流公司',
        '运单号',
        '后台备注',
        '删除时间',
    ));

    foreach ($orders as $order) {
        fputcsv($out, array_map('pix_data_csv_cell', array(
            intval($order->ID),
            $order->order_id,
            $order->pay_trade_no,
            $order->order_title,
            $order->product_title,
            $order->product_id ?: $order->data_id,
            pix_data_order_type_label($order->order_type),
            pix_data_product_subtype_label($order->product_subtype),
            intval($order->user_id),
            $order->buyer_name,
            $order->buyer_email,
            pix_data_order_pay_channel_label($order),
            number_format(floatval($order->total_price), 2, '.', ''),
            pix_data_order_status_label($order),
            $order->create_time,
            $order->pay_time,
            $order->expire_time,
            $order->order_address,
            $order->order_license,
            $order->shipping_status,
            $order->shipping_company,
            $order->tracking_no,
            $order->admin_note,
            $order->deleted_at,
        )));
    }

    fclose($out);
    exit;
}

function pix_data_csv_cell($value){
    $value = pix_data_string($value);
    if ($value !== '' && preg_match('/^[=\-+@]/', $value)) {
        return "\t" . $value;
    }

    return $value;
}

function pix_data_admin_orders_page(){
    if (!current_user_can('manage_options')) {
        wp_die('权限不足');
    }

    if (isset($_GET['action']) && sanitize_key($_GET['action']) === 'edit') {
        pix_data_admin_order_edit_page();
        return;
    }

    global $wpdb;
    $table = $wpdb->prefix . 'ppo_pay_order';
    if (!pix_data_table_exists($table)) {
        pix_data_render_missing_table('订单表不存在');
        return;
    }

    $per_page = 20;
    $paged = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
    $offset = ($paged - 1) * $per_page;
    $filters = pix_data_order_filters($_GET);
    $where_sql = $filters['where_sql'];
    $keyword = $filters['keyword'];
    $order_type = $filters['order_type'];
    $product_subtype = $filters['product_subtype'];
    $pay_channel = $filters['pay_channel'];
    $order_status = $filters['order_status'];
    $deleted = $filters['deleted'];
    $date_from = $filters['date_from'];
    $date_to = $filters['date_to'];
    $amount_min = $filters['amount_min'];
    $amount_max = $filters['amount_max'];

    $total = intval($wpdb->get_var("SELECT COUNT(*) FROM $table WHERE $where_sql"));
    $orders = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM $table WHERE $where_sql ORDER BY ID DESC LIMIT %d OFFSET %d",
        $per_page,
        $offset
    ));
    $export_url = pix_data_order_export_url($_GET);
    ?>
    <div class="wrap pix-data-admin">
        <h1>订单管理</h1>
        <form method="get" class="pix-data-filter">
            <input type="hidden" name="page" value="ppo-admin-orders">
            <input type="search" name="s" value="<?php echo esc_attr($keyword); ?>" placeholder="订单号 / 交易号 / 商品 / 买家 / ID">
            <select name="order_type">
                <option value="">全部类型</option>
                <?php foreach (pix_data_order_type_labels() as $key => $label): ?>
                    <option value="<?php echo esc_attr($key); ?>" <?php selected($order_type, $key); ?>><?php echo esc_html($label); ?></option>
                <?php endforeach; ?>
            </select>
            <select name="product_subtype">
                <option value="">全部细分</option>
                <?php foreach (pix_data_product_subtype_labels() as $key => $label): ?>
                    <option value="<?php echo esc_attr($key); ?>" <?php selected($product_subtype, $key); ?>><?php echo esc_html($label); ?></option>
                <?php endforeach; ?>
            </select>
            <select name="pay_channel">
                <option value="">全部渠道</option>
                <?php foreach (pix_data_pay_channel_labels() as $key => $label): ?>
                    <option value="<?php echo esc_attr($key); ?>" <?php selected($pay_channel, $key); ?>><?php echo esc_html($label); ?></option>
                <?php endforeach; ?>
            </select>
            <select name="order_status">
                <option value="">全部状态</option>
                <option value="pending" <?php selected($order_status, 'pending'); ?>>待支付</option>
                <option value="paid" <?php selected($order_status, 'paid'); ?>>已支付</option>
                <option value="cancel" <?php selected($order_status, 'cancel'); ?>>已取消</option>
                <option value="closed" <?php selected($order_status, 'closed'); ?>>已关闭</option>
            </select>
            <select name="deleted">
                <option value="0" <?php selected($deleted, '0'); ?>>正常订单</option>
                <option value="1" <?php selected($deleted, '1'); ?>>已删除</option>
            </select>
            <input type="date" name="date_from" value="<?php echo esc_attr($date_from); ?>" aria-label="开始日期">
            <input type="date" name="date_to" value="<?php echo esc_attr($date_to); ?>" aria-label="结束日期">
            <input type="number" step="0.01" min="0" name="amount_min" value="<?php echo esc_attr($amount_min); ?>" placeholder="最小金额">
            <input type="number" step="0.01" min="0" name="amount_max" value="<?php echo esc_attr($amount_max); ?>" placeholder="最大金额">
            <?php submit_button('筛选', 'secondary', '', false); ?>
            <a class="button" href="<?php echo esc_url(admin_url('admin.php?page=ppo-admin-orders')); ?>">重置</a>
            <a class="button button-primary" href="<?php echo esc_url($export_url); ?>">导出CSV</a>
        </form>

        <table class="wp-list-table widefat fixed striped">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>订单号</th>
                    <th>交易号</th>
                    <th>商品</th>
                    <th>买家</th>
                    <th>类型/细分</th>
                    <th>支付渠道</th>
                    <th>金额</th>
                    <th>状态</th>
                    <th>创建时间</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
            <?php if ($orders): ?>
                <?php foreach ($orders as $order): ?>
                    <tr>
                        <td><?php echo intval($order->ID); ?></td>
                        <td><code><?php echo esc_html($order->order_id); ?></code><br><span class="description"><?php echo esc_html($order->order_title); ?></span></td>
                        <td><?php echo $order->pay_trade_no ? '<code>' . esc_html($order->pay_trade_no) . '</code>' : '-'; ?></td>
                        <td><?php echo pix_data_product_cell($order); ?></td>
                        <td><?php echo pix_data_buyer_cell($order); ?></td>
                        <td><?php echo esc_html(pix_data_order_type_label($order->order_type)); ?><br><span class="description"><?php echo esc_html(pix_data_product_subtype_label($order->product_subtype)); ?></span></td>
                        <td><?php echo esc_html(pix_data_order_pay_channel_label($order)); ?></td>
                        <td><?php echo pix_data_order_amount_cell($order); ?></td>
                        <td><?php echo esc_html(pix_data_order_status_label($order)); ?></td>
                        <td><?php echo esc_html($order->create_time); ?></td>
                        <td><?php echo pix_data_order_actions($order); ?></td>
                    </tr>
                <?php endforeach; ?>
            <?php else: ?>
                <tr><td colspan="11">暂无订单记录</td></tr>
            <?php endif; ?>
            </tbody>
        </table>
        <?php pix_data_pagination($total, $per_page, $paged); ?>
    </div>
    <?php
    pix_data_admin_inline_style();
}

function pix_data_admin_notify_logs_page(){
    if (!current_user_can('manage_options')) {
        wp_die('权限不足');
    }

    global $wpdb;
    $table = $wpdb->prefix . 'ppo_pay_notify_log';
    if (!pix_data_table_exists($table)) {
        pix_data_render_missing_table('支付回调日志表不存在，等下一次支付回调或进入后台初始化后会自动创建。');
        return;
    }

    $per_page = 20;
    $paged = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
    $offset = ($paged - 1) * $per_page;
    $where = array('1=1');

    $keyword = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
    if ($keyword !== '') {
        $like = '%' . $wpdb->esc_like($keyword) . '%';
        $where[] = $wpdb->prepare('(order_id LIKE %s OR trade_no LIKE %s OR message LIKE %s)', $like, $like, $like);
    }

    $success = isset($_GET['success']) ? sanitize_text_field($_GET['success']) : '';
    if ($success === '0' || $success === '1') {
        $where[] = $wpdb->prepare('success = %d', intval($success));
    }

    $channel = isset($_GET['channel']) ? sanitize_key($_GET['channel']) : '';
    if ($channel !== '') {
        $where[] = $wpdb->prepare('channel = %s', $channel);
    }

    $where_sql = implode(' AND ', $where);
    $total = intval($wpdb->get_var("SELECT COUNT(*) FROM $table WHERE $where_sql"));
    $logs = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM $table WHERE $where_sql ORDER BY ID DESC LIMIT %d OFFSET %d",
        $per_page,
        $offset
    ));
    ?>
    <div class="wrap pix-data-admin">
        <h1>支付回调日志</h1>
        <form method="get" class="pix-data-filter">
            <input type="hidden" name="page" value="ppo-pay-notify-logs">
            <input type="search" name="s" value="<?php echo esc_attr($keyword); ?>" placeholder="订单号 / 交易号 / 消息">
            <select name="success">
                <option value="">全部结果</option>
                <option value="1" <?php selected($success, '1'); ?>>成功</option>
                <option value="0" <?php selected($success, '0'); ?>>失败</option>
            </select>
            <input type="text" name="channel" value="<?php echo esc_attr($channel); ?>" placeholder="渠道，如 yipay">
            <?php submit_button('筛选', 'secondary', '', false); ?>
            <a class="button" href="<?php echo esc_url(admin_url('admin.php?page=ppo-pay-notify-logs')); ?>">重置</a>
        </form>

        <table class="wp-list-table widefat fixed striped pix-log-table">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>结果</th>
                    <th>渠道</th>
                    <th>订单号</th>
                    <th>交易号</th>
                    <th>金额</th>
                    <th>类型</th>
                    <th>IP</th>
                    <th>消息</th>
                    <th>时间</th>
                    <th>详情</th>
                </tr>
            </thead>
            <tbody>
            <?php if ($logs): ?>
                <?php foreach ($logs as $log): ?>
                    <tr>
                        <td><?php echo intval($log->ID); ?></td>
                        <td><?php echo $log->success ? '<span class="pix-badge success">成功</span>' : '<span class="pix-badge fail">失败</span>'; ?></td>
                        <td><?php echo esc_html($log->channel ?: '-'); ?></td>
                        <td><code><?php echo esc_html($log->order_id ?: '-'); ?></code></td>
                        <td><?php echo $log->trade_no ? '<code>' . esc_html($log->trade_no) . '</code>' : '-'; ?></td>
                        <td><?php echo esc_html(number_format(floatval($log->amount), 2)); ?></td>
                        <td><?php echo esc_html($log->request_type . ' / ' . $log->method); ?></td>
                        <td><?php echo esc_html($log->ip_address ?: '-'); ?></td>
                        <td><?php echo esc_html($log->message ?: $log->error_code); ?></td>
                        <td><?php echo esc_html($log->created_at); ?></td>
                        <td><button type="button" class="button button-small pix-toggle-log">查看</button></td>
                    </tr>
                    <tr class="pix-log-detail" style="display:none;">
                        <td colspan="11">
                            <strong>Payload</strong>
                            <pre><?php echo esc_html(pix_data_pretty_json($log->payload)); ?></pre>
                            <strong>Result</strong>
                            <pre><?php echo esc_html(pix_data_pretty_json($log->result)); ?></pre>
                        </td>
                    </tr>
                <?php endforeach; ?>
            <?php else: ?>
                <tr><td colspan="11">暂无回调日志</td></tr>
            <?php endif; ?>
            </tbody>
        </table>
        <?php pix_data_pagination($total, $per_page, $paged); ?>
    </div>
    <script>
    jQuery(function($){
        $('.pix-toggle-log').on('click', function(){
            $(this).closest('tr').next('.pix-log-detail').toggle();
        });
    });
    </script>
    <?php
    pix_data_admin_inline_style();
}

function pix_data_admin_order_edit_page(){
    if (!current_user_can('manage_options')) {
        wp_die('权限不足');
    }

    global $wpdb;
    $table = $wpdb->prefix . 'ppo_pay_order';
    $order_id = isset($_GET['order_id']) ? sanitize_text_field(wp_unslash($_GET['order_id'])) : '';
    $order = $order_id ? $wpdb->get_row($wpdb->prepare("SELECT * FROM $table WHERE order_id = %s", $order_id)) : null;
    if (!$order) {
        pix_data_render_missing_table('订单不存在');
        return;
    }

    $shipping_status = pix_data_string($order->shipping_status ?? '');
    $shipping_company = pix_data_string($order->shipping_company ?? '');
    $tracking_no = pix_data_string($order->tracking_no ?? '');
    $admin_note = pix_data_string($order->admin_note ?? '');
    $order_meta = pix_data_string($order->order_meta ?? '');
    $shipping_meta = pix_data_string($order->shipping_meta ?? '');
    $notify_logs = pix_data_get_order_notify_logs($order->order_id, $order->pay_trade_no ?? '');
    ?>
    <div class="wrap pix-data-admin">
        <h1>编辑订单</h1>
        <p><a href="<?php echo esc_url(admin_url('admin.php?page=ppo-admin-orders')); ?>">&larr; 返回订单管理</a></p>
        <?php if (!empty($_GET['updated'])): ?>
            <div class="notice notice-success is-dismissible"><p>订单已保存。</p></div>
        <?php endif; ?>

        <div class="pix-order-detail-grid">
            <?php
            pix_data_render_detail_card('订单信息', array(
                '订单号' => '<code>' . esc_html($order->order_id) . '</code>',
                '订单状态' => esc_html(pix_data_order_status_label($order)),
                '订单类型' => esc_html(pix_data_order_type_label($order->order_type)),
                '内容类型' => esc_html(pix_data_product_subtype_label($order->product_subtype)),
                '创建时间' => esc_html($order->create_time ?: '-'),
                '过期时间' => esc_html($order->expire_time ?: '-'),
                '支付时间' => esc_html($order->pay_time ?: '-'),
            ));

            pix_data_render_detail_card('商品信息', array(
                '商品' => pix_data_product_cell($order),
                '商品类型' => esc_html($order->product_type ?: '-'),
                '商品子类型' => esc_html(pix_data_product_subtype_label($order->product_subtype)),
                '商品ID' => esc_html(intval($order->product_id ?: $order->data_id)),
                '原始data_id' => esc_html($order->data_id ?: '-'),
                '订单标题' => esc_html($order->order_title ?: '-'),
            ));

            pix_data_render_detail_card('买家信息', array(
                '买家' => pix_data_buyer_cell($order),
                '用户ID' => esc_html(intval($order->user_id)),
                '收件/联系地址' => esc_html($order->order_address ?: '-'),
            ));

            pix_data_render_detail_card('支付信息', array(
                '支付渠道' => esc_html(pix_data_order_pay_channel_label($order)),
                '支付方式原值' => esc_html(($order->pay_type ?: '-') . ' / ' . ($order->pay_type_info ?: '-')),
                '支付金额' => pix_data_order_amount_cell($order),
                '购买数量' => esc_html($order->pay_count ?: '-'),
                '交易号' => $order->pay_trade_no ? '<code>' . esc_html($order->pay_trade_no) . '</code>' : '-',
                '卡密/授权码' => $order->order_license ? '<code>' . esc_html($order->order_license) . '</code>' : '-',
                '扩展值' => esc_html($order->order_extra ?: '-'),
            ));
            ?>
        </div>

        <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" class="pix-order-edit-form">
            <?php wp_nonce_field('pix_data_update_order_' . $order->order_id); ?>
            <input type="hidden" name="action" value="pix_data_update_order">
            <input type="hidden" name="order_id" value="<?php echo esc_attr($order->order_id); ?>">
            <div class="pix-order-edit-grid">
                <div class="pix-order-panel">
                    <h2>物流信息</h2>
                    <table class="form-table">
                        <tr>
                            <th><label for="shipping_status">物流状态</label></th>
                            <td><input type="text" class="regular-text" id="shipping_status" name="shipping_status" value="<?php echo esc_attr($shipping_status); ?>" placeholder="如：未发货 / 已发货 / 已签收"></td>
                        </tr>
                        <tr>
                            <th><label for="shipping_company">物流公司</label></th>
                            <td><input type="text" class="regular-text" id="shipping_company" name="shipping_company" value="<?php echo esc_attr($shipping_company); ?>"></td>
                        </tr>
                        <tr>
                            <th><label for="tracking_no">运单号</label></th>
                            <td><input type="text" class="regular-text" id="tracking_no" name="tracking_no" value="<?php echo esc_attr($tracking_no); ?>"></td>
                        </tr>
                    </table>
                </div>
                <div class="pix-order-panel">
                    <h2>后台备注</h2>
                    <textarea class="large-text" rows="8" id="admin_note" name="admin_note"><?php echo esc_textarea($admin_note); ?></textarea>
                    <p class="description">仅后台可见，用于记录人工处理、客服沟通或异常说明。</p>
                </div>
            </div>
            <?php submit_button('保存订单'); ?>
        </form>

        <div class="pix-order-detail-grid">
            <?php
            pix_data_render_raw_card('原始扩展字段', array(
                'order_content' => pix_data_string($order->order_content ?? ''),
                'order_meta' => $order_meta,
                'shipping_meta' => $shipping_meta,
            ));
            ?>
        </div>

        <div class="pix-order-panel pix-order-callback-panel">
            <div class="pix-order-panel-head">
                <h2>支付回调日志</h2>
                <a class="button button-small" href="<?php echo esc_url(admin_url('admin.php?page=ppo-pay-notify-logs&s=' . rawurlencode($order->order_id))); ?>">查看全部</a>
            </div>
            <?php pix_data_render_order_notify_logs($notify_logs, $order); ?>
        </div>
    </div>
    <script>
    jQuery(function($){
        $('.pix-order-log-toggle').on('click', function(){
            $(this).closest('tr').next('.pix-order-log-detail').toggle();
        });
    });
    </script>
    <?php
    pix_data_admin_inline_style();
}

function pix_data_handle_update_order(){
    if (!current_user_can('manage_options')) {
        wp_die('权限不足');
    }

    $order_id = isset($_POST['order_id']) ? sanitize_text_field(wp_unslash($_POST['order_id'])) : '';
    check_admin_referer('pix_data_update_order_' . $order_id);

    global $wpdb;
    $table = $wpdb->prefix . 'ppo_pay_order';
    $wpdb->update($table, array(
        'shipping_status' => isset($_POST['shipping_status']) ? sanitize_text_field(wp_unslash($_POST['shipping_status'])) : '',
        'shipping_company' => isset($_POST['shipping_company']) ? sanitize_text_field(wp_unslash($_POST['shipping_company'])) : '',
        'tracking_no' => isset($_POST['tracking_no']) ? sanitize_text_field(wp_unslash($_POST['tracking_no'])) : '',
        'admin_note' => isset($_POST['admin_note']) ? sanitize_textarea_field(wp_unslash($_POST['admin_note'])) : '',
    ), array('order_id' => $order_id));

    wp_redirect(add_query_arg(array('page' => 'ppo-admin-orders', 'action' => 'edit', 'order_id' => rawurlencode($order_id), 'updated' => 1), admin_url('admin.php')));
    exit;
}

function pix_data_handle_delete_order(){
    if (!current_user_can('manage_options')) {
        wp_die('权限不足');
    }

    $order_id = isset($_GET['order_id']) ? sanitize_text_field(wp_unslash($_GET['order_id'])) : '';
    check_admin_referer('pix_data_delete_order_' . $order_id);

    global $wpdb;
    $table = $wpdb->prefix . 'ppo_pay_order';
    $wpdb->update($table, array('deleted_at' => current_time('mysql')), array('order_id' => $order_id));

    wp_redirect(add_query_arg(array('page' => 'ppo-admin-orders', 'deleted_msg' => 1), admin_url('admin.php')));
    exit;
}

function pix_data_table_exists($table_name){
    global $wpdb;
    return $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $table_name)) === $table_name;
}

function pix_data_string($value){
    if ($value === null) {
        return '';
    }

    return (string)$value;
}

function pix_data_render_detail_card($title, $items){
    ?>
    <div class="pix-order-detail-card">
        <h2><?php echo esc_html($title); ?></h2>
        <dl>
            <?php foreach ($items as $label => $value): ?>
                <dt><?php echo esc_html($label); ?></dt>
                <dd><?php echo $value === '' ? '-' : $value; ?></dd>
            <?php endforeach; ?>
        </dl>
    </div>
    <?php
}

function pix_data_render_raw_card($title, $items){
    ?>
    <div class="pix-order-detail-card pix-order-raw-card">
        <h2><?php echo esc_html($title); ?></h2>
        <?php foreach ($items as $label => $value): ?>
            <h3><?php echo esc_html($label); ?></h3>
            <pre><?php echo esc_html($value !== '' ? pix_data_pretty_json($value) : '-'); ?></pre>
        <?php endforeach; ?>
    </div>
    <?php
}

function pix_data_get_order_notify_logs($order_id, $trade_no = ''){
    global $wpdb;
    $table = $wpdb->prefix . 'ppo_pay_notify_log';
    if (!pix_data_table_exists($table)) {
        return array();
    }

    $where = array();
    $args = array();
    if ($order_id !== '') {
        $where[] = 'order_id = %s';
        $args[] = $order_id;
    }
    if ($trade_no !== '') {
        $where[] = 'trade_no = %s';
        $args[] = $trade_no;
    }

    if (empty($where)) {
        return array();
    }

    $sql = "SELECT * FROM $table WHERE (" . implode(' OR ', $where) . ") ORDER BY ID DESC LIMIT 10";
    array_unshift($args, $sql);
    return $wpdb->get_results(call_user_func_array(array($wpdb, 'prepare'), $args));
}

function pix_data_render_order_notify_logs($logs, $order = null){
    if (empty($logs)) {
        $pay_type = $order && isset($order->pay_type) ? (string)$order->pay_type : '';
        $pay_type_info = $order && isset($order->pay_type_info) ? (string)$order->pay_type_info : '';
        $internal_types = array('balance', 'credit', 'card', 'card_auth', 'card_balance', 'card_credit');
        $is_internal = in_array($pay_type, $internal_types, true) || in_array($pay_type_info, $internal_types, true);

        if ($is_internal) {
            echo '<div class="pix-empty-note"><strong>暂无外部支付回调</strong><p>当前订单使用的是站内资产或卡密支付，这类支付会直接在本站完成扣款/兑换，不会请求第三方网关，因此不会产生支付回调日志。请查看上方支付信息、订单状态和钱包流水。</p></div>';
        } else {
            echo '<div class="pix-empty-note"><strong>暂无该订单相关回调日志</strong><p>外部支付只有在支付宝、微信、虎皮椒、易支付等网关请求本站 notify/return 地址时才会记录日志。如果用户尚未完成支付，或网关没有成功回调，这里会暂时为空。</p></div>';
        }
        return;
    }
    ?>
    <table class="wp-list-table widefat fixed striped pix-order-log-table">
        <thead>
            <tr>
                <th>结果</th>
                <th>渠道</th>
                <th>交易号</th>
                <th>金额</th>
                <th>类型</th>
                <th>IP</th>
                <th>消息</th>
                <th>时间</th>
                <th>详情</th>
            </tr>
        </thead>
        <tbody>
        <?php foreach ($logs as $log): ?>
            <tr>
                <td><?php echo $log->success ? '<span class="pix-badge success">成功</span>' : '<span class="pix-badge fail">失败</span>'; ?></td>
                <td><?php echo esc_html($log->channel ?: '-'); ?></td>
                <td><?php echo $log->trade_no ? '<code>' . esc_html($log->trade_no) . '</code>' : '-'; ?></td>
                <td><?php echo esc_html(number_format(floatval($log->amount), 2)); ?></td>
                <td><?php echo esc_html($log->request_type . ' / ' . $log->method); ?></td>
                <td><?php echo esc_html($log->ip_address ?: '-'); ?></td>
                <td><?php echo esc_html($log->message ?: $log->error_code ?: '-'); ?></td>
                <td><?php echo esc_html($log->created_at); ?></td>
                <td><button type="button" class="button button-small pix-order-log-toggle">查看</button></td>
            </tr>
            <tr class="pix-order-log-detail" style="display:none;">
                <td colspan="9">
                    <strong>Payload</strong>
                    <pre><?php echo esc_html(pix_data_pretty_json($log->payload)); ?></pre>
                    <strong>Result</strong>
                    <pre><?php echo esc_html(pix_data_pretty_json($log->result)); ?></pre>
                </td>
            </tr>
        <?php endforeach; ?>
        </tbody>
    </table>
    <?php
}

function pix_data_render_missing_table($message){
    ?>
    <div class="wrap"><h1>PIX数据管理</h1><div class="notice notice-warning"><p><?php echo esc_html($message); ?></p></div></div>
    <?php
}

function pix_data_order_type_labels(){
    return array(
        'vip' => '会员购买',
        'post' => '文章购买',
        'mj' => '圈子订阅',
        'jfcz' => '积分充值',
        'yecz' => '余额充值',
    );
}

function pix_data_product_subtype_labels(){
    return array(
        'read' => '付费阅读',
        'down' => '付费下载',
        'video' => '付费视频',
        'gallary' => '付费图集',
        'gallery' => '付费图集',
        'm' => '月费',
        'q' => '季费',
        'y' => '年费',
        'jfcz' => '积分充值',
        'yecz' => '余额充值',
        'physical' => '实物商品',
        'virtual' => '虚拟商品',
    );
}

function pix_data_product_subtype_label($subtype){
    if (empty($subtype)) {
        return '-';
    }

    $labels = pix_data_product_subtype_labels();
    return isset($labels[$subtype]) ? $labels[$subtype] : $subtype;
}

function pix_data_order_type_label($type){
    $labels = pix_data_order_type_labels();
    return isset($labels[$type]) ? $labels[$type] : ($type ?: '其他');
}

function pix_data_pay_channel_labels(){
    return array(
        'alipay_normal' => '支付宝官方',
        'wepay_normal' => '微信官方',
        'alipay_hupijiao' => '虎皮椒支付宝',
        'wepay_hupijiao' => '虎皮椒微信',
        'card_auth' => '卡密兑换授权',
        'card_balance' => '卡密兑换余额',
        'card_credit' => '卡密兑换积分',
        'card' => '卡密兑换',
        'balance' => '余额',
        'credit' => '积分',
        'yipay' => '易支付',
        'alipay' => '支付宝',
        'wepay' => '微信',
    );
}

function pix_data_pay_channel_label($channel){
    if (empty($channel)) {
        return '-';
    }

    $labels = pix_data_pay_channel_labels();
    return isset($labels[$channel]) ? $labels[$channel] : $channel;
}

function pix_data_order_pay_channel_label($order){
    $pay_type = isset($order->pay_type) ? (string)$order->pay_type : '';
    $pay_type_info = isset($order->pay_type_info) ? (string)$order->pay_type_info : '';
    $trade_no = isset($order->pay_trade_no) ? (string)$order->pay_trade_no : '';

    if (in_array($pay_type_info, array('card_auth', 'card_balance', 'card_credit'), true)) {
        return pix_data_pay_channel_label($pay_type_info);
    }

    if ($pay_type === 'card' || pix_data_looks_like_card_code($pay_type_info) || pix_data_looks_like_card_code($trade_no)) {
        $card_type = pix_data_get_card_type_by_order($order);
        if ($card_type) {
            return pix_data_pay_channel_label($card_type);
        }

        if (!empty($order->order_license) || $order->order_type === 'post') {
            return '卡密兑换授权';
        }

        return '卡密兑换';
    }

    return pix_data_pay_channel_label($pay_type_info ?: $pay_type);
}

function pix_data_get_card_type_by_order($order){
    global $wpdb;
    $card_table = $wpdb->prefix . 'ppo_cards';
    if (!pix_data_table_exists($card_table)) {
        return '';
    }

    $codes = array();
    foreach (array($order->pay_trade_no ?? '', $order->pay_type_info ?? '') as $code) {
        $code = strtoupper(trim((string)$code));
        if (pix_data_looks_like_card_code($code)) {
            $codes[] = $code;
        }
    }

    $codes = array_values(array_unique($codes));
    foreach ($codes as $code) {
        $type = $wpdb->get_var($wpdb->prepare("SELECT type FROM $card_table WHERE code = %s LIMIT 1", $code));
        if ($type) {
            return sanitize_key($type);
        }
    }

    return '';
}

function pix_data_looks_like_card_code($value){
    return is_string($value) && preg_match('/^[A-Z0-9]{16}$/', strtoupper(trim($value)));
}

function pix_data_product_cell($order){
    $product_id = !empty($order->product_id) ? intval($order->product_id) : intval($order->data_id);
    $title = !empty($order->product_title) ? $order->product_title : $order->order_title;

    if ($order->order_type === 'post' && $product_id > 0) {
        $post_title = get_the_title($product_id);
        $title = $post_title ? $post_title : $title;
        $edit_link = get_edit_post_link($product_id);
        $html = $edit_link
            ? '<a href="' . esc_url($edit_link) . '">' . esc_html($title) . '</a>'
            : esc_html($title);
        $html .= '<br><span class="description">文章ID: ' . intval($product_id) . '</span>';
        return $html;
    }

    $html = esc_html($title ?: '-');
    if ($product_id > 0) {
        $html .= '<br><span class="description">商品ID: ' . intval($product_id) . '</span>';
    }

    return $html;
}

function pix_data_buyer_cell($order){
    $user = intval($order->user_id) > 0 ? get_userdata(intval($order->user_id)) : false;
    $name = !empty($order->buyer_name) ? $order->buyer_name : ($user ? $user->display_name : '');
    $email = !empty($order->buyer_email) ? $order->buyer_email : ($user ? $user->user_email : '');

    $html = esc_html($name ?: '未知用户') . '<br><span class="description">ID: ' . intval($order->user_id);
    if ($email) {
        $html .= ' / ' . esc_html($email);
    }
    $html .= '</span>';

    return $html;
}

function pix_data_order_actions($order){
    $edit_url = add_query_arg(array(
        'page' => 'ppo-admin-orders',
        'action' => 'edit',
        'order_id' => rawurlencode($order->order_id),
    ), admin_url('admin.php'));
    $delete_url = wp_nonce_url(
        admin_url('admin-post.php?action=pix_data_delete_order&order_id=' . rawurlencode($order->order_id)),
        'pix_data_delete_order_' . $order->order_id
    );

    $html = '<a class="button button-small" href="' . esc_url($edit_url) . '">编辑</a> ';
    if (empty($order->deleted_at)) {
        $html .= '<a class="button button-small" href="' . esc_url($delete_url) . '" onclick="return confirm(\'确定删除该订单吗？已支付订单会软删除，不会从数据库物理移除。\')">删除</a>';
    } else {
        $html .= '<span class="description">已删除</span>';
    }

    return $html;
}

function pix_data_order_amount_cell($order){
    $pay_amount = number_format(floatval($order->total_price), 2);
    $pay_type_info = isset($order->pay_type_info) ? (string)$order->pay_type_info : '';

    if ($pay_type_info === 'card_balance') {
        return esc_html($pay_amount) . '<br><span class="description">兑换余额：¥' . esc_html(number_format(floatval($order->order_extra), 2)) . '</span>';
    }

    if ($pay_type_info === 'card_credit') {
        return esc_html($pay_amount) . '<br><span class="description">兑换积分：' . esc_html(number_format_i18n(intval($order->order_extra))) . '</span>';
    }

    if ($order->order_type === 'yecz' && floatval($order->order_extra) > 0 && floatval($order->total_price) <= 0) {
        return esc_html($pay_amount) . '<br><span class="description">到账余额：¥' . esc_html(number_format(floatval($order->order_extra), 2)) . '</span>';
    }

    if ($order->order_type === 'jfcz' && floatval($order->order_extra) > 0 && floatval($order->total_price) <= 0) {
        return esc_html($pay_amount) . '<br><span class="description">到账积分：' . esc_html(number_format_i18n(intval($order->order_extra))) . '</span>';
    }

    return esc_html($pay_amount);
}

function pix_data_order_status_label($order){
    if (!empty($order->deleted_at)) {
        return '已删除';
    }

    if (intval($order->status) === 1) {
        return '已支付';
    }

    $status = intval($order->order_status);
    if (class_exists('PixOrder')) {
        if ($status === PixOrder::STATUS_CANCEL) return '已取消';
        if ($status === PixOrder::STATUS_CLOSED) return '已关闭';
    }

    return '待支付';
}

function pix_data_user_label($user_id){
    $user_id = intval($user_id);
    $user = $user_id > 0 ? get_userdata($user_id) : false;
    return $user ? $user->display_name . ' (ID:' . $user_id . ')' : 'ID:' . $user_id;
}

function pix_data_pretty_json($json){
    $decoded = json_decode((string)$json, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        return (string)$json;
    }

    return wp_json_encode($decoded, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}

function pix_data_pagination($total, $per_page, $paged, $extra_args = array()){
    $total_pages = (int)ceil($total / $per_page);
    if ($total_pages <= 1) {
        return;
    }

    $from = ($paged - 1) * $per_page + 1;
    $to = min($total, $paged * $per_page);

    echo '<div class="pix-data-pagination">';
    echo '<div class="pix-data-page-info">共 <strong>' . esc_html(number_format_i18n($total)) . '</strong> 条，当前 ' . esc_html(number_format_i18n($from)) . '-' . esc_html(number_format_i18n($to)) . ' 条</div>';
    echo '<div class="pix-data-page-links">';
    $base_args = is_array($extra_args) ? array_merge($extra_args, array('paged' => '%#%')) : array('paged' => '%#%');
    echo paginate_links(array(
        'base' => add_query_arg($base_args),
        'format' => '',
        'prev_text' => '上一页',
        'next_text' => '下一页',
        'total' => $total_pages,
        'current' => $paged,
        'mid_size' => 2,
        'end_size' => 1,
    ));
    echo '</div></div>';
}

function pix_data_admin_inline_style(){
    ?>
    <style>
        .pix-data-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px;margin-top:18px;max-width:920px}
        .pix-data-card{display:block;padding:18px 20px;background:#fff;border:1px solid #dcdcde;border-radius:10px;text-decoration:none;box-shadow:0 1px 2px rgba(0,0,0,.04)}
        .pix-data-card span{display:block;color:#646970;margin-bottom:10px}
        .pix-data-card strong{font-size:28px;color:#1d2327}
        .pix-data-filter{display:flex;gap:8px;align-items:center;margin:14px 0 16px;flex-wrap:wrap}
        .pix-data-filter input[type="search"]{min-width:280px}
        .pix-data-filter input[type="date"]{min-width:145px}
        .pix-data-filter input[type="number"]{width:110px}
        .pix-badge{display:inline-block;padding:2px 8px;border-radius:999px;font-size:12px;font-weight:600}
        .pix-badge.success{background:#e7f7ed;color:#147a3d}
        .pix-badge.fail{background:#fde8e8;color:#b42318}
        .pix-log-detail pre{max-height:320px;overflow:auto;background:#f6f7f7;border:1px solid #dcdcde;padding:12px;white-space:pre-wrap}
        .pix-data-pagination{display:flex;align-items:center;justify-content:space-between;gap:14px;margin:18px 0 8px;padding:14px 16px;background:#fff;border:1px solid #dcdcde;border-radius:12px;box-shadow:0 1px 2px rgba(0,0,0,.04)}
        .pix-data-page-info{color:#646970;font-size:13px}
        .pix-data-page-info strong{color:#1d2327}
        .pix-data-page-links{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
        .pix-data-page-links .page-numbers{display:inline-flex;align-items:center;justify-content:center;min-width:34px;height:34px;padding:0 11px;border:1px solid #dcdcde;border-radius:9px;background:#f6f7f7;color:#1d2327;text-decoration:none;font-weight:500;line-height:1;transition:all .15s ease}
        .pix-data-page-links a.page-numbers:hover{border-color:#2271b1;background:#f0f6fc;color:#135e96;box-shadow:0 0 0 1px rgba(34,113,177,.08)}
        .pix-data-page-links .page-numbers.current{border-color:#2271b1;background:#2271b1;color:#fff;box-shadow:0 4px 10px rgba(34,113,177,.22)}
        .pix-data-page-links .page-numbers.dots{border-color:transparent;background:transparent;color:#8c8f94;min-width:22px;padding:0 4px}
        .pix-data-page-links .prev,.pix-data-page-links .next{min-width:auto;padding:0 14px}
        .pix-order-detail-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:16px;margin:16px 0}
        .pix-order-detail-card,.pix-order-panel{background:#fff;border:1px solid #dcdcde;border-radius:12px;box-shadow:0 1px 2px rgba(0,0,0,.04);padding:18px 20px}
        .pix-order-detail-card h2,.pix-order-panel h2{margin:0 0 14px;color:#1d2327;font-size:16px;font-weight:600}
        .pix-order-detail-card dl{display:grid;grid-template-columns:108px minmax(0,1fr);gap:10px 14px;margin:0}
        .pix-order-detail-card dt{color:#646970}
        .pix-order-detail-card dd{margin:0;color:#1d2327;word-break:break-word}
        .pix-order-detail-card .description{color:#646970}
        .pix-order-edit-grid{display:grid;grid-template-columns:minmax(320px,1fr) minmax(320px,1fr);gap:16px;margin-top:16px}
        .pix-order-panel .form-table{margin-top:0}
        .pix-order-panel .form-table th{width:96px;padding-left:0}
        .pix-order-panel textarea.large-text{width:100%}
        .pix-order-panel-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px}
        .pix-order-panel-head h2{margin:0}
        .pix-order-raw-card{grid-column:1/-1}
        .pix-order-raw-card h3{margin:14px 0 6px;color:#646970;font-size:13px;font-weight:600}
        .pix-order-raw-card pre,.pix-order-log-detail pre{max-height:260px;overflow:auto;background:#f6f7f7;border:1px solid #dcdcde;border-radius:8px;padding:12px;white-space:pre-wrap}
        .pix-order-callback-panel{margin-top:16px}
        .pix-order-log-table code{white-space:normal;word-break:break-all}
        .pix-order-edit-form .submit{margin-top:12px}
        .pix-empty-note{padding:14px 16px;background:#f6f7f7;border:1px dashed #c3c4c7;border-radius:10px;color:#646970}
        .pix-empty-note strong{display:block;margin-bottom:6px;color:#1d2327}
        .pix-empty-note p{margin:0;line-height:1.7}
        .pix-wallet-adjust-layout{display:grid;grid-template-columns:minmax(420px,1fr) 360px;gap:16px;margin-top:18px;max-width:1080px}
        .pix-wallet-adjust-form .form-table th{width:96px}
        .pix-wallet-adjust-user{height:max-content}
        .pix-wallet-user-card{padding:14px;border:1px solid #e5e7eb;border-radius:12px;background:#f8fafc}
        .pix-wallet-user-name{font-size:18px;color:#1d2327;margin-bottom:4px}
        .pix-wallet-assets{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:16px}
        .pix-wallet-assets div{padding:14px;border-radius:12px;background:#fff;border:1px solid #e5e7eb}
        .pix-wallet-assets span{display:block;color:#646970;margin-bottom:8px}
        .pix-wallet-assets strong{font-size:22px;color:#2271b1}
        @media (max-width:1100px){.pix-wallet-adjust-layout{grid-template-columns:1fr}}
        @media (max-width:1100px){.pix-order-edit-grid{grid-template-columns:1fr}}
        @media (max-width:782px){.pix-data-pagination{align-items:flex-start;flex-direction:column}.pix-data-page-links .page-numbers{min-width:32px;height:32px}}
    </style>
    <?php
}
