using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Extensions.DependencyInjection;
using PSLauncher.App.ViewModels;
using PSLauncher.Core.Security;

namespace PSLauncher.App.Views;

public partial class SettingsDialog : Window
{
    private readonly SettingsViewModel _vm;

    public SettingsDialog(SettingsViewModel vm)
    {
        InitializeComponent();
        DataContext = _vm = vm;
    }

    private void OnSave(object sender, RoutedEventArgs e)
    {
        _vm.SaveCommand.Execute(null);
        DialogResult = true;
        Close();
    }

    private void OnCancel(object sender, RoutedEventArgs e)
    {
        DialogResult = false;
        Close();
    }

    /// <summary>
    /// Quand l'opérateur clique pour déplier les paramètres avancés, on vérifie le
    /// settings lock service. Si verrouillé, on affiche le password prompt. Si Cancel
    /// ou mauvais mot de passe, on referme l'expander pour que la section reste cachée.
    ///
    /// Trace écrite dans un fichier dédié (settings-lock.log) à chaque appel pour
    /// permettre de diagnostiquer les cas "l'expander se déplie pas" sans dépendre
    /// du Serilog principal (au cas où l'event ne traverserait même pas le code).
    /// </summary>
    private void OnAdvancedExpanded(object sender, RoutedEventArgs e)
    {
        TraceExpanded("OnAdvancedExpanded fired");
        if (sender is not Expander exp)
        {
            TraceExpanded("sender is not Expander, aborting");
            return;
        }

        // Résout le service depuis l'App DI container. Service-locator pattern toléré
        // ici car SettingsDialog n'est pas injectable directement (instancié par new).
        var app = (App)Application.Current;
        var lockService = app.HostServices?.GetService<ISettingsLockService>();
        if (lockService is null)
        {
            TraceExpanded("lockService is null, expander stays open");
            return;
        }
        TraceExpanded($"lockService.HasLockConfigured={lockService.HasLockConfigured} IsLocked={lockService.IsLocked}");
        if (!lockService.IsLocked)
        {
            TraceExpanded("not locked, expander stays open");
            return;
        }

        TraceExpanded("locked, showing password dialog");
        bool? ok = null;
        try
        {
            var dialog = new SettingsLockDialog(lockService) { Owner = this };
            ok = dialog.ShowDialog();
            TraceExpanded($"dialog result: {ok}");
        }
        catch (Exception ex)
        {
            // Toute exception (XAML parse error, missing resource, etc.) doit être
            // logguée et NE PAS rester silencieuse. Sans ce catch, le bug se manifeste
            // par "rien ne s'ouvre, mais le log dit que ça devrait" (cas 0.28.2 avec
            // Brush.Status.Danger inexistant).
            TraceExpanded($"EXCEPTION creating/showing SettingsLockDialog: {ex.GetType().Name}: {ex.Message}");
            // On laisse l'expander DÉPLIÉ (ok=null tombera dans le if false ci-dessous
            // qui le refermerait). Plutôt : on garde déplié pour ne pas frustrer l'user
            // si le lock dialog est cassé — il aura accès, et le bug doit être réglé.
            return;
        }
        if (ok != true)
        {
            // Cancel ou mauvais mot de passe → on referme l'expander.
            exp.IsExpanded = false;
        }
    }

    private static void TraceExpanded(string msg)
    {
        try
        {
            var dir = Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                "PSLauncher", "logs");
            Directory.CreateDirectory(dir);
            var path = Path.Combine(dir, "settings-lock.log");
            File.AppendAllText(path,
                $"{DateTime.UtcNow:yyyy-MM-dd HH:mm:ss.fff}Z  {msg}{Environment.NewLine}");
        }
        catch { /* best effort */ }
    }
}
