using System.ComponentModel;
using System.Text.Json.Serialization;
using ClawdDotNet.Core.Storage;

namespace ClawdDotNet.App.Settings;

/// <summary>
/// Anwendungsweite Einstellungen (nicht instanzgebunden).
///
/// Die <see cref="CategoryAttribute"/>-, <see cref="DisplayNameAttribute"/>- und
/// <see cref="DescriptionAttribute"/>-Angaben stammen aus der PropertyGrid-Zeit. Sie
/// bleiben stehen: Sie sind die Beschriftungen und Hilfetexte, aus denen die
/// Avalonia-Einstellungsansicht gebaut wird — nur eben von Hand statt automatisch.
/// </summary>
public sealed class AppSettings
{
    // Die Vorgaben waren "./Logs" und "./Instances" — relativ zum Arbeitsverzeichnis.
    // Unter Linux liegt die Anwendung in /opt oder /usr/lib und darf dort nicht
    // schreiben; zudem hing der Ort davon ab, aus welchem Verzeichnis gestartet wurde.
    // Jetzt absolute Pfade im Datenverzeichnis des Benutzers (siehe AppPaths).
    [Category("Allgemein")]
    [DisplayName("Log-Verzeichnis")]
    [Description("Pfad zum Verzeichnis, in dem Log-Dateien gespeichert werden.")]
    [JsonPropertyName("logDirectory")]
    public string LogDirectory { get; set; } = Path.Combine(AppPaths.DataDirectory, "Logs");

    [Category("Allgemein")]
    [DisplayName("Instanzen-Verzeichnis")]
    [Description("Pfad zum Verzeichnis, in dem alle Instanz-Ordner liegen.")]
    [JsonPropertyName("instancesDirectory")]
    public string InstancesDirectory { get; set; } = Path.Combine(AppPaths.DataDirectory, "Instances");

    // DefaultConfigPath ist ersatzlos entfallen. Die Eigenschaft war als „(Legacy)"
    // markiert und wurde von keiner Stelle mehr gelesen — sie stand nur noch als
    // relativer Pfad in der Datei und hätte unter Linux ohnehin ins Leere gezeigt.

    [Category("Allgemein")]
    [DisplayName("Minimaler Log-Level")]
    [Description("Minimaler Log-Level für die Datei-Logs (Debug, Info, Warn, Error).")]
    [JsonPropertyName("minimumLogLevel")]
    public string MinimumLogLevel { get; set; } = "Info";

    [Category("UI")]
    [DisplayName("Max. Log-Zeilen in UI")]
    [Description("Maximale Anzahl Zeilen in der Log-RichTextBox bevor bereinigt wird.")]
    [JsonPropertyName("maxLogLinesInUi")]
    public int MaxLogLinesInUi { get; set; } = 2000;

    [Category("UI")]
    [DisplayName("Log-Aktualisierungsintervall (ms)")]
    [Description("Intervall in Millisekunden, in dem die Log-Anzeige aktualisiert wird.")]
    [JsonPropertyName("logRefreshIntervalMs")]
    public int LogRefreshIntervalMs { get; set; } = 500;

    // ─── Zustand der Oberflaeche ───
    //
    // Bewusst hier und nicht in der Instanzkonfiguration: Das sind Gewohnheiten des
    // Benutzers am Geraet, keine Eigenschaften der Instanz. Wer zwischen zwei Instanzen
    // wechselt, will nicht jedes Mal wieder im Hellmodus mit ausgeklappter Leiste landen.

    [Category("UI")]
    [DisplayName("Farbschema")]
    [Description("Light oder Dark. Umschaltbar ueber das Symbol in der Kopfzeile.")]
    [JsonPropertyName("theme")]
    public string Theme { get; set; } = "Light";

    [Category("UI")]
    [DisplayName("Seitenleiste eingeklappt")]
    [Description("Merkt sich, ob die Navigation auf Symbolbreite zusammengeklappt war.")]
    [JsonPropertyName("sidebarCollapsed")]
    public bool SidebarCollapsed { get; set; }

    // Die drei Teiler der Agenten-Seite, jeweils als Anteil 0..1 der Gesamtflaeche.
    // Als Verhaeltnis und nicht in Pixeln: Sonst sitzt der Teiler nach einem Wechsel
    // auf einen anderen Bildschirm an einer voellig anderen Stelle.

    [Category("UI")]
    [DisplayName("Agenten-Seite: Teiler waagerecht")]
    [Description("Anteil des oberen Bereichs (Agentenliste und Einstellungen), 0.2 bis 0.8.")]
    [JsonPropertyName("agentsSplitVertical")]
    public double AgentsSplitVertical { get; set; } = 0.55;

    [Category("UI")]
    [DisplayName("Agenten-Seite: Teiler oben")]
    [Description("Anteil der Agentenliste an der Breite des oberen Bereichs, 0.2 bis 0.8.")]
    [JsonPropertyName("agentsSplitTopList")]
    public double AgentsSplitTopList { get; set; } = 0.44;

    [Category("UI")]
    [DisplayName("Agenten-Seite: Teiler unten")]
    [Description("Anteil der Werkzeugliste an der Breite des unteren Bereichs, 0.2 bis 0.8.")]
    [JsonPropertyName("agentsSplitBottomList")]
    public double AgentsSplitBottomList { get; set; } = 0.44;

    [Category("API")]
    [DisplayName("Status-Check-Intervall (Sek)")]
    [Description("Intervall in Sekunden für den OpenRouter-API-Status-Check.")]
    [JsonPropertyName("statusCheckIntervalSeconds")]
    public int StatusCheckIntervalSeconds { get; set; } = 60;

    [Category("API")]
    [DisplayName("OpenRouter Base-URL")]
    [Description("Basis-URL der OpenRouter-API.")]
    [JsonPropertyName("openRouterBaseUrl")]
    public string OpenRouterBaseUrl { get; set; } = "https://openrouter.ai/api/v1/";

    [Category("Backup")]
    [DisplayName("Backup-Verzeichnis")]
    [Description("Ordner, in dem Sicherungen abgelegt werden.")]
    [JsonPropertyName("backupDirectory")]
    public string BackupDirectory { get; set; } = Path.Combine(AppPaths.DataDirectory, "Backups");

    [Category("Backup")]
    [DisplayName("Automatisch sichern")]
    [Description("Erstellt täglich zur angegebenen Uhrzeit eine Sicherung der laufenden Instanz.")]
    [JsonPropertyName("autoBackupEnabled")]
    public bool AutoBackupEnabled { get; set; }

    [Category("Backup")]
    [DisplayName("Uhrzeit der automatischen Sicherung")]
    [Description("Tageszeit im Format HH:mm.")]
    [JsonPropertyName("autoBackupTime")]
    public string AutoBackupTime { get; set; } = "03:00";

    [Category("Backup")]
    [DisplayName("Aufbewahrte Sicherungen")]
    [Description("Wie viele Sicherungen je Instanz behalten werden. Ältere werden entfernt. 0 = alle behalten.")]
    [JsonPropertyName("backupKeepCount")]
    public int BackupKeepCount { get; set; } = 14;

    // ─── Deploymentcenter ───
    //
    // Ein Server, ein Token. Lizenz, Watchdog, Updates, Fehler-Stream und Bugtracker
    // sind Module derselben Anwendung — die frühere Aufteilung auf zwei Adressen
    // (watchdog.mhdf.de, license.mhdf.de) mit je eigenem Schlüssel gibt es nicht mehr.

    [Category("Deploymentcenter")]
    [DisplayName("Server-URL")]
    [Description("Basis-URL des Deploymentcenters (nur HTTPS, Ausnahme localhost).")]
    [JsonPropertyName("deploymentcenterUrl")]
    public string DeploymentcenterUrl { get; set; } = "https://dc.mhdf.de";

    [Category("Deploymentcenter")]
    [DisplayName("Token")]
    [Description("Master-Token mit den Rechten 'watchdog:ping' und 'bugtracker:report'. " +
                 "Jede Instanz tauscht es beim ersten Start gegen ein eigenes, " +
                 "eingeschränktes Sub-Token. Wird verschlüsselt gespeichert.")]
    [PasswordPropertyText(true)]
    [JsonPropertyName("deploymentcenterToken")]
    public string DeploymentcenterToken { get; set; } = "";

    [Category("Deploymentcenter")]
    [DisplayName("Umgebung")]
    [Description("Wird an Fehler- und Bugtracker-Meldungen gehängt: production oder development.")]
    [JsonPropertyName("deploymentcenterEnvironment")]
    public string DeploymentcenterEnvironment { get; set; } = "production";

    [Category("Deploymentcenter")]
    [DisplayName("Fehler automatisch melden")]
    [Description("Meldet ungefangene Ausnahmen an den Fehler-Stream des Deploymentcenters. " +
                 "Derselbe Fehler geht höchstens alle fünf Minuten einmal raus.")]
    [JsonPropertyName("errorReportingEnabled")]
    public bool ErrorReportingEnabled { get; set; } = true;

    [Category("Deploymentcenter")]
    [DisplayName("Beim Start auf Updates prüfen")]
    [Description("Fragt einmalig beim Start, ob ein neueres Release vorliegt. Blockiert nicht.")]
    [JsonPropertyName("updateCheckEnabled")]
    public bool UpdateCheckEnabled { get; set; } = true;

    [Category("Deploymentcenter")]
    [DisplayName("Update-Kanal")]
    [Description("prod, beta oder dev.")]
    [JsonPropertyName("updateChannel")]
    public string UpdateChannel { get; set; } = "prod";

    // ─── Lizenz ───

    [Category("Lizenz")]
    [DisplayName("Lizenzschlüssel")]
    [Description("Der Lizenzschlüssel für ClawdDotNet. Wird verschlüsselt gespeichert.")]
    [PasswordPropertyText(true)]
    [JsonPropertyName("licenseKey")]
    public string LicenseKey { get; set; } = "";

    // LicensePublicKeyBase64 und LicenseEndpoints sind entfallen. Das Deploymentcenter
    // signiert seine Antworten nicht (siehe LicenseInfo), ein Public-Key hätte also
    // nichts zu prüfen; und der Lizenzserver ist dasselbe Deploymentcenter, dessen
    // Adresse oben steht — zwei Felder für eine Adresse waren nur eine Gelegenheit,
    // sie widersprüchlich zu füllen.

    public override string ToString() => "Anwendungseinstellungen";
}
