using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.DependencyInjection;
using PersonalToolBox.Helpers;
using PersonalToolBox.Models;
using PersonalToolBox.Services;
using PersonalToolBox.Views;
namespace PersonalToolBox.ViewModels;
///
/// 主窗口 ViewModel,管理 UI 状态、数据绑定和用户交互逻辑
///
public partial class MainViewModel : ObservableObject
{
private readonly ILogService _logService;
private readonly IDataService _dataService;
private readonly IProcessExecutionService _processService;
private readonly IServiceProvider _serviceProvider;
private readonly HotKeyManager _hotKeyManager;
///
/// 全部分类的虚拟对象
///
private static readonly Category AllCategory = new() { Id = "", Name = "全部" };
public MainViewModel(
ILogService logService,
IDataService dataService,
IProcessExecutionService processService,
IServiceProvider serviceProvider,
HotKeyManager hotKeyManager)
{
_logService = logService;
_dataService = dataService;
_processService = processService;
_serviceProvider = serviceProvider;
_hotKeyManager = hotKeyManager;
LoadData();
}
// ───────────────────────────── 可观察属性 ─────────────────────────────
[ObservableProperty]
private string _searchText = string.Empty;
[ObservableProperty]
private Category? _selectedCategory;
public ObservableCollection Logs => _logService.Logs;
public ObservableCollection Categories { get; } = new();
public ObservableCollection Tools { get; } = new();
[ObservableProperty]
private ObservableCollection _filteredTools = new();
[ObservableProperty]
private string _currentTheme = "Dark";
// ───────────────────────────── 命令 ─────────────────────────────
[RelayCommand]
private void ClearLogs() => _logService.Clear();
[RelayCommand]
private void ToggleTheme()
{
CurrentTheme = CurrentTheme == "Dark" ? "Light" : "Dark";
ThemeHelper.ApplyTheme(CurrentTheme);
_dataService.Config.Theme = CurrentTheme;
_dataService.Save();
_logService.Info($"已切换到{(CurrentTheme == "Dark" ? "暗黑" : "明亮")}主题");
}
///
/// 打开添加工具弹窗
///
[RelayCommand]
private void AddTool()
{
var vm = _serviceProvider.GetRequiredService();
var window = new ToolEditWindow(vm);
window.ShowDialog();
if (vm.Saved)
{
RefreshData();
}
}
///
/// 打开编辑工具弹窗
///
[RelayCommand]
private void EditTool(ToolItem tool)
{
if (tool == null) return;
// 创建编辑 ViewModel(需要新建实例,DI 容器无法区分参数)
var dataService = _serviceProvider.GetRequiredService();
var logService = _serviceProvider.GetRequiredService();
var editVm = new ToolEditViewModel(dataService, logService, tool);
var window = new ToolEditWindow(editVm);
window.ShowDialog();
if (editVm.Saved)
{
RefreshData();
}
}
///
/// 执行工具(双击卡片或右键菜单)
///
[RelayCommand]
private void ExecuteTool(ToolItem? tool)
{
if (tool == null) return;
_processService.Execute(tool);
}
// ───────────────────────────── 分类管理命令 ─────────────────────────────
///
/// 添加分类
///
[RelayCommand]
private void AddCategory()
{
var vm = _serviceProvider.GetRequiredService();
var window = new CategoryEditWindow(vm);
window.ShowDialog();
if (vm.Saved) RefreshData();
}
///
/// 编辑分类(右键菜单触发)
///
[RelayCommand]
private void EditCategory(Category? category)
{
if (category == null || string.IsNullOrEmpty(category.Id)) return;
var dataService = _serviceProvider.GetRequiredService();
var logService = _serviceProvider.GetRequiredService();
var editVm = new CategoryEditViewModel(dataService, logService, category);
var window = new CategoryEditWindow(editVm);
window.ShowDialog();
if (editVm.Saved) RefreshData();
}
///
/// 删除分类,其下所有工具移入"全部"
///
[RelayCommand]
private void DeleteCategory(Category? category)
{
if (category == null || string.IsNullOrEmpty(category.Id)) return;
if (MessageBox.Show(
$"确定删除分类 \"{category.Name}\" 吗?\n该分类下的所有工具将移入「全部」。",
"确认删除", MessageBoxButton.YesNo, MessageBoxImage.Warning) != MessageBoxResult.Yes)
return;
// 将属于该分类的工具设为"全部"
foreach (var tool in _dataService.Config.Tools.Where(t => t.CategoryId == category.Id))
tool.CategoryId = string.Empty;
// 从配置中移除分类
_dataService.Config.Categories.Remove(category);
_dataService.Save();
_logService.Info($"已删除分类: {category.Name}");
RefreshData();
}
// ───────────────────────────── 数据刷新 ─────────────────────────────
///
/// 从配置重新加载数据并刷新 UI
///
public void RefreshData()
{
var previousCategoryId = SelectedCategory?.Id;
Categories.Clear();
Categories.Add(AllCategory);
foreach (var cat in _dataService.Config.Categories)
Categories.Add(cat);
Tools.Clear();
foreach (var tool in _dataService.Config.Tools)
Tools.Add(tool);
// 恢复之前选中的分类(若仍存在),否则选中"全部"
SelectedCategory = Categories.FirstOrDefault(c => c.Id == previousCategoryId) ?? AllCategory;
ApplyFilter();
// 工具列表变更后重新注册快捷键
RegisterAllHotKeys();
}
// ───────────────────────────── 快捷键 ─────────────────────────────
///
/// 注册所有工具的全局快捷键(由 MainWindow.OnSourceInitialized 及数据变更后调用)
///
public void RegisterAllHotKeys()
{
_hotKeyManager.RegisterAll(Tools);
}
private void LoadData()
{
RefreshData();
SelectedCategory = AllCategory;
CurrentTheme = _dataService.Config.Theme;
ThemeHelper.ApplyTheme(CurrentTheme);
}
// ───────────────────────────── 过滤逻辑 ─────────────────────────────
partial void OnSearchTextChanged(string value) => ApplyFilter();
partial void OnSelectedCategoryChanged(Category? value) => ApplyFilter();
private void ApplyFilter()
{
var filtered = Tools.AsEnumerable();
if (SelectedCategory != null && !string.IsNullOrEmpty(SelectedCategory.Id))
filtered = filtered.Where(t => t.CategoryId == SelectedCategory.Id);
if (!string.IsNullOrWhiteSpace(SearchText))
filtered = filtered.Where(t =>
t.Name.Contains(SearchText, System.StringComparison.OrdinalIgnoreCase));
FilteredTools = new ObservableCollection(filtered);
}
}