<?php

require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/SystemConfigService.php';

class EconomicCalendarService
{
    public static function check(string $symbol, int $minutesAhead = 90, int $minutesBehind = 30): array
    {
        $events = self::getUpcomingEvents($symbol, $minutesAhead, $minutesBehind);

        if (empty($events)) {
            return [
                'has_news' => false,
                'risk' => 'LOW',
                'score_penalty' => 0,
                'title' => '',
                'time' => '',
                'message' => 'No high-impact economic calendar risk detected.',
                'events' => [],
                'source' => 'database_calendar'
            ];
        }

        $highest = 'LOW';
        $penalty = 0;

        foreach ($events as $event) {
            $impact = strtoupper((string)($event['impact'] ?? 'LOW'));

            if ($impact === 'CRITICAL') {
                $highest = 'EXTREME';
                $penalty = max($penalty, 5);
            } elseif ($impact === 'HIGH') {
                $highest = self::maxRisk($highest, 'HIGH');
                $penalty = max($penalty, 4);
            } elseif ($impact === 'MEDIUM') {
                $highest = self::maxRisk($highest, 'MEDIUM');
                $penalty = max($penalty, 2);
            }
        }

        $primary = $events[0];

        return [
            'has_news' => true,
            'risk' => $highest,
            'score_penalty' => $penalty,
            'title' => $primary['title'] ?? '',
            'time' => $primary['time'] ?? '',
            'message' => $highest . ' economic calendar risk detected.',
            'events' => $events,
            'source' => 'database_calendar'
        ];
    }

    public static function getUpcomingEvents(string $symbol, int $minutesAhead = 90, int $minutesBehind = 30): array
    {
        try {
            $pdo = db();

            $currencies = self::currenciesForSymbol($symbol);

            $now = time();
            $start = $now - ($minutesBehind * 60);
            $end = $now + ($minutesAhead * 60);

            $placeholders = implode(',', array_fill(0, count($currencies), '?'));

            $sql = "
                SELECT *
                FROM news_events
                WHERE event_timestamp BETWEEN ? AND ?
                AND (
                    currency IN ($placeholders)
                    OR title LIKE '%FED%'
                    OR title LIKE '%FOMC%'
                    OR title LIKE '%CPI%'
                    OR title LIKE '%NFP%'
                    OR title LIKE '%POWELL%'
                    OR title LIKE '%GDP%'
                    OR title LIKE '%INFLATION%'
                    OR title LIKE '%INTEREST RATE%'
                )
                AND impact IN ('MEDIUM','HIGH','CRITICAL')
                ORDER BY event_timestamp ASC
                LIMIT 50
            ";

            $params = [$start, $end];

            foreach ($currencies as $currency) {
                $params[] = $currency;
            }

            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);

            $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

            $events = [];

            foreach ($rows as $row) {
                $events[] = [
                    'title' => $row['title'],
                    'event' => $row['title'],
                    'currency' => $row['currency'],
                    'impact' => strtoupper((string)$row['impact']),
                    'time' => date('Y-m-d H:i', (int)$row['event_timestamp']),
                    'timestamp' => (int)$row['event_timestamp'],
                    'seconds_until' => ((int)$row['event_timestamp']) - time(),
                    'minutes_until' => (int)round((((int)$row['event_timestamp']) - time()) / 60),
                    'actual' => $row['actual'],
                    'forecast' => $row['forecast'],
                    'previous' => $row['previous'],
                    'source' => $row['source'] ?? 'database'
                ];
            }

            return $events;

        } catch (Throwable $e) {

            self::logError($e->getMessage());

            return [];
        }
    }

    public static function symbolCurrencies(string $symbol): array
    {
        return self::currenciesForSymbol($symbol);
    }

    private static function currenciesForSymbol(string $symbol): array
    {
        $symbol = strtoupper(str_replace('/', '', trim($symbol)));

        if ($symbol === 'XAUUSD') {
            return ['USD', 'XAU'];
        }

        if (strlen($symbol) >= 6) {
            return [
                substr($symbol, 0, 3),
                substr($symbol, 3, 3)
            ];
        }

        return ['USD'];
    }

    private static function maxRisk(string $a, string $b): string
    {
        $rank = [
            'LOW' => 1,
            'MEDIUM' => 2,
            'HIGH' => 3,
            'EXTREME' => 4
        ];

        return ($rank[$b] ?? 0) > ($rank[$a] ?? 0)
            ? $b
            : $a;
    }

    private static function logError(string $message): void
    {
        try {

            $dir = __DIR__ . '/../storage/logs';

            if (!is_dir($dir)) {
                @mkdir($dir, 0755, true);
            }

            $file = $dir . '/news_errors.log';

            $line = '[' . date('Y-m-d H:i:s') . '] ' . $message . PHP_EOL;

            @file_put_contents($file, $line, FILE_APPEND);

        } catch (Throwable $e) {
            // fail silently
        }
    }
}
