using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using PersonalToolBox.Models;

namespace PersonalToolBox.Services;

/// <summary>
/// 进程执行服务，负责启动外部工具进程并处理异常
/// 支持一键多开：当 IsGroup 为 true 时批量启动子工具（支持嵌套组合，带循环检测）
/// </summary>
public class ProcessExecutionService : IProcessExecutionService
{
    private readonly ILogService _logService;
    private readonly IDataService _dataService;

    public ProcessExecutionService(ILogService logService, IDataService dataService)
    {
        _logService = logService;
        _dataService = dataService;
    }

    public async Task ExecuteAsync(ToolItem tool)
    {
        if (tool == null)
        {
            _logService.Error("尝试执行空工具项");
            return;
        }

        if (tool.IsGroup)
        {
            await ExecuteGroupAsync(tool, new HashSet<string>());
            return;
        }

        if (!tool.IsValid)
        {
            _logService.Warning($"无法运行工具 \"{tool.Name}\"，路径失效: {tool.ExecutablePath}");
            return;
        }

        LaunchSingleTool(tool);
    }

    /// <summary>
    /// 批量启动组合中的所有子工具，支持嵌套组合，每次间隔 500ms 防止系统卡顿
    /// </summary>
    private async Task ExecuteGroupAsync(ToolItem group, HashSet<string> visited)
    {
        if (!visited.Add(group.Id))
        {
            _logService.Warning($"组合启动跳过：检测到循环引用 ({group.Name})");
            return;
        }

        var subTools = new List<ToolItem>();
        foreach (var subId in group.SubToolIds)
        {
            var subTool = _dataService.Config.Tools.FirstOrDefault(t => t.Id == subId);
            if (subTool == null)
            {
                _logService.Warning($"组合启动跳过：找不到 ID 为 {subId} 的工具");
                continue;
            }
            subTools.Add(subTool);
        }

        _logService.Info($"开始启动组合 \"{group.Name}\"，共 {subTools.Count} 个工具");

        foreach (var subTool in subTools)
        {
            if (subTool.IsGroup)
            {
                await ExecuteGroupAsync(subTool, visited);
            }
            else
            {
                if (!subTool.IsValid)
                {
                    _logService.Warning($"组合启动跳过 \"{subTool.Name}\"，路径失效: {subTool.ExecutablePath}");
                    continue;
                }
                LaunchSingleTool(subTool);
            }
            await Task.Delay(500);
        }

        _logService.Info($"组合 \"{group.Name}\" 启动完成");
    }

    /// <summary>
    /// 启动单个工具进程
    /// </summary>
    private void LaunchSingleTool(ToolItem tool)
    {
        try
        {
            var startInfo = new ProcessStartInfo
            {
                FileName = tool.ExecutablePath,
                Arguments = tool.Arguments ?? string.Empty,
                UseShellExecute = true
            };

            Process.Start(startInfo);
            _logService.Info($"成功启动: {tool.Name}");
        }
        catch (Exception ex)
        {
            _logService.Error($"启动工具 \"{tool.Name}\" 失败: {ex.Message}");
        }
    }
}
