<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;

class WestWalletService
{
    private $apiKey;
    private $privateKey;
    private $baseUrl;

    public function __construct()
    {
        // Get credentials from config, trim to remove any whitespace that may have been copied
        $this->apiKey = trim(config('services.westwallet.api_key', 'ra4qvKRdAsGZN83fHQLpOR74WsQInOtF90w_bEe6'));
        $this->privateKey = trim(config('services.westwallet.private_key', 'wFubRYIt6TcbAQX57OdtswACaAHOjErfcew4obj3NCNc-T_GoHmr6w'));
        $this->baseUrl = trim(config('services.westwallet.base_url', 'https://api.westwallet.io'));
        
        // Log loaded credentials (partial for security)
        Log::debug('WestWallet Service initialized', [
            'api_key_preview' => substr($this->apiKey, 0, 5) . '...',
            'private_key_preview' => substr($this->privateKey, 0, 5) . '...',
            'base_url' => $this->baseUrl
        ]);
    }

    /**
     * Generate HMAC signature for WestWallet API
     */
    private function generateSignature($timestamp, $data = [])
    {
        // Ensure consistent JSON encoding across environments
        // Force empty object {} instead of empty array [] for empty data
        $body = empty($data) ? '' : json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        $message = $timestamp . $body;
        $signature = hash_hmac('sha256', $message, trim($this->privateKey));

        // Log signature generation details
        Log::debug('WestWallet HMAC Signature Generation', [
            'timestamp' => $timestamp,
            'data' => $data,
            'json_body' => $body,
            'message' => $message,
            'private_key_length' => strlen($this->privateKey),
            'private_key_preview' => substr($this->privateKey, 0, 8) . '...',
            'generated_signature' => $signature,
        ]);

        return $signature;
    }

    /**
     * Make authenticated request to WestWallet API
     */
    private function makeRequest($method, $endpoint, $data = [])
    {
        $timestamp = time();
        
        // Ensure consistent data format
        // Use object for empty data in POST requests
        if ($method === 'POST' && empty($data)) {
            $data = (object) [];
        }
        
        $signature = $this->generateSignature($timestamp, $data);

        $headers = [
            'Content-Type' => 'application/json',
            'X-API-KEY' => $this->apiKey,
            'X-ACCESS-SIGN' => $signature,
            'X-ACCESS-TIMESTAMP' => $timestamp,
        ];

        $url = $this->baseUrl . $endpoint;

        // Log request details for debugging
        Log::info('WestWallet API Request', [
            'method' => $method,
            'url' => $url,
            'endpoint' => $endpoint,
            'timestamp' => $timestamp,
            'headers' => [
                'Content-Type' => $headers['Content-Type'],
                'X-API-KEY' => substr($this->apiKey, 0, 8) . '...', // Partial API key for security
                'X-ACCESS-SIGN' => substr($signature, 0, 16) . '...', // Partial signature for security
                'X-ACCESS-TIMESTAMP' => $timestamp,
            ],
            'data' => $data,
            'json_body' => $method === 'POST' ? (empty($data) ? '{}' : json_encode($data, JSON_UNESCAPED_UNICODE)) : null,
            'signature_generation' => [
                'message' => $timestamp . (empty($data) ? '' : json_encode($data, JSON_UNESCAPED_UNICODE)),
                'private_key_preview' => substr($this->privateKey, 0, 8) . '...',
            ]
        ]);

        try {
            $httpOptions = [
                'verify' => true, // Always verify SSL certificates, especially in production
            ];

            if ($method === 'GET') {
                $response = Http::withHeaders($headers)
                    ->withOptions($httpOptions)
                    ->get($url, $data);
            } else {
                // For POST requests, ensure consistent JSON encoding
                $jsonData = empty($data) ? '{}' : json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
                $response = Http::withHeaders($headers)
                    ->withOptions($httpOptions)
                    ->withBody($jsonData, 'application/json')
                    ->post($url);
            }

            $result = $response->json();

            // Log response details
            Log::info('WestWallet API Response', [
                'endpoint' => $endpoint,
                'status' => $response->status(),
                'response_body' => $result,
                'response_headers' => $response->headers(),
            ]);

            if (!$response->successful()) {
                Log::error('WestWallet API Error', [
                    'endpoint' => $endpoint,
                    'status' => $response->status(),
                    'response' => $result
                ]);
                return ['error' => $result['error'] ?? 'API request failed'];
            }

            if (isset($result['error']) && $result['error'] !== 'ok') {
                Log::error('WestWallet API Error', [
                    'endpoint' => $endpoint,
                    'error' => $result['error'],
                    'response' => $result
                ]);
                return ['error' => $result['error']];
            }

            return $result;
        } catch (\Exception $e) {
            Log::error('WestWallet API Exception', [
                'endpoint' => $endpoint,
                'message' => $e->getMessage()
            ]);
            return ['error' => 'Connection failed: ' . $e->getMessage()];
        }
    }

    /**
     * Get available currencies and their limits
     */
    public function getCurrencies()
    {
        return $this->makeRequest('GET', '/wallet/currencies_data');
    }

    /**
     * Get wallet balance for specific currency
     */
    public function getBalance($currency)
    {
        return $this->makeRequest('GET', '/wallet/balance', ['currency' => $currency]);
    }

    /**
     * Get all wallet balances
     */
    public function getAllBalances()
    {
        return $this->makeRequest('GET', '/wallet/balances');
    }

    /**
     * Generate address for receiving payments
     */
    public function generateAddress($currency, $ipnUrl = null, $label = null)
    {
        $data = [
            'currency' => $currency,
        ];

        // Only add ipn_url if it's provided and not a localhost URL (for development)
        if ($ipnUrl && !$this->isLocalhostUrl($ipnUrl)) {
            $data['ipn_url'] = $ipnUrl;
        }

        if ($label) {
            $data['label'] = $label;
        }

        return $this->makeRequest('POST', '/address/generate', $data);
    }

    /**
     * Check if URL is localhost (for development environments)
     */
    private function isLocalhostUrl($url)
    {
        return strpos($url, '127.0.0.1') !== false || 
               strpos($url, 'localhost') !== false ||
               strpos($url, 'http://') === 0; // Also block HTTP URLs for security
    }

    /**
     * Create withdrawal transaction
     */
    public function createWithdrawal($currency, $amount, $address, $destTag = null, $description = null, $priority = 'medium', $ipnUrl = null)
    {
        $data = [
            'currency' => $currency,
            'amount' => $amount,
            'address' => $address,
            'priority' => $priority,
        ];

        if ($destTag) {
            $data['dest_tag'] = $destTag;
        }

        if ($description) {
            $data['description'] = $description;
        }

        if ($ipnUrl) {
            $data['ipn_url'] = $ipnUrl;
        }

        return $this->makeRequest('POST', '/wallet/create_withdrawal', $data);
    }

    /**
     * Create multiple withdrawals
     */
    public function createMultipleWithdrawals($currency, $transactions, $priority = 'medium')
    {
        $data = [
            'currency' => $currency,
            'transactions' => $transactions,
            'priority' => $priority,
        ];

        return $this->makeRequest('POST', '/wallet/create_withdrawal/many', $data);
    }

    /**
     * Get transaction status
     */
    public function getTransactionStatus($id = null, $label = null)
    {
        $data = [];
        
        if ($id) {
            $data['id'] = $id;
        }
        
        if ($label) {
            $data['label'] = $label;
        }

        return $this->makeRequest('POST', '/wallet/transaction', $data);
    }

    /**
     * Get transactions history
     */
    public function getTransactions($currency = null, $limit = 10, $offset = 0, $type = null, $order = 'desc', $status = null, $startDate = null, $endDate = null)
    {
        $data = [
            'limit' => $limit,
            'offset' => $offset,
            'order' => $order,
        ];

        if ($currency) {
            $data['currency'] = $currency;
        }

        if ($type) {
            $data['type'] = $type;
        }

        if ($status) {
            $data['status'] = $status;
        }

        if ($startDate) {
            $data['start_date'] = $startDate;
        }

        if ($endDate) {
            $data['end_date'] = $endDate;
        }

        return $this->makeRequest('POST', '/wallet/transactions', $data);
    }

    /**
     * Create invoice for payment page
     */
    public function createInvoice($currencies, $amount, $ipnUrl, $amountInUsd = false, $successUrl = null, $description = null, $label = null, $ttl = 15)
    {
        $data = [
            'currencies' => $currencies,
            'amount' => $amount,
            'ipn_url' => $ipnUrl,
            'ttl' => $ttl,
        ];

        if ($amountInUsd) {
            $data['amount_in_usd'] = true;
        }

        if ($successUrl) {
            $data['success_url'] = $successUrl;
        }

        if ($description) {
            $data['description'] = $description;
        }

        if ($label) {
            $data['label'] = $label;
        }

        return $this->makeRequest('POST', '/address/create_invoice', $data);
    }

    /**
     * Get invoice transactions
     */
    public function getInvoiceTransactions($token)
    {
        return $this->makeRequest('GET', '/address/invoice_transactions', ['token' => $token]);
    }

    /**
     * Validate webhook signature (for incoming notifications)
     */
    public function validateWebhook($payload, $signature)
    {
        $expectedSignature = hash_hmac('sha256', $payload, $this->privateKey);
        return hash_equals($expectedSignature, $signature);
    }
}
