<?php
// src/DataHandler.php

require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/AdvancedHttpClient.php';

class DataHandler {
    private $httpClient;
    private $cacheFile;
    private $lastRequestFile;
    private $cacheTime;

    public function __construct() {
        $this->httpClient = new AdvancedHttpClient();
        $this->cacheFile = CACHED_PRICES_FILE;
        $this->lastRequestFile = LAST_REQUEST_FILE;
        $this->cacheTime = DATA_API_CACHE_TIME;
    }

    public function getLatestRates() {
        // 1. اگر کش وجود داشت و زمان کافی نگذشته، از کش استفاده کن
        $cachedData = $this->readCache();
        if ($cachedData && (time() - $cachedData['timestamp']) < $this->cacheTime) {
            error_log("Using cached prices (last request was " . round((time() - $cachedData['timestamp']) / 60, 2) . " minutes ago).");
            return $cachedData['data'];
        }

        // 2. بررسی زمان آخرین درخواست موفق
        $lastRequestTime = $this->getLastRequestTime();
        $timeSinceLastRequest = time() - $lastRequestTime;
        $minInterval = 30; // 30 ثانیه فاصله حداقل بین درخواست‌ها

        if ($timeSinceLastRequest < $minInterval) {
            $remainingTime = $minInterval - $timeSinceLastRequest;
            error_log("Last request was $timeSinceLastRequest seconds ago. Waiting $remainingTime seconds before next request.");
            sleep($remainingTime);
        }

        // 3. تلاش برای دریافت از API اصلی
        error_log("Trying to fetch data from primary: " . GOLD_API_URL . " using AdvancedHttpClient");
        $primaryResponse = $this->httpClient->get(GOLD_API_URL, ['max_retries' => 2]);

        if ($primaryResponse['success']) {
            $data = json_decode($primaryResponse['data'], true);
            if ($data) {
                $this->updateLastRequestTime();
                $this->writeCache($data);
                return $data;
            } else {
                error_log("Received invalid JSON from primary API.");
            }
        } else {
            error_log("Primary API request failed: " . $primaryResponse['error']);
        }

        // 4. تلاش با پروکسی‌ها
        $proxies = getGoldAPIProxies();
        foreach ($proxies as $proxyName => $proxyUrl) {
            $fullUrl = $proxyUrl . urlencode(GOLD_API_URL);
            error_log("Trying to fetch data from API via proxy: $fullUrl");
            $proxyResponse = $this->httpClient->get($fullUrl, ['max_retries' => 1]);

            if ($proxyResponse['success']) {
                $data = json_decode($proxyResponse['data'], true);
                if ($data) {
                    $this->updateLastRequestTime();
                    $this->writeCache($data);
                    return $data;
                } else {
                    error_log("Received invalid JSON from proxy: $proxyName");
                }
            } else {
                error_log("Proxy request failed for $proxyName: " . $proxyResponse['error']);
            }
        }

        // 5. اگر همه شکست خورد، آخرین کش معتبر را برگردان
        if ($cachedData) {
            error_log("All API attempts failed. Using cached data as fallback.");
            return $cachedData['data'];
        }

        error_log("Failed to fetch data from all APIs and cache file.");
        return null;
    }

    public function getScreenshotImage() {
        $apis = getScreenshotAPIs();
        $lastUsedAPI = $this->getLastUsedAPI();
        $apiKeys = array_keys($apis);
        $currentIndex = array_search($lastUsedAPI, $apiKeys);
        $nextIndex = ($currentIndex !== false && $currentIndex < count($apiKeys) - 1) ? $currentIndex + 1 : 0;
        $apiName = $apiKeys[$nextIndex];

        error_log("Trying to fetch image from API: $apiName");
        $response = $this->httpClient->get($apis[$apiName]);

        if ($response['success'] && $response['data']) {
            $this->updateLastUsedAPI($apiName);
            return $response['data'];
        } else {
            error_log("Received invalid data from API: $apiName");
            // اگر اولین API ناموفق بود، امتحان API دیگر
            foreach ($apiKeys as $tryApiName) {
                if ($tryApiName !== $apiName) {
                    error_log("Trying to fetch image from API: $tryApiName");
                    $fallbackResponse = $this->httpClient->get($apis[$tryApiName]);
                    if ($fallbackResponse['success'] && $fallbackResponse['data']) {
                        $this->updateLastUsedAPI($tryApiName);
                        return $fallbackResponse['data'];
                    } else {
                        error_log("Received invalid data from API: $tryApiName");
                    }
                }
            }
        }

        return null; // تمام APIها ناموفق بودند
    }

    public function getBrandInfo() {
        $file_path = BRAND_INFO_FILE;
        if (file_exists($file_path)) {
            return file_get_contents($file_path, true);
        }
        return "اطلاعات برند در دسترس نیست. لطفاً با پشتیبانی تماس بگیرید.";
    }

    public function captureAndSaveScreenshot($botInstance, $chatId) { // افزودن $botInstance و $chatId
        $apis = getScreenshotAPIs();
        $lastUsedAPI = $this->getLastUsedAPI();
        $apiKeys = array_keys($apis);
        $currentIndex = array_search($lastUsedAPI, $apiKeys);
        $nextIndex = ($currentIndex !== false && $currentIndex < count($apiKeys) - 1) ? $currentIndex + 1 : 0;
        $apiName = $apiKeys[$nextIndex];

        // ارسال پیام تلاش به کاربر
        $attemptNumber = $nextIndex + 1; // شماره سرور از 1 شروع می‌شود
        $botInstance->sendMessage($chatId, "📸 تلاش برای دریافت تصویر از سرور شماره $attemptNumber ...");

        $url = $apis[$apiName];
        error_log("Trying to fetch image from API: $apiName (URL: $url)");
        $response = $this->httpClient->get($url, ['timeout' => 25]); // افزایش زمان انتظار

        if ($response['success'] && $response['data']) {
            $timestamp = time();
            // استفاده از date برای نام فایل (میلادی) - یکپارچگی
            $formatted_date = date('Y-m-d_H-i', $timestamp); // مثلاً 2025-11-09_19-42
            $file_name = $formatted_date . '.jpg';
            $file_path = UPLOAD_PATH . $file_name;

            if (file_put_contents($file_path, $response['data'])) {
                $this->updateLastUsedAPI($apiName);
                error_log("Screenshot saved: $file_path");
                return $file_name;
            } else {
                error_log("Failed to save screenshot to: $file_path");
            }
        } else {
            error_log("Failed to capture screenshot from API: $apiName. Error: " . ($response['error'] ?? 'No error message'));
        }

        // اگر اولین تلاش ناموفق بود، تلاش با سایر APIها
        foreach ($apiKeys as $tryApiName) {
            if ($tryApiName !== $apiName) {
                $attemptNumber = array_search($tryApiName, $apiKeys) + 1;
                $botInstance->sendMessage($chatId, "📸 تلاش برای دریافت تصویر از سرور شماره $attemptNumber ...");
                error_log("Trying to fetch image from API: $tryApiName (URL: " . $apis[$tryApiName] . ")");
                $fallbackResponse = $this->httpClient->get($apis[$tryApiName], ['timeout' => 25]);

                if ($fallbackResponse['success'] && $fallbackResponse['data']) {
                    $timestamp = time();
                    // استفاده از date برای نام فایل (میلادی) - یکپارچگی
                    $formatted_date = date('Y-m-d_H-i', $timestamp);
                    $file_name = $formatted_date . '.jpg';
                    $file_path = UPLOAD_PATH . $file_name;

                    if (file_put_contents($file_path, $fallbackResponse['data'])) {
                        $this->updateLastUsedAPI($tryApiName);
                        error_log("Screenshot saved from fallback API: $file_path");
                        return $file_name;
                    } else {
                        error_log("Failed to save screenshot from fallback API to: $file_path");
                    }
                } else {
                    error_log("Failed to capture screenshot from fallback API: $tryApiName. Error: " . ($fallbackResponse['error'] ?? 'No error message'));
                }
            }
        }

        // اگر تمام تلاش‌ها ناموفق بود
        $botInstance->sendFallbackLinks($chatId);
        return false; // تمام APIها ناموفق بودند
    }


    public function getFileCreationDate($file_path) {
        if (!file_exists($file_path)) {
            return "❌ اطلاعات فایل قابل دسترسی نیست.";
        }

        $filename = basename($file_path);
        // تبدیل کاراکترهای فارسی به انگلیسی برای پردازش
        $eng_filename = str_replace(['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹', '‏', '‌'], ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '', ''], $filename);

        $pattern = '/^(\d{4})-(\d{2})-(\d{2})_(\d{2})-(\d{2})\.jpg$/';
        if (preg_match($pattern, $eng_filename, $matches)) {
            $year = (int)$matches[1];
            $month = (int)$matches[2];
            $day = (int)$matches[3];
            $hour = (int)$matches[4];
            $minute = (int)$matches[5];

            $jdate_str = '';
            // تشخیص تاریخ میلادی (سال بزرگتر از 1500 و کوچکتر از 2100)
            if ($year > 1500 && $year < 2100) {
                // تاریخ میلادی - تبدیل به شمسی
                $jdate_parts = self::gregorian_to_jalali($year, $month, $day);
                if ($jdate_parts) {
                    $jyear = $jdate_parts[0];
                    $jmonth = $jdate_parts[1];
                    $jday = $jdate_parts[2];
                    $jdate_str = sprintf("%04d/%02d/%02d %02d:%02d", $jyear, $jmonth, $jday, $hour, $minute);
                } else {
                    // اگر تابع تبدیل کار نکرد، از filemtime استفاده کن
                    $timestamp = filemtime($file_path);
                    $jdate_str = jdate('Y/m/d H:i', $timestamp);
                }
            } else {
                // فرض بر این است که تاریخ شمسی است (مثلاً 1404-08-18)
                // اگرچه تابع captureAndSaveScreenshot الان میلادی می‌سازد، اما ممکن است فایل‌های قدیمی با نام فارسی وجود داشته باشند
                // بنابراین، اگر سال کوچکتر از 1500 بود، مستقیماً نمایش دهید (هرچند کمتر احتمال دارد)
                // اما اگر سال کوچکتر بود، ممکن است فرمت اشتباه باشد
                // برای اطمینان، از filemtime استفاده کن
                $timestamp = filemtime($file_path);
                $jdate_str = jdate('Y/m/d H:i', $timestamp);
            }

            if ($jdate_str) {
                return " - تاریخ: {$jdate_str}";
            }
        }

        // اگر الگوی بالا نبود یا تبدیل انجام نشد، از filemtime استفاده کن
        $timestamp = filemtime($file_path);
        $jdate_str = jdate('Y/m/d H:i', $timestamp);
        return " - تاریخ: {$jdate_str}";
    }

    public function getScreenshotArchive() {
        $files = glob(UPLOAD_PATH . '*.jpg');
        if (empty($files)) {
            return [];
        }
        rsort($files); // مرتب سازی معکوس (جدیدترین اول)
        return $files;
    }

    private function readCache() {
        if (file_exists($this->cacheFile)) {
            $content = file_get_contents($this->cacheFile);
            return json_decode($content, true);
        }
        return null;
    }

    private function writeCache($data) {
        $toWrite = [
            'timestamp' => time(),
            'data' => $data
        ];
        file_put_contents($this->cacheFile, json_encode($toWrite, JSON_PRETTY_PRINT));
    }

    private function getLastRequestTime() {
        if (file_exists($this->lastRequestFile)) {
            $content = file_get_contents($this->lastRequestFile);
            $data = json_decode($content, true);
            return $data['timestamp'] ?? 0;
        }
        return 0;
    }

    private function updateLastRequestTime() {
        $data = ['timestamp' => time()];
        file_put_contents($this->lastRequestFile, json_encode($data, JSON_PRETTY_PRINT));
    }

    private function getLastUsedAPI() {
        // اطمینان از وجود فایل قبل از خواندن
        if (!file_exists(STATE_FILE)) {
            // اگر وجود نداشت، یک فایل جدید با مقدار پیش‌فرض ایجاد کن
            $initialState = ['last' => array_keys(getScreenshotAPIs())[0]];
            file_put_contents(STATE_FILE, json_encode($initialState, JSON_PRETTY_PRINT));
            return $initialState['last'];
        }
        $state = json_decode(file_get_contents(STATE_FILE, true), true) ?: [];
        $last_api = $state['last'] ?? null;
        $api_keys = array_keys(getScreenshotAPIs());

        if (!in_array($last_api, $api_keys)) {
            return $api_keys[0]; // اولین API
        }
        return $last_api;
    }

    private function updateLastUsedAPI($api_name) {
        $state = json_decode(file_get_contents(STATE_FILE, true), true) ?: [];
        $state['last'] = $api_name;
        $state['stats'][$api_name] = isset($state['stats'][$api_name]) ? $state['stats'][$api_name] + 1 : 1;
        file_put_contents(STATE_FILE, json_encode($state, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX);
    }

    // تابع تبدیل تاریخ میلادی به شمسی - تغییر به public static
    public static function gregorian_to_jalali($gy, $gm, $gd) {
        $g_d_m = array(0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334);
        $gy2 = ($gm > 2) ? ($gy + 1) : $gy;
        $days = 355666 + (365 * $gy) + ((int)(($gy2 + 3) / 4)) - ((int)(($gy2 + 99) / 100)) + ((int)(($gy2 + 399) / 400)) + $gd + $g_d_m[$gm - 1];
        $jy = -1595 + (33 * ((int)($days / 12053)));
        $days %= 12053;
        $jy += 4 * ((int)($days / 1461));
        $days %= 1461;
        if ($days > 365) {
            $jy += (int)(($days - 1) / 365);
            $days = ($days - 1) % 365;
        }
        if ($days < 186) {
            $jm = 1 + (int)($days / 31);
            $jd = 1 + ($days % 31);
        } else {
            $jm = 7 + (int)(($days - 186) / 30);
            $jd = 1 + (($days - 186) % 30);
        }
        return array($jy, $jm, $jd);
    }
}