import { ref } from "vue"; import { defineStore } from "pinia"; import * as api from "@/api/rulebooks"; import type { Rulebook, RulebookTopic, Rule, RuleHeader } from "@/api/rulebooks"; import { useToastStore } from "@/stores/toast"; export const useRulebooksStore = defineStore("rulebooks", () => { const rulebooks = ref([]); const topicsByRulebook = ref>({}); const rulesByTopic = ref>({}); const currentRule = ref(null); const loading = ref(false); async function fetchRulebooks() { loading.value = true; try { rulebooks.value = await api.listRulebooks(); } catch (e) { useToastStore().show("Failed to load rulebooks", "error"); throw e; } finally { loading.value = false; } } async function fetchTopics(rulebookId: number) { try { topicsByRulebook.value[rulebookId] = await api.listTopics(rulebookId); } catch (e) { useToastStore().show("Failed to load topics", "error"); throw e; } } async function fetchRules(topicId: number) { try { const rules = await api.listRules({ topic_id: topicId }); rulesByTopic.value[topicId] = rules.map((r) => ({ id: r.id, title: r.title, statement: r.statement, topic_id: r.topic_id, })); } catch (e) { useToastStore().show("Failed to load rules", "error"); throw e; } } async function fetchRule(id: number) { currentRule.value = await api.getRule(id); } async function createRulebook(data: { title: string; description?: string }) { const rb = await api.createRulebook(data); rulebooks.value.push(rb); return rb; } async function updateRulebook(id: number, data: Partial>) { const rb = await api.updateRulebook(id, data); const idx = rulebooks.value.findIndex((r) => r.id === id); if (idx >= 0) rulebooks.value[idx] = rb; return rb; } async function deleteRulebook(id: number) { await api.deleteRulebook(id); rulebooks.value = rulebooks.value.filter((r) => r.id !== id); delete topicsByRulebook.value[id]; } async function createTopic(rulebookId: number, data: { title: string; description?: string }) { const topic = await api.createTopic(rulebookId, data); if (!topicsByRulebook.value[rulebookId]) topicsByRulebook.value[rulebookId] = []; topicsByRulebook.value[rulebookId].push(topic); return topic; } async function updateTopic(id: number, data: Partial>) { const topic = await api.updateTopic(id, data); for (const rbId of Object.keys(topicsByRulebook.value)) { const list = topicsByRulebook.value[Number(rbId)]; const idx = list.findIndex((t) => t.id === id); if (idx >= 0) list[idx] = topic; } return topic; } async function deleteTopic(id: number) { await api.deleteTopic(id); for (const rbId of Object.keys(topicsByRulebook.value)) { topicsByRulebook.value[Number(rbId)] = topicsByRulebook.value[Number(rbId)].filter((t) => t.id !== id); } delete rulesByTopic.value[id]; } async function createRule(topicId: number, data: { title: string; statement: string; why?: string; how_to_apply?: string }) { const rule = await api.createRule(topicId, data); if (!rulesByTopic.value[topicId]) rulesByTopic.value[topicId] = []; rulesByTopic.value[topicId].push({ id: rule.id, title: rule.title, statement: rule.statement, topic_id: rule.topic_id }); return rule; } async function updateRule(id: number, data: Partial>) { const rule = await api.updateRule(id, data); if (currentRule.value?.id === id) currentRule.value = rule; for (const tid of Object.keys(rulesByTopic.value)) { const list = rulesByTopic.value[Number(tid)]; const idx = list.findIndex((r) => r.id === id); if (idx >= 0) list[idx] = { id: rule.id, title: rule.title, statement: rule.statement, topic_id: rule.topic_id }; } return rule; } async function deleteRule(id: number) { await api.deleteRule(id); if (currentRule.value?.id === id) currentRule.value = null; for (const tid of Object.keys(rulesByTopic.value)) { rulesByTopic.value[Number(tid)] = rulesByTopic.value[Number(tid)].filter((r) => r.id !== id); } } return { rulebooks, topicsByRulebook, rulesByTopic, currentRule, loading, fetchRulebooks, fetchTopics, fetchRules, fetchRule, createRulebook, updateRulebook, deleteRulebook, createTopic, updateTopic, deleteTopic, createRule, updateRule, deleteRule, }; });