<?php
/**
 * Error monitoring service for Bayarcash GiveWP integration.
 *
 * @author  Bayarcash
 * @license GPLv3
 *
 * @see    https://bayarcash.com
 */

namespace BayarCash\GiveWP;

\defined('ABSPATH') || exit;

class ErrorMonitor
{
    private const MONITOR_URL = 'https://monitor.bayar.cash/api/v1/payment-errors';
    private const API_KEY = '5e553c4238bfd8bae4c67db7c0c76f78728f98446c0bbcecbec0dd0a6e604060';

    /**
     * Report payment error to monitoring service.
     *
     * @param array $data Error data to report
     * @return void
     */
    public static function report(array $data): void
    {
        try {
            $payload = self::preparePayload($data);

            wp_remote_post(self::MONITOR_URL, [
                'headers' => [
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json',
                    'X-API-Key' => self::API_KEY,
                ],
                'body' => json_encode($payload),
                'timeout' => 10,
                'blocking' => false,
            ]);
        } catch (\Exception $e) {
            // Silently fail
        }
    }

    /**
     * Prepare error payload for monitoring service.
     *
     * @param array $data Raw error data
     * @return array Formatted payload
     */
    private static function preparePayload(array $data): array
    {
        global $wp_version;

        // Normalize credentials
        $normalizeCredential = function($value) {
            return ($value && $value !== '' && $value !== false) ? (string) $value : 'not-configured';
        };

        // Normalize error details
        $error_details = $data['error_details'] ?? null;
        if ($error_details && !is_string($error_details)) {
            $error_details = print_r($error_details, true);
        }

        // Add test_mode to request_data
        $request_data = $data['request_data'] ?? null;
        if (is_array($request_data) && isset($data['test_mode'])) {
            $request_data['test_mode'] = $data['test_mode'];
        }

        $payload = [
            'merchant_portal_key' => $normalizeCredential($data['portal_key'] ?? null),
            'merchant_secret_key' => $normalizeCredential($data['secret_key'] ?? null),
            'merchant_pat' => $normalizeCredential($data['bearer_token'] ?? null),
            'error_message' => $data['error_message'] ?? 'Unknown error',
            'error_details' => $error_details,
            'site_domain' => get_site_url(),
            'page_url' => self::getCurrentUrl(),
            'payment_id' => isset($data['payment_id']) ? (int) $data['payment_id'] : null,
            'payment_channel' => $data['payment_channel'] ?? null,
            'amount' => isset($data['amount']) ? (float) $data['amount'] : null,
            'request_data' => $request_data,
            'response_data' => $data['response_data'] ?? null,
            'user_ip' => self::getUserIp(),
            'php_version' => PHP_VERSION,
            'wordpress_version' => $wp_version,
            'plugin_version' => self::getPluginVersion(),
        ];

        return array_filter($payload, fn($v) => $v !== null);
    }

    /**
     * Get current URL from request.
     *
     * @return string Current page URL
     */
    private static function getCurrentUrl(): string
    {
        $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
        $host = $_SERVER['HTTP_HOST'] ?? '';
        $uri = $_SERVER['REQUEST_URI'] ?? '';

        return $protocol . '://' . $host . $uri;
    }

    /**
     * Get user IP address from various sources.
     *
     * @return string|null User IP address
     */
    private static function getUserIp(): ?string
    {
        foreach (['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'] as $key) {
            if (empty($_SERVER[$key])) continue;

            $ip = trim(explode(',', $_SERVER[$key])[0]);
            if (filter_var($ip, FILTER_VALIDATE_IP)) {
                return $ip;
            }
        }
        return null;
    }

    /**
     * Get plugin version from plugin metadata.
     *
     * @return string Plugin version number
     */
    private static function getPluginVersion(): string
    {
        if (!function_exists('get_plugin_data')) {
            require_once ABSPATH . 'wp-admin/includes/plugin.php';
        }

        $plugin_file = dirname(dirname(__DIR__)) . '/bayarcash-givewp.php';
        return file_exists($plugin_file) ? (get_plugin_data($plugin_file)['Version'] ?? '0.0.0') : '0.0.0';
    }
}
