using System.Net.Http;

namespace AxCopilot.Services;

/// <summary>
/// Phase L3-9: 서버 상태 모니터 서비스.
/// Ollama / LLM API / 첫 번째 활성 MCP 서버의 연결 상태를 주기적으로 확인합니다.
/// 싱글턴 — 런처 표시 시 Start(), 숨김 시 Stop().
/// </summary>
internal sealed class ServerStatusService
{
    public static readonly ServerStatusService Instance = new();

    private static readonly HttpClient _http = new()
    {
        Timeout = TimeSpan.FromMilliseconds(1500)
    };

    // ─── 공개 상태 ───────────────────────────────────────────────────────────

    public bool   OllamaOnline { get; private set; }
    public bool   LlmOnline    { get; private set; }
    public bool   McpOnline    { get; private set; }
    public string McpName      { get; private set; } = "MCP";

    public event EventHandler? StatusChanged;

    // ─── 내부 ────────────────────────────────────────────────────────────────

    private System.Threading.Timer? _timer;
    private string _ollamaEndpoint = "http://localhost:11434";
    private string _llmEndpoint    = "";
    private string _llmService     = "Ollama";
    private string _mcpEndpoint    = "";

    private ServerStatusService() { }

    public void Start(AxCopilot.Models.AppSettings? settings = null)
    {
        LoadEndpoints(settings);
        if (_timer != null) return;
        _timer = new System.Threading.Timer(async _ => await CheckAllAsync(), null, 0, 15_000);
    }

    public void Stop()
    {
        _timer?.Dispose();
        _timer = null;
    }

    public void Refresh(AxCopilot.Models.AppSettings? settings = null)
    {
        LoadEndpoints(settings);
        _ = CheckAllAsync();
    }

    // ─── 내부 ────────────────────────────────────────────────────────────────

    private void LoadEndpoints(AxCopilot.Models.AppSettings? settings)
    {
        var llm = settings?.Llm;
        if (llm == null) return;

        _ollamaEndpoint = llm.OllamaEndpoint?.TrimEnd('/') ?? "http://localhost:11434";
        _llmService     = llm.Service ?? "Ollama";

        // LLM API 엔드포인트: vLLM이면 별도, 나머지는 Ollama와 동일
        _llmEndpoint = _llmService.Equals("vLLM", StringComparison.OrdinalIgnoreCase)
            ? (llm.VllmEndpoint?.TrimEnd('/') ?? "")
            : _ollamaEndpoint;

        // 첫 번째 활성 MCP 서버
        var mcp = llm.McpServers?.FirstOrDefault(s => s.Enabled && !string.IsNullOrEmpty(s.Url));
        if (mcp != null)
        {
            McpName      = mcp.Name;
            _mcpEndpoint = mcp.Url?.TrimEnd('/') ?? "";
        }
        else
        {
            McpName      = "MCP";
            _mcpEndpoint = "";
        }
    }

    private async Task CheckAllAsync()
    {
        var t1 = PingAsync(_ollamaEndpoint + "/api/version");
        var t2 = string.IsNullOrEmpty(_llmEndpoint) || _llmEndpoint == _ollamaEndpoint
            ? t1
            : PingAsync(_llmEndpoint);
        var t3 = string.IsNullOrEmpty(_mcpEndpoint)
            ? Task.FromResult(false)
            : PingAsync(_mcpEndpoint);

        await Task.WhenAll(t1, t2, t3).ConfigureAwait(false);

        bool changed =
            OllamaOnline != t1.Result ||
            LlmOnline    != t2.Result ||
            McpOnline    != t3.Result;

        OllamaOnline = t1.Result;
        LlmOnline    = t2.Result;
        McpOnline    = t3.Result;

        if (changed)
            StatusChanged?.Invoke(this, EventArgs.Empty);
    }

    private static async Task<bool> PingAsync(string url)
    {
        if (string.IsNullOrEmpty(url)) return false;
        try
        {
            var resp = await _http.GetAsync(url).ConfigureAwait(false);
            return resp.IsSuccessStatusCode || (int)resp.StatusCode < 500;
        }
        catch
        {
            return false;
        }
    }
}
