<?php
/**
 * StablePay 支付网关
 *
 * @package StablePay_WooCommerce
 */

// 防止直接访问
if (!defined('ABSPATH')) {
    exit;
}

/**
 * WC_StablePay_Gateway 类
 *
 * 继承 WC_Payment_Gateway，实现 StablePay 支付网关
 */
class WC_StablePay_Gateway extends WC_Payment_Gateway {
    /**
     * 金额格式配置
     *
     * true: 使用最小单位（当前 API 要求，USDT/USDC 为 6 位精度，如 1 USDT = 1000000）
     * false: 使用面额小数（未来 API 版本，如 1 USDT = "1.00"）
     *
     * @var bool
     */
    const USE_SMALLEST_UNIT = false;

    /**
     * API 客户端
     *
     * @var StablePay_API_Client
     */
    private $api_client;

    /**
     * Webhook 处理器
     *
     * @var StablePay_Webhook_Handler
     */
    private $webhook_handler;

    /**
     * 退款管理器
     *
     * @var StablePay_Refund_Manager
     */
    private $refund_manager;

    /**
     * 日志记录器
     *
     * @var StablePay_Logger
     */
    private $logger;

    /**
     * 构造函数
     */
    public function __construct() {
        // 基本配置
        $this->id = 'stablepay';
        $this->icon = apply_filters('woocommerce_stablepay_icon', STABLEPAY_WC_PLUGIN_URL . 'assets/images/logo.svg');
        $this->has_fields = false;
        $this->method_title = __('StablePay', 'stablepay-woocommerce');
        $this->method_description = __('为 WooCommerce 商城接入 StablePay 稳定币支付能力', 'stablepay-woocommerce');
        $this->supports = array(
            'products',
            'refunds',
        );

        // 加载配置
        $this->init_form_fields();
        $this->init_settings();

        // 加载配置项
        $this->enabled = $this->get_option('enabled');
        $this->title = $this->get_option('title');
        $this->description = $this->get_option('description');

        // 初始化组件
        $this->init_components();

        // 注册钩子
        add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
        add_action('woocommerce_admin_order_data_after_order_details', array($this, 'display_order_meta'));
    }

    /**
     * 初始化组件
     */
    private function init_components() {
        // 初始化日志记录器
        $log_enabled = $this->get_option('debug', 'no') === 'yes';
        $log_level = $this->get_option('log_level', 'info');
        $this->logger = new StablePay_Logger($log_enabled, $log_level);

        // 初始化 API 客户端
        $api_key = $this->get_option('api_key');
        $secret_key = $this->get_option('secret_key');
        $environment = $this->get_option('environment', 'dev');

        if (!empty($api_key) && !empty($secret_key)) {
            $this->api_client = new StablePay_API_Client(
                $api_key,
                $secret_key,
                $environment,
                $this->logger
            );

            // 初始化退款管理器
            $this->refund_manager = new StablePay_Refund_Manager($this->api_client, $this->logger);
        } else {
            // 仅在支付功能被启用但配置不完整时记录错误（管理员可追溯问题）
            if ($this->enabled === 'yes') {
                $this->logger->error('StablePay 支付已启用但 API 配置不完整，支付和退款功能将不可用', array(
                    'has_api_key' => !empty($api_key),
                    'has_secret_key' => !empty($secret_key),
                ));
            }
        }

        // Webhook 处理器已在插件主文件中初始化（stablepay_wc_init_webhook_handler）
        global $stablepay_webhook_handler;
        if ($stablepay_webhook_handler) {
            $this->webhook_handler = $stablepay_webhook_handler;
        }
    }

    /**
     * 初始化配置表单字段
     */
    public function init_form_fields() {
        $this->form_fields = array(
            'enabled' => array(
                'title' => __('启用/禁用', 'stablepay-woocommerce'),
                'type' => 'checkbox',
                'label' => __('启用 StablePay 支付', 'stablepay-woocommerce'),
                'default' => 'no',
            ),
            'title' => array(
                'title' => __('支付标题', 'stablepay-woocommerce'),
                'type' => 'text',
                'description' => __('在结账页面显示的支付方式名称', 'stablepay-woocommerce'),
                'default' => 'USDT | USDC Stablecoin Payment',
                'desc_tip' => true,
            ),
            'description' => array(
                'title' => __('支付描述', 'stablepay-woocommerce'),
                'type' => 'textarea',
                'description' => __('在结账页面显示的支付方式说明', 'stablepay-woocommerce'),
                'default' => 'Metamask | Trust Wallet | Bitget Wallet | Imtoken | Token Pocket and more',
                'desc_tip' => true,
            ),
            'api_settings' => array(
                'title' => __('API 配置', 'stablepay-woocommerce'),
                'type' => 'title',
                'description' => __('配置 StablePay API 密钥。请在 StablePay 商户后台获取密钥信息。', 'stablepay-woocommerce'),
            ),
            'environment' => array(
                'title' => __('环境模式', 'stablepay-woocommerce'),
                'type' => 'select',
                'description' => __('选择使用测试环境、预发环境或生产环境', 'stablepay-woocommerce'),
                'default' => 'dev',
                'options' => array(
                    'dev' => __('测试环境', 'stablepay-woocommerce'),
                    'staging' => __('预发环境', 'stablepay-woocommerce'),
                    'production' => __('生产环境', 'stablepay-woocommerce'),
                ),
                'desc_tip' => true,
            ),
            'api_key' => array(
                'title' => __('API Key', 'stablepay-woocommerce'),
                'type' => 'text',
                'description' => __('StablePay API 密钥', 'stablepay-woocommerce'),
                'desc_tip' => true,
            ),
            'secret_key' => array(
                'title' => __('Secret Key', 'stablepay-woocommerce'),
                'type' => 'password',
                'description' => __('StablePay Secret Key，用于签名', 'stablepay-woocommerce'),
                'desc_tip' => true,
            ),
            'webhook_secret' => array(
                'title' => __('Webhook Secret', 'stablepay-woocommerce'),
                'type' => 'password',
                'description' => sprintf(
                    __('用于验证 Webhook 签名的密钥。Webhook URL: %s', 'stablepay-woocommerce'),
                    get_rest_url(null, 'stablepay/v1/webhook')
                ),
            ),
            'payment_options' => array(
                'title' => __('支付选项', 'stablepay-woocommerce'),
                'type' => 'title',
                'description' => '',
            ),
            'payment_timeout' => array(
                'title' => __('支付超时时间', 'stablepay-woocommerce'),
                'type' => 'number',
                'description' => __('支付会话有效期（分钟）', 'stablepay-woocommerce'),
                'default' => '30',
                'custom_attributes' => array(
                    'min' => '5',
                    'max' => '120',
                ),
                'desc_tip' => true,
            ),
            'order_prefix' => array(
                'title' => __('订单前缀', 'stablepay-woocommerce'),
                'type' => 'text',
                'description' => __('StablePay 订单号前缀', 'stablepay-woocommerce'),
                'default' => 'WC-',
                'desc_tip' => true,
            ),
            'status_mapping' => array(
                'title' => __('订单状态映射', 'stablepay-woocommerce'),
                'type' => 'title',
                'description' => __('配置支付状态与 WooCommerce 订单状态的映射关系', 'stablepay-woocommerce'),
            ),
            'pending_status' => array(
                'title' => __('支付确认中状态', 'stablepay-woocommerce'),
                'type' => 'select',
                'description' => __('支付确认中时订单的状态', 'stablepay-woocommerce'),
                'default' => 'pending',
                'options' => array(
                    'pending' => __('待支付', 'stablepay-woocommerce'),
                    'on-hold' => __('等待确认', 'stablepay-woocommerce'),
                ),
                'desc_tip' => true,
            ),
            'completed_status' => array(
                'title' => __('支付成功状态', 'stablepay-woocommerce'),
                'type' => 'select',
                'description' => __('支付成功时订单的状态', 'stablepay-woocommerce'),
                'default' => 'processing',
                'options' => array(
                    'processing' => __('处理中', 'stablepay-woocommerce'),
                    'completed' => __('已完成', 'stablepay-woocommerce'),
                ),
                'desc_tip' => true,
            ),
            'advanced_settings' => array(
                'title' => __('高级设置', 'stablepay-woocommerce'),
                'type' => 'title',
            ),
            'debug' => array(
                'title' => __('启用调试日志', 'stablepay-woocommerce'),
                'type' => 'checkbox',
                'label' => __('记录插件运行日志', 'stablepay-woocommerce'),
                'default' => 'no',
                'description' => sprintf(
                    __('日志文件位于：%s', 'stablepay-woocommerce'),
                    '<code>WooCommerce > 状态 > 日志</code>'
                ),
            ),
            'log_level' => array(
                'title' => __('日志级别', 'stablepay-woocommerce'),
                'type' => 'select',
                'default' => 'info',
                'options' => array(
                    'error' => __('错误', 'stablepay-woocommerce'),
                    'warning' => __('警告', 'stablepay-woocommerce'),
                    'info' => __('信息', 'stablepay-woocommerce'),
                    'debug' => __('调试', 'stablepay-woocommerce'),
                ),
            ),
        );
    }

    /**
     * 处理支付
     *
     * @param int $order_id 订单 ID
     * @return array 重定向信息
     */
    public function process_payment($order_id) {
        $this->logger->info('开始处理支付请求', array('order_id' => $order_id));

        $order = wc_get_order($order_id);

        if (!$order) {
            $this->logger->error('订单不存在', array('order_id' => $order_id));
            wc_add_notice(__('订单不存在', 'stablepay-woocommerce'), 'error');
            return array('result' => 'failure');
        }

        $this->logger->debug('获取订单信息', array(
            'order_id' => $order_id,
            'order_number' => $order->get_order_number(),
            'order_total' => $order->get_total(),
            'order_currency' => $order->get_currency(),
            'order_status' => $order->get_status(),
            'customer_email' => $order->get_billing_email(),
        ));

        // 验证 API 配置
        if (!$this->api_client) {
            $this->logger->error('API 客户端未初始化，无法处理支付', array('order_id' => $order_id));
            wc_add_notice(__('支付配置错误，请联系商家', 'stablepay-woocommerce'), 'error');
            return array('result' => 'failure');
        }

        // 构造支付参数
        $params = $this->build_payment_params($order);

        // 获取客户端 IP
        $client_ip = $this->get_client_ip();

        // 构造额外的 HTTP 请求头
        $extra_headers = array();
        if (!empty($client_ip)) {
            $extra_headers['X-Real-IP'] = $client_ip;
            $extra_headers['X-Forwarded-For'] = $client_ip;
        }

        // 记录日志
        $this->logger->info('创建支付会话', array(
            'order_id' => $order_id,
            'amount' => $order->get_total(),
            'client_ip' => $client_ip,
        ));

        $this->logger->debug('支付请求参数', array(
            'order_id' => $order_id,
            'params' => $params,
            'extra_headers' => array_keys($extra_headers),
        ));

        // 调用 API 创建支付会话
        $response = $this->api_client->create_checkout_session($params, $extra_headers);

        // 检查响应
        if (is_wp_error($response)) {
            $this->logger->error('创建支付会话失败', array(
                'order_id' => $order_id,
                'error_code' => $response->get_error_code(),
                'error_message' => $response->get_error_message(),
                'error_data' => $response->get_error_data(),
            ));
            wc_add_notice(__('创建支付失败：', 'stablepay-woocommerce') . $response->get_error_message(), 'error');
            return array('result' => 'failure');
        }

        $this->logger->debug('支付会话创建成功', array(
            'order_id' => $order_id,
            'session_id' => $response['id'],
            'redirect_url' => $response['url'],
        ));

        // 保存会话信息到订单
        $order->update_meta_data('_stablepay_session_id', $response['id']);
        $order->update_meta_data('_stablepay_currency', $response['currency']);
        $order->save();

        // 添加订单备注
        $order->add_order_note(sprintf(
            __('StablePay 支付会话已创建。会话 ID: %s', 'stablepay-woocommerce'),
            $response['id']
        ));

        // 清除会话中的 order_awaiting_payment，确保下次结账创建新订单
        // 这是因为外部支付网关（如 StablePay）在用户支付完成前不会更新订单状态
        // 如果不清除，用户取消支付后再次购物会复用旧订单
        if (function_exists('WC') && WC()->session) {
            WC()->session->set('order_awaiting_payment', false);
            $this->logger->debug('已清除 order_awaiting_payment 会话', array('order_id' => $order_id));
        }

        // 清空购物车（订单已创建，重定向到支付页面）
        if (function_exists('WC') && WC()->cart) {
            WC()->cart->empty_cart();
            $this->logger->debug('已清空购物车', array('order_id' => $order_id));
        }

        $this->logger->info('支付请求处理完成，准备重定向', array(
            'order_id' => $order_id,
            'session_id' => $response['id'],
        ));

        // 返回重定向信息
        return array(
            'result' => 'success',
            'redirect' => $response['url'],
        );
    }

    /**
     * 获取货币的小数位数
     *
     * @param string $currency 货币代码
     * @return int 小数位数
     */
    private function get_currency_decimals($currency) {
        // 零小数位货币列表（与 stablepay-common/money/currency.go 保持一致）
        $zero_decimal_currencies = array(
            'IDR', // 印尼盾
            'JPY', // 日元
            'VND', // 越南盾
            'KRW', // 韩元
        );

        if (in_array(strtoupper($currency), $zero_decimal_currencies)) {
            return 0;
        }

        // 默认 2 位小数（大多数货币如 USD, EUR, CNY 等）
        return 2;
    }

    /**
     * 格式化金额，根据 API 要求和货币精度转换为对应格式
     *
     * @param float $amount 金额
     * @param string|null $currency 货币代码（可选，默认使用订单货币）
     * @return int|string 根据 USE_SMALLEST_UNIT 配置返回最小单位（int）或面额字符串（string）
     */
    private function format_amount($amount, $currency = null) {
        // 获取货币的小数位数
        $decimals = $currency ? $this->get_currency_decimals($currency) : 2;

        if (self::USE_SMALLEST_UNIT) {
            // 当前 API 版本：使用最小单位
            // 例如：1 USD = 100，0.01 USD = 1；1 IDR = 1（无小数）
            $multiplier = pow(10, $decimals);
            return (int)round((float)$amount * $multiplier);
        } else {
            // 使用面额字符串，根据货币精度格式化
            // 例如：USD "1.00"，IDR "101"（无小数）
            return number_format((float)$amount, $decimals, '.', '');
        }
    }

    /**
     * 获取客户端真实 IP 地址
     *
     * @return string 客户端 IP 地址
     */
    private function get_client_ip() {
        // 优先检查代理服务器设置的 IP 头
        $headers = array(
            'HTTP_CF_CONNECTING_IP',    // Cloudflare
            'HTTP_X_REAL_IP',            // Nginx proxy
            'HTTP_X_FORWARDED_FOR',      // Standard proxy header
            'HTTP_CLIENT_IP',            // Proxy header
            'REMOTE_ADDR',               // Fallback to direct connection IP
        );

        $checked_headers = array();
        foreach ($headers as $header) {
            if (!empty($_SERVER[$header])) {
                $ip_list = $_SERVER[$header];
                $checked_headers[$header] = $ip_list;

                // X-Forwarded-For 可能包含多个 IP，取第一个（客户端 IP）
                if ($header === 'HTTP_X_FORWARDED_FOR') {
                    $ips = array_map('trim', explode(',', $ip_list));
                    $ip = $ips[0];
                } else {
                    $ip = $ip_list;
                }

                // 验证 IP 格式
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                    $this->logger->debug('获取客户端 IP', array(
                        'ip' => $ip,
                        'source_header' => $header,
                        'is_public' => true,
                    ));
                    return $ip;
                }

                // 如果 IP 是私有地址（本地测试环境），也返回
                if (filter_var($ip, FILTER_VALIDATE_IP)) {
                    $this->logger->debug('获取客户端 IP（私有地址）', array(
                        'ip' => $ip,
                        'source_header' => $header,
                        'is_public' => false,
                    ));
                    return $ip;
                }
            }
        }

        // 默认返回空字符串
        $this->logger->debug('无法获取客户端 IP', array(
            'checked_headers' => $checked_headers,
        ));
        return '';
    }

    /**
     * 构造支付参数
     *
     * @param WC_Order $order 订单对象
     * @return array 支付参数
     */
    private function build_payment_params($order) {
        // 获取配置
        $timeout = (int)$this->get_option('payment_timeout', 30);
        $order_prefix = $this->get_option('order_prefix', 'WC-');

        // 构造订单商品明细
        $line_items = array();
        $items = $order->get_items();

        // 获取订单币种（通常是 USD）
        $order_currency = $order->get_currency();

        if (!empty($items)) {
            foreach ($items as $item) {
                $line_items[] = array(
                    'price_data' => array(
                        'currency' => $order_currency,
                        'unit_amount' => $this->format_amount($order->get_item_total($item, true), $order_currency),
                        'product_data' => array(
                            'name' => $item->get_name(),
                            'description' => '',
                        ),
                    ),
                    'quantity' => (int)$item->get_quantity(),
                );
            }
        } else {
            // 没有商品明细，使用订单总额
            $line_items[] = array(
                'price_data' => array(
                    'currency' => $order_currency,
                    'unit_amount' => $this->format_amount($order->get_total(), $order_currency),
                    'product_data' => array(
                        'name' => sprintf(__('订单 #%s', 'stablepay-woocommerce'), $order->get_order_number()),
                        'description' => '',
                    ),
                ),
                'quantity' => 1,
            );
        }

        // 构造回调 URL
        $success_url = $this->get_return_url($order);
        $cancel_url = wc_get_checkout_url();

        // 计算过期时间
        $expires_at = time() + ($timeout * 60);

        // 构造订单号（用于关联 WooCommerce 订单，添加时间戳避免重复）
        $order_id_str = $order_prefix . $order->get_id() . '-' . time();

        // 获取运费和税费（用于 API 金额校验）
        $shipping_total = (float)$order->get_shipping_total();
        $tax_total = (float)$order->get_total_tax();

        $params = array(
            'mode' => 'payment',
            'order_id' => $order_id_str,
            'success_url' => $success_url,
            'cancel_url' => $cancel_url,
            'line_items' => $line_items,
            'amount' => $this->format_amount($order->get_total(), $order_currency),
            'currency' => $order_currency,
            'payment_method_types' => array('crypto'),
            'expires_at' => (int)$expires_at,
            'source_system' => 'woocommerce',
            'metadata' => array(
                'wc_order_id' => (string)$order->get_id(),
                'wc_order_number' => (string)$order->get_order_number(),
                'customer_email' => $order->get_billing_email(),
                'source' => 'woocommerce',
            ),
        );

        // 添加运费（如果有）
        if ($shipping_total > 0) {
            $params['shipping_amount'] = $this->format_amount($shipping_total, $order_currency);
        }

        // 添加税费（如果有）
        if ($tax_total > 0) {
            $params['tax_amount'] = $this->format_amount($tax_total, $order_currency);
        }

        return $params;
    }

    /**
     * 处理退款
     *
     * @param int $order_id 订单 ID
     * @param float $amount 退款金额
     * @param string $reason 退款原因
     * @return bool|WP_Error 成功返回 true，失败返回 WP_Error
     */
    public function process_refund($order_id, $amount = null, $reason = '') {
        // 强制写入 error_log 便于调试
        error_log(sprintf('[StablePay] process_refund 入口: order_id=%s, amount=%s', $order_id, $amount));

        $this->logger->info('网关收到退款请求', array(
            'order_id' => $order_id,
            'amount' => $amount,
            'reason' => $reason,
        ));

        $order = wc_get_order($order_id);

        if (!$order) {
            $this->logger->error('退款失败：订单不存在', array('order_id' => $order_id));
            return new WP_Error('invalid_order', __('订单不存在', 'stablepay-woocommerce'));
        }

        $this->logger->debug('退款订单详情', array(
            'order_id' => $order_id,
            'order_total' => $order->get_total(),
            'total_refunded' => $order->get_total_refunded(),
            'payment_method' => $order->get_payment_method(),
            'order_status' => $order->get_status(),
        ));

        if (!$this->refund_manager) {
            $this->logger->error('退款失败：退款管理器未初始化', array('order_id' => $order_id));
            return new WP_Error('refund_unavailable', __('退款功能不可用', 'stablepay-woocommerce'));
        }

        $result = $this->refund_manager->process_refund($order, $amount, $reason);

        if (is_wp_error($result)) {
            $this->logger->warning('退款处理返回错误', array(
                'order_id' => $order_id,
                'error_code' => $result->get_error_code(),
                'error_message' => $result->get_error_message(),
            ));
        } else {
            $this->logger->info('退款处理成功', array('order_id' => $order_id));
        }

        return $result;
    }

    /**
     * 在订单详情页显示支付信息
     *
     * @param WC_Order $order 订单对象
     */
    public function display_order_meta($order) {
        if ($order->get_payment_method() !== 'stablepay') {
            return;
        }

        $session_id = $order->get_meta('_stablepay_session_id');
        $currency = $order->get_meta('_stablepay_currency');
        $tx_hash = $order->get_meta('_stablepay_tx_hash');
        $amount_received = $order->get_meta('_stablepay_amount_received');

        echo '<div class="stablepay-order-info" style="margin-top: 20px; padding: 15px; background: #f9f9f9; border: 1px solid #ddd;">';
        echo '<h3>' . esc_html__('StablePay 支付信息', 'stablepay-woocommerce') . '</h3>';

        if ($session_id) {
            echo '<p><strong>' . esc_html__('支付会话 ID:', 'stablepay-woocommerce') . '</strong> ' . esc_html($session_id) . '</p>';
        }

        if ($currency) {
            echo '<p><strong>' . esc_html__('支付币种:', 'stablepay-woocommerce') . '</strong> ' . esc_html($currency) . '</p>';
        }

        if ($amount_received) {
            echo '<p><strong>' . esc_html__('实收金额:', 'stablepay-woocommerce') . '</strong> ' . esc_html($amount_received) . ' ' . esc_html($currency) . '</p>';
        }

        if ($tx_hash) {
            echo '<p><strong>' . esc_html__('交易哈希:', 'stablepay-woocommerce') . '</strong> <code>' . esc_html($tx_hash) . '</code></p>';
        }

        echo '</div>';
    }
}
