using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using Microsoft.Extensions.DependencyInjection;
using PersonalToolBox.Services;
using PersonalToolBox.Views;

namespace PersonalToolBox;

/// <summary>
/// WPF 应用程序入口，负责依赖注入容器初始化和启动主窗口
/// </summary>
public partial class App : System.Windows.Application
{
    public static IServiceProvider Services { get; private set; } = null!;

    private static readonly string CrashLogPath = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
        "PersonalToolBox", "crash.log");

    private const string AppMutexName = "PersonalToolBox_SingleInstance_8E2F4A1C";
    private static Mutex? _mutex;

    [DllImport("user32.dll")]
    private static extern uint RegisterWindowMessage(string lpString);

    [DllImport("user32.dll")]
    private static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

    private static readonly IntPtr HWND_BROADCAST = new IntPtr(0xFFFF);

    public App()
    {
        // 监听未处理的异常，写入文件日志
        DispatcherUnhandledException += (s, e) =>
        {
            WriteCrashLog($"UI线程异常: {e.Exception}");
            e.Handled = true;
            MessageBox.Show($"发生未处理异常:\n{e.Exception.Message}\n\n详情已写入:\n{CrashLogPath}",
                "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        };

        AppDomain.CurrentDomain.UnhandledException += (s, e) =>
        {
            WriteCrashLog($"未处理异常: {e.ExceptionObject}");
        };
    }

    protected override async void OnStartup(StartupEventArgs e)
    {
        _mutex = new Mutex(true, AppMutexName, out bool createdNew);
        if (!createdNew)
        {
            uint msg = RegisterWindowMessage("PersonalToolBox_ShowMain");
            PostMessage(HWND_BROADCAST, msg, IntPtr.Zero, IntPtr.Zero);
            Shutdown();
            return;
        }

        try
        {
            base.OnStartup(e);

            var services = new ServiceCollection();
            ConfigureServices(services);
            Services = services.BuildServiceProvider();

            // 启动时加载配置文件（含路径验证与容错）
            var dataService = Services.GetRequiredService<IDataService>();
            dataService.Load();

            var mainWindow = Services.GetRequiredService<MainWindow>();
            var mainViewModel = Services.GetRequiredService<ViewModels.MainViewModel>();

            // -autostart 参数：开机自启时隐藏窗口
            if (e.Args.Contains("-autostart", StringComparer.OrdinalIgnoreCase))
            {
                mainWindow.Hide();
            }
            else
            {
                mainWindow.Show();
            }

            // 启动标记为自动运行的工具和组合
            await mainViewModel.ExecuteAutoRunToolsAsync();
        }
        catch (Exception ex)
        {
            WriteCrashLog($"启动失败: {ex}");
            MessageBox.Show($"启动失败:\n{ex.Message}\n\n详情已写入:\n{CrashLogPath}",
                "启动错误", MessageBoxButton.OK, MessageBoxImage.Error);
            Shutdown();
        }
    }

    /// <summary>
    /// 注册所有服务到 DI 容器
    /// </summary>
    private static void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<ILogService, LogService>();
        services.AddSingleton<IDataService, JsonDataService>();
        services.AddSingleton<IProcessExecutionService, ProcessExecutionService>();
        services.AddSingleton<Helpers.HotKeyManager>();
        services.AddSingleton<ViewModels.MainViewModel>();
        services.AddTransient<ViewModels.ToolEditViewModel>();
        services.AddTransient<ViewModels.CategoryEditViewModel>();
        services.AddTransient<ViewModels.GroupEditViewModel>();
        services.AddSingleton<MainWindow>();
    }

    /// <summary>
    /// 将崩溃信息写入文件日志
    /// </summary>
    public static void WriteCrashLog(string message)
    {
        try
        {
            var dir = Path.GetDirectoryName(CrashLogPath);
            if (dir != null) Directory.CreateDirectory(dir);
            File.AppendAllText(CrashLogPath,
                $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}{Environment.NewLine}{Environment.NewLine}");
        }
        catch
        {
            // 无法写入日志时静默忽略
        }
    }
}
