using System.Text.Json;
using System.Text.Json.Serialization;
using BrassAndSigil.Server.Services;

namespace BrassAndSigil.Server.Models;

public sealed class ServerConfig
{
    [JsonPropertyName("manifestUrl")]
    public string ManifestUrl { get; set; } = "https://sijbers.uk/pack/manifest.json";

    [JsonPropertyName("serverDir")]
    public string ServerDir { get; set; } = "./server";

    [JsonPropertyName("javaPath")]
    public string JavaPath { get; set; } = "java";

    [JsonPropertyName("memoryMB")]
    public int MemoryMB { get; set; } = 8192;

    [JsonPropertyName("webPort")]
    public int WebPort { get; set; } = 8080;

    /// <summary>"localhost" by default -- bind to 0.0.0.0 only behind a reverse proxy.</summary>
    [JsonPropertyName("webHost")]
    public string WebHost { get; set; } = "localhost";

    /// <summary>Shared password for web UI. Required if WebHost is not localhost.</summary>
    [JsonPropertyName("webPassword")]
    public string? WebPassword { get; set; }

    /// <summary>Where world backups land. Empty -> &lt;serverDir&gt;/../backups. Set to a
    /// large/slower drive on real deployments -- backups grow over time.</summary>
    [JsonPropertyName("backupDir")]
    public string? BackupDir { get; set; }

    /// <summary>Auto-rotation: keep this many most recent backups, delete older.</summary>
    [JsonPropertyName("backupKeep")]
    public int BackupKeep { get; set; } = 10;

    /// <summary>Daily auto-backup time as "HH:mm" (24-hour, server-local). Null/empty disables.</summary>
    [JsonPropertyName("backupSchedule")]
    public string? BackupSchedule { get; set; }

    /// <summary>
    /// Where BlueMap CLI's working dir lives (cli.jar, configs, render output).
    /// Empty -> alongside &lt;serverDir&gt;/.. (default ~/brass-sigil-server/bluemap).
    /// Set to a big-disk path on real deployments -- rendered output for a 5000-block
    /// world is several GB.
    /// </summary>
    [JsonPropertyName("bluemapDir")]
    public string? BlueMapDir { get; set; }

    [JsonPropertyName("rconPort")]
    public int RconPort { get; set; } = 25575;

    [JsonPropertyName("rconPassword")]
    public string RconPassword { get; set; } = "";

    [JsonPropertyName("acceptEula")]
    public bool AcceptEula { get; set; } = false;

    public static ServerConfig Load(string path)
    {
        if (!File.Exists(path)) return new ServerConfig();
        var json = File.ReadAllText(path);
        return JsonSerializer.Deserialize<ServerConfig>(json, JsonOpts.CaseInsensitive) ?? new ServerConfig();
    }

    public void Save(string path)
    {
        var dir = Path.GetDirectoryName(Path.GetFullPath(path));
        if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) Directory.CreateDirectory(dir);
        var json = JsonSerializer.Serialize(this, JsonOpts.Pretty);
        File.WriteAllText(path, json);
    }
}
