<?php
// core/Helpers/CryptoHelper.php

namespace Core\Helpers;

class CryptoHelper
{
    private static $apiBase = 'https://api.coingecko.com/api/v3';
    private static $cacheDir = FS_STORAGE_PATH . '/cache/crypto/';
    private static $cacheDuration = 600; // 10 Minutes cache time

    // Map internal currency codes to CoinGecko IDs
    private static $coinMap = [
        'BTC'  => 'bitcoin',
        'ETH'  => 'ethereum',
        'USDT' => 'tether',
        'SOL'  => 'solana',
        'BNB'  => 'binancecoin',
        'XRP'  => 'ripple',
        'DOGE' => 'dogecoin',
        'TRX'  => 'tron'
    ];

    /**
     * Get simple prices for wallet calculation with Caching
     */
    public static function getRates(string $vsCurrency = 'usd'): array
    {
        $cacheKey = "rates_{$vsCurrency}";
        $cached = self::getCache($cacheKey);

        // 1. Return fresh cache if available
        if ($cached && $cached['time'] > (time() - self::$cacheDuration)) {
            return $cached['data'];
        }

        // 2. Try Fetching from API
        $ids = implode(',', array_values(self::$coinMap));
        $url = self::$apiBase . "/simple/price?ids={$ids}&vs_currencies={$vsCurrency}";

        $response = self::fetch($url);
        
        $rates = [];
        
        // Default Fallbacks (Last resort)
        $defaults = [
            'BTC' => 64000, 'ETH' => 3400, 'USDT' => 1, 'SOL' => 145, 
            'BNB' => 590, 'XRP' => 0.60, 'DOGE' => 0.12, 'TRX' => 0.12
        ];

        if ($response) {
            // API Success: Process and Save
            foreach (self::$coinMap as $symbol => $id) {
                if (isset($response[$id][$vsCurrency])) {
                    $rates[$symbol] = $response[$id][$vsCurrency];
                } else {
                    $rates[$symbol] = $defaults[$symbol] ?? 0;
                }
            }
            // Save valid data to cache
            self::setCache($cacheKey, $rates);
            return $rates;
        } 
        
        // 3. API Failed: Return stale cache if it exists (The "Previous One")
        if ($cached) {
            return $cached['data'];
        }

        // 4. No Cache & No API: Return defaults
        return $defaults;
    }

    /**
     * Get detailed market data for Market page with Caching
     */
    public static function getMarketOverview(string $vsCurrency = 'usd'): array
    {
        $cacheKey = "market_{$vsCurrency}";
        $cached = self::getCache($cacheKey);

        // 1. Return fresh cache
        if ($cached && $cached['time'] > (time() - self::$cacheDuration)) {
            return $cached['data'];
        }

        // 2. Fetch API
        $ids = implode(',', array_values(self::$coinMap));
        $url = self::$apiBase . "/coins/markets?vs_currency={$vsCurrency}&ids={$ids}&order=market_cap_desc&per_page=10&page=1&sparkline=false&price_change_percentage=24h";

        $data = self::fetch($url);

        if (!$data || !is_array($data)) {
            // 3. API Failed: Return stale cache if exists
            return $cached ? $cached['data'] : [];
        }

        // Map back to our structure
        $formatted = [];

        foreach ($data as $coin) {
            $symbol = strtoupper($coin['symbol']);
            // Only include coins we map
            if(array_key_exists($symbol, self::$coinMap)) {
                $formatted[] = [
                    'name' => $coin['name'],
                    'symbol' => $symbol,
                    'price' => $coin['current_price'],
                    'change' => $coin['price_change_percentage_24h'],
                    'image' => $coin['image']
                ];
            }
        }
        
        // Save to cache
        self::setCache($cacheKey, $formatted);

        return $formatted;
    }

    private static function fetch($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_USERAGENT, 'NexusApp/1.0'); // User-Agent is required by CoinGecko
        curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 10s timeout
        $output = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode === 200) {
            return json_decode($output, true);
        }
        return null;
    }

    // --- Cache Helpers ---

    private static function getCache($key)
    {
        $file = self::$cacheDir . $key . '.json';
        if (file_exists($file)) {
            $content = file_get_contents($file);
            $decoded = json_decode($content, true);
            if (json_last_error() === JSON_ERROR_NONE) {
                return $decoded;
            }
        }
        return null;
    }

    private static function setCache($key, $data)
    {
        if (!is_dir(self::$cacheDir)) {
            mkdir(self::$cacheDir, 0777, true);
        }
        $file = self::$cacheDir . $key . '.json';
        $content = [
            'time' => time(),
            'data' => $data
        ];
        file_put_contents($file, json_encode($content));
    }
}