using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using PolyTrader.Core.Notifications;
using PolyTrader.Modules.Supervisor.Agent;
using PolyTrader.Modules.Supervisor.Persistence;
using PolyTraderSharp.Services;

namespace PolyTrader.Modules.Supervisor.Services
{
    /// <summary>
    /// Täglicher Supervisor-Bericht (S-3): lässt den Agenten einmal am Tag eine Kurz-Analyse der
    /// letzten 24 h erstellen (KPIs, Auffälligkeiten, Fehler) und sendet sie über den konfigurierten
    /// Benachrichtigungskanal (<see cref="INotificationSink"/>); zusätzlich
    /// als sup_report gespeichert. OPT-IN: läuft nur, wenn POLYTRADER_SUPERVISOR_DAILY die Ziel-Stunde
    /// (0–23, lokale Zeit) enthält — und braucht den OpenRouter-Key (sonst still übersprungen).
    /// </summary>
    public sealed class DailyReportService : BackgroundService
    {
        public const string DailyPrompt =
            "Erstelle den täglichen Supervisor-Kurzbericht für die letzten 24 Stunden: " +
            "1) KPIs gesamt und je Modul (get_kpis, sinceDays=1), 2) auffällige Fehler/Warnings " +
            "(read_logs, level=Error für heute), 3) bemerkenswerte Reject-Häufungen (query_decisions, " +
            "sinceHours=24, decision=Rejected). Maximal ~1200 Zeichen, deutsch, stichpunktartig, " +
            "mit klarem Fazit (läuft alles normal / Handlungsbedarf X).";

        private readonly SupervisorAgent _agent;
        private readonly ISupervisorReportRepository _reports;
        private readonly Func<string, Task> _sendAsync;   // Versand (injizierbar für Tests)
        private readonly TerminalLogger _logger;

        public DailyReportService(SupervisorAgent agent, ISupervisorReportRepository reports,
            INotificationSink notify, TerminalLogger logger)
            : this(agent, reports, async msg => await notify.SendAsync(msg, NotificationSeverity.Info), logger) { }

        internal DailyReportService(SupervisorAgent agent, ISupervisorReportRepository reports,
            Func<string, Task> sendAsync, TerminalLogger logger)
        {
            _agent = agent;
            _reports = reports;
            _sendAsync = sendAsync;
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            string? hourRaw = Environment.GetEnvironmentVariable("POLYTRADER_SUPERVISOR_DAILY");
            if (string.IsNullOrWhiteSpace(hourRaw))
            {
                _logger.Info("Supervisor-Tagesbericht: deaktiviert (POLYTRADER_SUPERVISOR_DAILY nicht gesetzt; Wert = Stunde 0–23).");
                return;
            }
            if (!int.TryParse(hourRaw, out int hour) || hour is < 0 or > 23)
            {
                _logger.Warning($"Supervisor-Tagesbericht: ungültige Stunde '{hourRaw}' – deaktiviert.");
                return;
            }

            _logger.Info($"Supervisor-Tagesbericht aktiv: täglich um {hour:D2}:00 (lokal).");
            while (!stoppingToken.IsCancellationRequested)
            {
                var now = DateTime.Now;
                var next = now.Date.AddHours(hour);
                if (next <= now) next = next.AddDays(1);
                try { await Task.Delay(next - now, stoppingToken); }
                catch (OperationCanceledException) { break; }

                try { await RunOnceAsync(stoppingToken); }
                catch (Exception ex) { _logger.Error($"Supervisor-Tagesbericht fehlgeschlagen: {ex.Message}"); }
            }
        }

        /// <summary>Testbarer Kern: erstellt den Bericht, sendet ihn und legt ihn ab.</summary>
        internal async Task RunOnceAsync(CancellationToken ct)
        {
            if (string.IsNullOrWhiteSpace(OpenRouterClient.DefaultApiKeyProvider()))
            {
                _logger.Info("Supervisor-Tagesbericht: übersprungen (kein OpenRouter-Key).");
                return;
            }

            var result = await _agent.AskAsync(DailyPrompt, profile: SupervisorProfiles.Allgemein, ct: ct);

            _reports.Insert(new SupervisorReport
            {
                Profile = "Tagesbericht",
                Model = SupervisorAgent.DefaultModel,
                Question = DailyPrompt,
                Answer = result.Answer,
                ToolCallCount = result.ToolInvocations.Count,
                PromptTokens = result.PromptTokens,
                CompletionTokens = result.CompletionTokens
            });

            try { await _sendAsync($"📋 Supervisor-Tagesbericht\n\n{result.Answer}"); }
            catch (Exception ex) { _logger.Error($"Tagesbericht-Versand fehlgeschlagen: {ex.Message}"); }

            _logger.Info("📋 Supervisor-Tagesbericht erstellt und versendet.");
        }
    }
}
