<?php

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

class GeoRiskService
{
    private static function apiKey(): ?string
    {
        if (class_exists('SystemConfigService') && method_exists('SystemConfigService', 'getApiKey')) {
            $key = SystemConfigService::getApiKey('fmp');
            if ($key) return $key;
        }

        $stmt = db()->prepare("SELECT api_key FROM api_settings WHERE provider = 'fmp' AND is_active = 1 LIMIT 1");
        $stmt->execute();

        return $stmt->fetchColumn() ?: null;
    }

    private static function request(string $url): array
    {
        $ch = curl_init();

        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 20,
            CURLOPT_CONNECTTIMEOUT => 10,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_HTTPHEADER => ['Accept: application/json']
        ]);

        $body = curl_exec($ch);
        $http = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        $json = json_decode((string)$body, true);

        return [
            'ok' => $body !== false && $http >= 200 && $http < 300 && is_array($json),
            'http' => $http,
            'error' => $error,
            'json' => is_array($json) ? $json : [],
            'url' => preg_replace('/apikey=[^&]+/', 'apikey=***', $url)
        ];
    }

    public static function analyze(string $symbol): array
    {
        $apiKey = self::apiKey();

        if (!$apiKey) {
            return [
                'risk' => 'UNKNOWN',
                'impact' => 'Neutral',
                'score_penalty' => 0,
                'message' => 'FMP API key not found.',
                'events' => [],
                'source' => 'none'
            ];
        }

        $endpoints = [
            [
                'source' => 'fmp_api_v4_general_news',
                'url' => 'https://financialmodelingprep.com/api/v4/general_news?' . http_build_query([
                    'page' => 0,
                    'apikey' => $apiKey
                ])
            ],
            [
                'source' => 'fmp_stable_general_latest',
                'url' => 'https://financialmodelingprep.com/stable/news/general-latest?' . http_build_query([
                    'page' => 0,
                    'limit' => 50,
                    'apikey' => $apiKey
                ])
            ],
            [
                'source' => 'fmp_api_v3_stock_news',
                'url' => 'https://financialmodelingprep.com/api/v3/stock_news?' . http_build_query([
                    'limit' => 50,
                    'apikey' => $apiKey
                ])
            ],
        ];

        $lastMessage = 'No geopolitical news endpoint responded.';

        foreach ($endpoints as $endpoint) {
            $res = self::request($endpoint['url']);

            if (!$res['ok']) {
                $lastMessage = $res['error'] ?: ('HTTP ' . $res['http']);
                continue;
            }

            $headlines = self::normalize($res['json']);
            $risk = self::score($symbol, $headlines);
            $risk['source'] = $endpoint['source'];

            return $risk;
        }

        return [
            'risk' => 'UNKNOWN',
            'impact' => 'Neutral',
            'score_penalty' => 0,
            'message' => $lastMessage,
            'events' => [],
            'source' => 'fmp_failed'
        ];
    }

    private static function normalize(array $rows): array
    {
        $items = [];

        foreach ($rows as $row) {
            if (!is_array($row)) continue;

            $items[] = [
                'title' => (string)($row['title'] ?? $row['headline'] ?? 'News headline'),
                'time' => $row['publishedDate'] ?? $row['date'] ?? '',
                'text' => (string)($row['text'] ?? $row['summary'] ?? ''),
                'url' => $row['url'] ?? '',
                'raw' => $row
            ];
        }

        return $items;
    }

    private static function score(string $symbol, array $items): array
    {
        $negative = [
            'war', 'conflict', 'attack', 'missile', 'sanctions', 'crisis', 'invasion',
            'oil shock', 'geopolitical', 'middle east', 'iran', 'israel', 'russia',
            'ukraine', 'taiwan', 'terror', 'escalation', 'safe haven', 'emergency'
        ];

        $positive = [
            'ceasefire', 'peace', 'deal reached', 'agreement', 'de-escalation',
            'talks resume', 'truce'
        ];

        $score = 0;
        $matched = [];

        foreach ($items as $item) {
            $text = strtolower($item['title'] . ' ' . $item['text']);
            $hit = false;

            foreach ($negative as $word) {
                if (str_contains($text, $word)) {
                    $score += 2;
                    $hit = true;
                }
            }

            foreach ($positive as $word) {
                if (str_contains($text, $word)) {
                    $score -= 1;
                    $hit = true;
                }
            }

            if ($hit) {
                $matched[] = $item;
            }
        }

        if ($score >= 8) {
            $risk = 'HIGH';
            $penalty = -3;
        } elseif ($score >= 3) {
            $risk = 'MEDIUM';
            $penalty = -1;
        } elseif ($score <= -2) {
            $risk = 'LOW';
            $penalty = 0;
        } else {
            $risk = 'LOW';
            $penalty = 0;
        }

        $impact = 'Neutral';

        if (strtoupper($symbol) === 'XAUUSD') {
            if ($risk === 'HIGH') {
                $impact = 'Bullish Gold safe-haven volatility likely';
            } elseif ($risk === 'MEDIUM') {
                $impact = 'Gold volatility may increase';
            }
        } elseif (str_contains(strtoupper($symbol), 'USD')) {
            if ($risk === 'HIGH') {
                $impact = 'USD volatility likely elevated';
            }
        }

        return [
            'risk' => $risk,
            'impact' => $impact,
            'score_penalty' => $penalty,
            'message' => count($matched)
                ? 'Geopolitical headlines detected and scored.'
                : 'No major geopolitical headline detected.',
            'sentiment' => $score,
            'events' => array_slice($matched, 0, 5)
        ];
    }
}
