using ITNexusAgent.Models;
using Newtonsoft.Json;
using System.Diagnostics;
using System.Management;
using System.Text;

namespace ITNexusAgent.Services;

public class NotificationService
{
    private readonly string _exePath;
    private readonly string _dataDir;
    private readonly string _shownIdsPath;
    private readonly HashSet<int> _shownIds;

    public NotificationService(string exePath, string dataDir)
    {
        _exePath = exePath;
        _dataDir = dataDir;
        _shownIdsPath = Path.Combine(dataDir, "shown_announcements.json");
        _shownIds = LoadShownIds();
    }

    private HashSet<int> LoadShownIds()
    {
        try
        {
            if (File.Exists(_shownIdsPath))
            {
                var ids = JsonConvert.DeserializeObject<List<int>>(File.ReadAllText(_shownIdsPath));
                return ids != null ? new HashSet<int>(ids) : [];
            }
        }
        catch { }
        return [];
    }

    public void RemoveShownId(int id)
    {
        if (_shownIds.Remove(id)) SaveShownIds();
    }

    private void SaveShownIds()
    {
        try { File.WriteAllText(_shownIdsPath, JsonConvert.SerializeObject(_shownIds.ToList())); }
        catch { }
    }

    public void ShowAnnouncements(List<Announcement> announcements)
    {
        foreach (var ann in announcements)
        {
            if (_shownIds.Contains(ann.Id)) continue;
            _shownIds.Add(ann.Id);
            SaveShownIds();
            ShowNotification(ann);
        }
    }

    // Vollständigen eingeloggten User aus WMI holen (z.B. "WINKEL\gruessing" oder "AzureAD\gruessing")
    public static string GetLoggedOnUser()
    {
        try
        {
            using var searcher = new ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem");
            foreach (ManagementObject obj in searcher.Get())
            {
                var user = obj["UserName"]?.ToString();
                if (!string.IsNullOrEmpty(user)) return user;
            }
        }
        catch { }
        return "";
    }

    private void ShowNotification(Announcement ann)
    {
        try
        {
            var fullUser = GetLoggedOnUser();
            if (string.IsNullOrEmpty(fullUser)) return;

            var json = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(ann)));
            var taskName = $"ITNexus-Ann-{ann.Id}";

            // Alten Task entfernen
            Process.Start(new ProcessStartInfo("schtasks.exe", $"/delete /tn \"{taskName}\" /f")
            { CreateNoWindow = true })?.WaitForExit();

            // Task mit Trigger weit in der Zukunft erstellen (damit er nicht abläuft vor /run)
            var triggerTime = DateTime.Now.AddMinutes(60).ToString("HH:mm:ss");
            // AzureAD-User (Entra/Hybrid-Join) können nicht per /ru aufgelöst werden → INTERACTIVE
            var ruArg = fullUser.StartsWith("AzureAD\\", StringComparison.OrdinalIgnoreCase)
                ? "/ru \"INTERACTIVE\""
                : $"/ru \"{fullUser}\"";
            var args = $"/create /tn \"{taskName}\" /tr \"\\\"{_exePath}\\\" --notify {json}\" " +
                       $"/sc ONCE /st {triggerTime} {ruArg} /it /f";
            var p = Process.Start(new ProcessStartInfo("schtasks.exe", args)
            { CreateNoWindow = true, RedirectStandardError = true, UseShellExecute = false });
            p?.WaitForExit();

            // Sofort ausführen
            var run = Process.Start(new ProcessStartInfo("schtasks.exe", $"/run /tn \"{taskName}\"")
            { CreateNoWindow = true });
            run?.WaitForExit();

            // Task löschen damit der +60min Trigger nicht nochmal feuert
            Thread.Sleep(3000);
            Process.Start(new ProcessStartInfo("schtasks.exe", $"/delete /tn \"{taskName}\" /f")
            { CreateNoWindow = true })?.WaitForExit();

            AgentWorker.Log($"NOTIFY: Task '{taskName}' für User '{fullUser}' gestartet (ExitCode={p?.ExitCode})");
        }
        catch (Exception ex)
        {
            AgentWorker.Log($"NOTIFY ERROR: {ex.Message}");
        }
    }
}
