<?php

namespace App\Services;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;

class CurrencyService
{
    private $exchangeRates = [];
    private $baseCurrency = 'USD';
    
    public function __construct()
    {
        $this->loadExchangeRates();
    }
    
    /**
     * Convert amount from one currency to another
     */
    public function convert($amount, $fromCurrency, $toCurrency)
    {
        if ($fromCurrency === $toCurrency) {
            return $amount;
        }
        
        $rate = $this->getExchangeRate($fromCurrency, $toCurrency);
        return round($amount * $rate, 2);
    }
    
    /**
     * Get exchange rate between two currencies
     */
    public function getExchangeRate($fromCurrency, $toCurrency)
    {
        if ($fromCurrency === $toCurrency) {
            return 1;
        }
        
        // Try direct rate first
        if (isset($this->exchangeRates[$fromCurrency][$toCurrency])) {
            return $this->exchangeRates[$fromCurrency][$toCurrency];
        }
        
        // Try inverse rate
        if (isset($this->exchangeRates[$toCurrency][$fromCurrency])) {
            return 1 / $this->exchangeRates[$toCurrency][$fromCurrency];
        }
        
        // Try via base currency
        if (isset($this->exchangeRates[$fromCurrency][$this->baseCurrency]) && 
            isset($this->exchangeRates[$this->baseCurrency][$toCurrency])) {
            
            return $this->exchangeRates[$fromCurrency][$this->baseCurrency] * 
                   $this->exchangeRates[$this->baseCurrency][$toCurrency];
        }
        
        // If no rate found, return 1 (fallback)
        return 1;
    }
    
    /**
     * Format amount with currency symbol
     */
    public function formatWithSymbol($amount, $currency)
    {
        $symbols = [
            'USD' => '$', 'EUR' => '€', 'GBP' => '£', 'INR' => '₹',
            'CAD' => 'C$', 'AUD' => 'A$', 'JPY' => '¥', 'BRL' => 'R$',
            'CNY' => '¥', 'SAR' => '﷼', 'RUB' => '₽', 'MXN' => '$',
            'ARS' => '$', 'ZAR' => 'R', 'NGN' => '₦', 'EGP' => '£',
            'TRY' => '₺', 'PLN' => 'zł', 'SEK' => 'kr', 'NOK' => 'kr',
            'DKK' => 'kr', 'CHF' => 'CHF', 'NZD' => 'NZ$',
        ];
        
        $symbol = $symbols[$currency] ?? $currency;
        return $symbol . number_format($amount, 2);
    }
    
    /**
     * Get currency symbol
     */
    public function getSymbol($currency)
    {
        $symbols = [
            'USD' => '$', 'EUR' => '€', 'GBP' => '£', 'INR' => '₹',
            'CAD' => 'C$', 'AUD' => 'A$', 'JPY' => '¥', 'BRL' => 'R$',
            'CNY' => '¥', 'SAR' => '﷼', 'RUB' => '₽', 'MXN' => '$',
            'ARS' => '$', 'ZAR' => 'R', 'NGN' => '₦', 'EGP' => '£',
            'TRY' => '₺', 'PLN' => 'zł', 'SEK' => 'kr', 'NOK' => 'kr',
            'DKK' => 'kr', 'CHF' => 'CHF', 'NZD' => 'NZ$',
        ];
        
        return $symbols[$currency] ?? $currency;
    }
    
    /**
     * Get currency name
     */
    public function getName($currency)
    {
        $names = [
            'USD' => 'US Dollar', 'EUR' => 'Euro', 'GBP' => 'British Pound',
            'INR' => 'Indian Rupee', 'CAD' => 'Canadian Dollar', 'AUD' => 'Australian Dollar',
            'JPY' => 'Japanese Yen', 'BRL' => 'Brazilian Real', 'CNY' => 'Chinese Yuan',
            'SAR' => 'Saudi Riyal', 'RUB' => 'Russian Ruble', 'MXN' => 'Mexican Peso',
            'ARS' => 'Argentine Peso', 'ZAR' => 'South African Rand', 'NGN' => 'Nigerian Naira',
            'EGP' => 'Egyptian Pound', 'TRY' => 'Turkish Lira', 'PLN' => 'Polish Zloty',
            'SEK' => 'Swedish Krona', 'NOK' => 'Norwegian Krone', 'DKK' => 'Danish Krone',
            'CHF' => 'Swiss Franc', 'NZD' => 'New Zealand Dollar',
        ];
        
        return $names[$currency] ?? $currency;
    }
    
    /**
     * Get all supported currencies
     */
    public function getSupportedCurrencies()
    {
        return [
            'USD' => ['name' => 'US Dollar', 'symbol' => '$', 'enabled' => true],
            'EUR' => ['name' => 'Euro', 'symbol' => '€', 'enabled' => true],
            'GBP' => ['name' => 'British Pound', 'symbol' => '£', 'enabled' => true],
            'INR' => ['name' => 'Indian Rupee', 'symbol' => '₹', 'enabled' => true],
            'CAD' => ['name' => 'Canadian Dollar', 'symbol' => 'C$', 'enabled' => true],
            'AUD' => ['name' => 'Australian Dollar', 'symbol' => 'A$', 'enabled' => true],
            'JPY' => ['name' => 'Japanese Yen', 'symbol' => '¥', 'enabled' => true],
            'BRL' => ['name' => 'Brazilian Real', 'symbol' => 'R$', 'enabled' => true],
            'CNY' => ['name' => 'Chinese Yuan', 'symbol' => '¥', 'enabled' => true],
            'SAR' => ['name' => 'Saudi Riyal', 'symbol' => '﷼', 'enabled' => true],
            'RUB' => ['name' => 'Russian Ruble', 'symbol' => '₽', 'enabled' => true],
            'MXN' => ['name' => 'Mexican Peso', 'symbol' => '$', 'enabled' => true],
            'ARS' => ['name' => 'Argentine Peso', 'symbol' => '$', 'enabled' => true],
            'ZAR' => ['name' => 'South African Rand', 'symbol' => 'R', 'enabled' => true],
            'NGN' => ['name' => 'Nigerian Naira', 'symbol' => '₦', 'enabled' => true],
            'EGP' => ['name' => 'Egyptian Pound', 'symbol' => '£', 'enabled' => true],
            'TRY' => ['name' => 'Turkish Lira', 'symbol' => '₺', 'enabled' => true],
            'PLN' => ['name' => 'Polish Zloty', 'symbol' => 'zł', 'enabled' => true],
            'SEK' => ['name' => 'Swedish Krona', 'symbol' => 'kr', 'enabled' => true],
            'NOK' => ['name' => 'Norwegian Krone', 'symbol' => 'kr', 'enabled' => true],
            'DKK' => ['name' => 'Danish Krone', 'symbol' => 'kr', 'enabled' => true],
            'CHF' => ['name' => 'Swiss Franc', 'symbol' => 'CHF', 'enabled' => true],
            'NZD' => ['name' => 'New Zealand Dollar', 'symbol' => 'NZ$', 'enabled' => true],
        ];
    }
    
    /**
     * Update exchange rates from external API
     */
    public function updateExchangeRates()
    {
        try {
            // Use a free currency API (you might want to use a paid service for production)
            $cacheKey = 'exchange_rates';
            $cacheTime = 3600; // Cache for 1 hour
            
            return Cache::remember($cacheKey, $cacheTime, function() {
                $response = Http::get('https://api.exchangerate-api.com/v4/latest/USD');
                
                if ($response->successful()) {
                    $data = $response->json();
                    $rates = $data['rates'] ?? [];
                    
                    // Store rates in database or cache
                    $this->storeExchangeRates($rates);
                    
                    return $rates;
                }
                
                return [];
            });
            
        } catch (\Exception $e) {
            \Log::warning('Failed to update exchange rates', ['error' => $e->getMessage()]);
            return $this->getDefaultRates();
        }
    }
    
    /**
     * Store exchange rates in cache/database
     */
    private function storeExchangeRates($rates)
    {
        // Store in cache
        Cache::put('exchange_rates', $rates, 3600);
        
        // Also store in database for persistence
        \App\Models\Setting::updateOrCreate(
            ['key' => 'currency_rates'],
            ['value' => json_encode($rates)]
        );
    }
    
    /**
     * Load exchange rates from cache/database
     */
    private function loadExchangeRates()
    {
        // Try cache first
        $rates = Cache::get('exchange_rates');
        
        if (!$rates) {
            // Try database
            $setting = \App\Models\Setting::where('key', 'currency_rates')->first();
            if ($setting) {
                $rates = json_decode($setting->value, true);
            }
        }
        
        if (!$rates) {
            $rates = $this->getDefaultRates();
        }
        
        $this->exchangeRates = $this->buildExchangeRateMatrix($rates);
    }
    
    /**
     * Build exchange rate matrix for all currency pairs
     */
    private function buildExchangeRateMatrix($baseRates)
    {
        $currencies = array_keys($this->getSupportedCurrencies());
        $matrix = [];
        
        foreach ($currencies as $from) {
            foreach ($currencies as $to) {
                if ($from === $to) {
                    $matrix[$from][$to] = 1;
                } elseif ($from === $this->baseCurrency && isset($baseRates[$to])) {
                    $matrix[$from][$to] = $baseRates[$to];
                } elseif ($to === $this->baseCurrency && isset($baseRates[$from])) {
                    $matrix[$from][$to] = 1 / $baseRates[$from];
                } else {
                    // Calculate cross rate via base currency
                    if (isset($baseRates[$from]) && isset($baseRates[$to])) {
                        $matrix[$from][$to] = $baseRates[$to] / $baseRates[$from];
                    } else {
                        $matrix[$from][$to] = 1; // Fallback
                    }
                }
            }
        }
        
        return $matrix;
    }
    
    /**
     * Get default exchange rates (fallback)
     */
    private function getDefaultRates()
    {
        return [
            'EUR' => 0.85,
            'GBP' => 0.75,
            'INR' => 83.00,
            'CAD' => 1.35,
            'AUD' => 1.45,
            'JPY' => 150.00,
            'BRL' => 5.00,
            'CNY' => 7.20,
            'SAR' => 3.75,
            'RUB' => 90.00,
            'MXN' => 17.00,
            'ARS' => 350.00,
            'ZAR' => 19.00,
            'NGN' => 460.00,
            'EGP' => 47.00,
            'TRY' => 26.00,
            'PLN' => 4.00,
            'SEK' => 10.50,
            'NOK' => 10.80,
            'DKK' => 6.90,
            'CHF' => 0.90,
            'NZD' => 1.65,
        ];
    }
    
    /**
     * Calculate average price in base currency for analytics
     */
    public function calculateAveragePriceInBaseCurrency($ads)
    {
        $total = 0;
        $count = 0;
        
        foreach ($ads as $ad) {
            $amountInUSD = $this->convert($ad->price, $ad->currency, $this->baseCurrency);
            $total += $amountInUSD;
            $count++;
        }
        
        return $count > 0 ? round($total / $count, 2) : 0;
    }
    
    /**
     * Get currency statistics for admin dashboard
     */
    public function getCurrencyStatistics()
    {
        $ads = \App\Models\Ad::select('currency', 'price')
                ->where('status', 'Active')
                ->get();
        
        $stats = [];
        $totalRevenueUSD = 0;
        
        foreach ($this->getSupportedCurrencies() as $currency => $info) {
            $currencyAds = $ads->where('currency', $currency);
            $count = $currencyAds->count();
            
            if ($count > 0) {
                $avgPrice = $this->calculateAveragePriceInBaseCurrency($currencyAds);
                $totalRevenue = $currencyAds->sum('price');
                $totalRevenueUSD += $this->convert($totalRevenue, $currency, $this->baseCurrency);
                
                $stats[$currency] = [
                    'name' => $info['name'],
                    'symbol' => $info['symbol'],
                    'ads_count' => $count,
                    'avg_price' => $avgPrice,
                    'total_revenue' => $totalRevenue,
                    'total_revenue_usd' => $this->convert($totalRevenue, $currency, $this->baseCurrency),
                ];
            }
        }
        
        return [
            'stats' => $stats,
            'total_revenue_usd' => $totalRevenueUSD,
        ];
    }
}
