using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace NexusShell.Agent;

public sealed class NexusAgentConfig
{
    public const string AgentVersion = "1.0.0";
    public const string DefaultLocalApiUrl = "http://127.0.0.1:5055";

    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        WriteIndented = true,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
    };

    public string DeviceId { get; set; } = string.Empty;
    public string BackendUrl { get; set; } = "http://localhost:5050";
    public string LocalApiUrl { get; set; } = DefaultLocalApiUrl;
    public int HeartbeatIntervalSeconds { get; set; } = 30;
    public DateTimeOffset? LastHeartbeatUtc { get; set; }
    public DateTimeOffset? RegisteredAtUtc { get; set; }
    public bool IsRegistered { get; set; }

    public static string AgentDirectory =>
        Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
            "NinjaNexus",
            "agent");

    public static string ConfigFilePath => Path.Combine(AgentDirectory, "agent-config.json");

    public static string LogsDirectory => Path.Combine(AgentDirectory, "logs");

    public static NexusAgentConfig Load(string defaultBackendUrl, string shellVersion, string? preferredDeviceId = null)
    {
        Directory.CreateDirectory(AgentDirectory);
        Directory.CreateDirectory(LogsDirectory);

        NexusAgentConfig config;
        if (File.Exists(ConfigFilePath))
        {
            var json = File.ReadAllText(ConfigFilePath);
            config = JsonSerializer.Deserialize<NexusAgentConfig>(json, JsonOptions) ?? new NexusAgentConfig();
        }
        else
        {
            config = new NexusAgentConfig();
        }

        if (string.IsNullOrWhiteSpace(config.BackendUrl))
        {
            config.BackendUrl = defaultBackendUrl.TrimEnd('/');
        }

        if (string.IsNullOrWhiteSpace(config.LocalApiUrl))
        {
            config.LocalApiUrl = DefaultLocalApiUrl;
        }

        if (!string.IsNullOrWhiteSpace(preferredDeviceId))
        {
            config.DeviceId = preferredDeviceId;
            config.Save();
        }
        else if (string.IsNullOrWhiteSpace(config.DeviceId))
        {
            NexusAgentLogger.Info("device", $"DeviceId pending identity enrollment (shell {shellVersion})");
        }

        return config;
    }

    public void Save()
    {
        Directory.CreateDirectory(AgentDirectory);
        var json = JsonSerializer.Serialize(this, JsonOptions);
        File.WriteAllText(ConfigFilePath, json);
    }

    public static string GenerateDeviceId() =>
        $"NEXUS-{Guid.NewGuid().ToString("N")[..8].ToUpperInvariant()}";
}
