using System.IO;
using System.IO.Compression;
using System.Text.Json;

namespace NexusShell.Services.Diagnostics;

public sealed class DiagnosticSessionManager
{
    public const string DefaultDiagnosticsRoot = @"C:\NinjaNexusPOC\logs\diagnostics";
    public const string DefaultExportRoot = @"C:\NinjaNexusPOC\logs\exports";

    private readonly WorkspaceEventLog _eventLog;
    private DiagnosticSessionInfo? _activeSession;

    public DiagnosticSessionManager(WorkspaceEventLog eventLog)
    {
        _eventLog = eventLog;
    }

    public DiagnosticSessionInfo? ActiveSession => _activeSession;
    public string DiagnosticsRoot { get; private set; } = DefaultDiagnosticsRoot;
    public string ExportRoot { get; private set; } = DefaultExportRoot;

    public void ConfigureRoot(string? rootPath)
    {
        if (!string.IsNullOrWhiteSpace(rootPath))
        {
            DiagnosticsRoot = rootPath;
            ExportRoot = Path.Combine(Path.GetDirectoryName(rootPath) ?? rootPath, "exports");
        }
    }

    public void ConfigureExportRoot(string? exportRootPath)
    {
        if (!string.IsNullOrWhiteSpace(exportRootPath))
        {
            ExportRoot = exportRootPath;
        }
    }

    public DiagnosticSessionInfo StartSession()
    {
        if (_activeSession is { IsActive: true } existing)
        {
            return existing;
        }

        var sessionId = DateTime.Now.ToString("yyyyMMdd-HHmmss");
        var sessionDir = Path.Combine(DiagnosticsRoot, "sessions", sessionId);
        Directory.CreateDirectory(sessionDir);

        _activeSession = new DiagnosticSessionInfo
        {
            SessionId = sessionId,
            SessionDirectory = sessionDir,
            StartedAtUtc = DateTimeOffset.UtcNow,
            IsActive = true,
        };

        _eventLog.BindSession(sessionDir);
        WriteSessionManifest(_activeSession);
        return _activeSession;
    }

    public void EndSession()
    {
        if (_activeSession is null || !_activeSession.IsActive)
        {
            return;
        }

        _activeSession.EndedAtUtc = DateTimeOffset.UtcNow;
        _activeSession.IsActive = false;
        WriteSessionManifest(_activeSession);
    }

    public async Task<string> ExportSessionZipAsync(CancellationToken cancellationToken = default)
    {
        if (_activeSession is null)
        {
            throw new InvalidOperationException("Ingen aktiv diagnostiksession.");
        }

        await _eventLog.FlushAsync(cancellationToken);

        Directory.CreateDirectory(ExportRoot);
        var zipPath = Path.Combine(ExportRoot, $"nexus-diagnostics-{_activeSession.SessionId}.zip");

        if (File.Exists(zipPath))
        {
            File.Delete(zipPath);
        }

        ZipFile.CreateFromDirectory(_activeSession.SessionDirectory, zipPath, CompressionLevel.Optimal, false);
        return zipPath;
    }

    public void OpenLogsFolder()
    {
        var target = _activeSession?.SessionDirectory ?? Path.Combine(DiagnosticsRoot, "sessions");
        Directory.CreateDirectory(target);
        System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
        {
            FileName = target,
            UseShellExecute = true,
        });
    }

    private void WriteSessionManifest(DiagnosticSessionInfo session)
    {
        var manifestPath = Path.Combine(session.SessionDirectory, "session.json");
        var manifest = new
        {
            session.SessionId,
            session.StartedAtUtc,
            session.EndedAtUtc,
            session.IsActive,
            ExportedAt = DateTimeOffset.UtcNow,
        };
        File.WriteAllText(manifestPath, JsonSerializer.Serialize(manifest, new JsonSerializerOptions { WriteIndented = true }));
    }
}
