using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using PersonalToolBox.Helpers;
using PersonalToolBox.Models;
using PersonalToolBox.Services;
namespace PersonalToolBox.ViewModels;
///
/// 组合编辑窗口 ViewModel,管理一键多开组合的创建与编辑
///
public partial class GroupEditViewModel : ObservableObject
{
private readonly IDataService _dataService;
private readonly ILogService _logService;
private readonly ToolItem? _editingGroup;
// ──────── 可观察属性 ────────
[ObservableProperty]
private string _windowTitle = "添加组合";
[ObservableProperty]
private string _name = string.Empty;
[ObservableProperty]
private string _hotKey = string.Empty;
[ObservableProperty]
private Category? _selectedCategory;
[ObservableProperty]
private IconProvider.IconOption? _selectedIcon;
[ObservableProperty]
private bool _autoRunOnStart;
///
/// 可供勾选的普通工具列表(IsGroup == false)
///
public ObservableCollection AvailableTools { get; } = new();
///
/// 分类下拉列表
///
public ObservableCollection Categories { get; } = new();
///
/// 按分类分组的可用图标列表
///
public ListCollectionView AvailableIconsView { get; }
public Action? CloseAction { get; set; }
public bool Saved { get; private set; }
// ──────── 构造 ────────
public GroupEditViewModel(IDataService dataService, ILogService logService, ToolItem? groupToEdit = null)
{
_dataService = dataService;
_logService = logService;
_editingGroup = groupToEdit;
AvailableIconsView = new ListCollectionView(IconProvider.AvailableIcons);
AvailableIconsView.GroupDescriptions.Add(new PropertyGroupDescription("Category"));
foreach (var cat in _dataService.Config.Categories)
Categories.Add(cat);
// 加载所有工具(排除自身及祖先组合,防止循环引用)
var excludeIds = GetAncestorIds();
var selectedIds = _editingGroup?.SubToolIds ?? new List();
foreach (var tool in _dataService.Config.Tools.Where(t => !excludeIds.Contains(t.Id)))
{
AvailableTools.Add(new SelectableTool
{
Tool = tool,
IsSelected = selectedIds.Contains(tool.Id)
});
}
if (groupToEdit != null)
{
WindowTitle = "编辑组合";
Name = groupToEdit.Name;
HotKey = groupToEdit.HotKey;
SelectedCategory = Categories.FirstOrDefault(c => c.Id == groupToEdit.CategoryId);
AutoRunOnStart = groupToEdit.AutoRunOnStart;
if (!string.IsNullOrEmpty(groupToEdit.IconCode))
{
SelectedIcon = IconProvider.AvailableIcons.FirstOrDefault(i => i.Icon.ToString() == groupToEdit.IconCode);
}
}
}
// ──────── 命令 ────────
[RelayCommand]
private void Save()
{
try
{
if (string.IsNullOrWhiteSpace(Name))
{
_logService.Warning("组合名称不能为空");
return;
}
var selectedIds = AvailableTools
.Where(t => t.IsSelected)
.Select(t => t.Tool.Id)
.ToList();
if (_editingGroup != null)
{
_editingGroup.Name = Name.Trim();
_editingGroup.IconCode = SelectedIcon?.Icon.ToString() ?? string.Empty;
_editingGroup.HotKey = HotKey.Trim();
_editingGroup.CategoryId = SelectedCategory?.Id ?? string.Empty;
_editingGroup.SubToolIds = selectedIds;
_editingGroup.IsValid = true;
_editingGroup.AutoRunOnStart = AutoRunOnStart;
_logService.Info($"已更新组合: {Name.Trim()}(包含 {selectedIds.Count} 个工具)");
}
else
{
_dataService.Config.Tools.Add(new ToolItem
{
Name = Name.Trim(),
IconCode = SelectedIcon?.Icon.ToString() ?? string.Empty,
HotKey = HotKey.Trim(),
CategoryId = SelectedCategory?.Id ?? string.Empty,
IsGroup = true,
SubToolIds = selectedIds,
IsValid = true,
AutoRunOnStart = AutoRunOnStart
});
_logService.Info($"已添加组合: {Name.Trim()}(包含 {selectedIds.Count} 个工具)");
}
_dataService.Save();
Saved = true;
CloseAction?.Invoke(true);
}
catch (Exception ex)
{
_logService.Error($"保存组合失败: {ex.Message}");
}
}
[RelayCommand]
private void Cancel()
{
CloseAction?.Invoke(false);
}
///
/// 获取需要排除的工具 ID 集合(自身 + 所有祖先组合),防止循环引用
///
private System.Collections.Generic.HashSet GetAncestorIds()
{
var ancestors = new System.Collections.Generic.HashSet();
if (_editingGroup != null)
{
ancestors.Add(_editingGroup.Id);
CollectAncestors(_editingGroup.Id, ancestors);
}
return ancestors;
}
private void CollectAncestors(string groupId, System.Collections.Generic.HashSet ancestors)
{
foreach (var tool in _dataService.Config.Tools.Where(t => t.IsGroup))
{
if (tool.SubToolIds.Contains(groupId) && ancestors.Add(tool.Id))
{
CollectAncestors(tool.Id, ancestors);
}
}
}
}
///
/// 可勾选的工具项(用于 CheckBox 列表绑定)
///
public partial class SelectableTool : ObservableObject
{
public ToolItem Tool { get; set; } = null!;
[ObservableProperty]
private bool _isSelected;
}