import { defineStore, storeToRefs } from 'pinia' import { computed } from 'vue' import { useCatalogStore } from './catalog' import { useTaskRuntimeStore } from './taskRuntime' export const useSoftwareStore = defineStore('software', () => { const catalog = useCatalogStore() const taskRuntime = useTaskRuntimeStore() const { essentials, essentialsVersion, updates, allSoftware, settings, loading, isInitialized, initStatus } = storeToRefs(catalog) const { activeTasks, selectedEssentialIds, selectedUpdateIds, logs, postInstallPrefs } = storeToRefs(taskRuntime) const mergedEssentials = computed(() => essentials.value.map(item => { const task = activeTasks.value[item.id] const enablePostInstall = postInstallPrefs.value[item.id] !== false const baseStatus = item.action_label === '已安装' ? 'installed' : 'idle' return { ...item, version: item.version ?? undefined, recommended_version: item.recommended_version ?? undefined, available_version: item.available_version ?? undefined, icon_url: item.icon_url ?? undefined, manifest_url: item.manifest_url ?? undefined, post_install_url: item.post_install_url ?? undefined, actionLabel: item.action_label, targetVersion: item.target_version ?? undefined, status: task ? task.status : baseStatus, progress: task ? task.progress : 0, enablePostInstall } })) const sortedUpdates = computed(() => [...updates.value].map(item => { const task = activeTasks.value[item.id] const enablePostInstall = postInstallPrefs.value[item.id] !== false return { ...item, version: item.version ?? undefined, recommended_version: item.recommended_version ?? undefined, available_version: item.available_version ?? undefined, icon_url: item.icon_url ?? undefined, manifest_url: item.manifest_url ?? undefined, post_install_url: item.post_install_url ?? undefined, actionLabel: item.action_label, targetVersion: item.target_version ?? undefined, status: task ? task.status : 'idle', progress: task ? task.progress : 0, enablePostInstall } }).sort((a, b) => a.name.localeCompare(b.name, 'zh-CN', { sensitivity: 'accent' }))) const isBusy = computed(() => loading.value || taskRuntime.isTaskBusy) const toggleSelection = (id: string, type: 'essential' | 'update') => { if (isBusy.value) return taskRuntime.toggleSelection(id, type) } const selectAll = (type: 'essential' | 'update') => { if (type === 'essential') { const selectable = mergedEssentials.value.filter(item => item.actionLabel !== '已安装') taskRuntime.setSelection('essential', selectable.map(item => item.id)) } else { taskRuntime.setSelection('update', updates.value.map(item => item.id)) } } const deselectAll = (type: 'essential' | 'update') => { taskRuntime.setSelection(type, []) } const invertSelection = (type: 'essential' | 'update') => { if (type === 'essential') { const selectable = mergedEssentials.value .filter(item => item.actionLabel !== '已安装') .map(item => item.id) taskRuntime.setSelection( 'essential', selectable.filter(id => !selectedEssentialIds.value.includes(id)) ) } else { const selectable = updates.value.map(item => item.id) taskRuntime.setSelection( 'update', selectable.filter(id => !selectedUpdateIds.value.includes(id)) ) } } const fetchUpdates = async () => { if (isBusy.value) return await catalog.fetchUpdates() if (selectedUpdateIds.value.length === 0) selectAll('update') } const syncDataIfNeeded = async (force = false) => { if (isBusy.value) return await catalog.syncDataIfNeeded(force) if (selectedEssentialIds.value.length === 0) selectAll('essential') } const fetchAllData = async () => { await catalog.fetchAllData() if (selectedEssentialIds.value.length === 0) selectAll('essential') } return { essentials, essentialsVersion, updates, allSoftware, selectedEssentialIds, selectedUpdateIds, logs, settings, activeTasks, loading, isInitialized, initStatus, mergedEssentials, sortedUpdates, isBusy, initializeApp: catalog.initializeApp, saveSettings: catalog.saveSettings, syncEssentials: catalog.syncEssentials, fetchEssentials: catalog.fetchEssentials, fetchUpdates, syncDataIfNeeded, fetchAllData, install: taskRuntime.install, togglePostInstallPref: taskRuntime.togglePostInstallPref, startBatch: taskRuntime.startBatch, scheduleDataRefresh: taskRuntime.scheduleDataRefresh, findSoftware: catalog.findSoftware, initListener: taskRuntime.initListener, toggleSelection, selectAll, deselectAll, invertSelection } })