import { defineStore } from "pinia"; export const useCoopBuilderStore = defineStore("coop", { state: () => ({ operatingMode: "min" as "min" | "target", // Currency preference currency: "EUR" as string, // Flag to track if data was intentionally cleared _wasCleared: false, members: [] as Array<{ id: string; name: string; hoursPerMonth?: number; minMonthlyNeeds: number; monthlyPayPlanned: number; }>, streams: [] as Array<{ id: string; label: string; monthly: number; annual?: number; amountType?: 'monthly' | 'annual'; category?: string; certainty?: string; }>, milestones: [] as Array<{ id: string; label: string; date: string; }>, // Scenario and stress test state scenario: "current" as | "current" | "start-production" | "custom", stress: { revenueDelay: 0, costShockPct: 0, grantLost: false, }, // Policy settings policy: { relationship: "equal-pay" as "equal-pay" | "needs-weighted" | "hours-weighted", }, equalHourlyWage: 50, payrollOncostPct: 25, savingsTargetMonths: 6, minCashCushion: 10000, // Cash reserves currentCash: 50000, currentSavings: 15000, // Overhead costs overheadCosts: [] as Array<{ id?: string; name: string; amount: number; annualAmount?: number; amountType?: 'monthly' | 'annual'; category?: string; }>, }), getters: { totalRevenue: (state) => { return state.streams.reduce((sum, s) => sum + (s.monthly || 0), 0); }, totalOverhead: (state) => { return state.overheadCosts.reduce((sum, c) => sum + (c.amount || 0), 0); }, totalLiquid: (state) => { return state.currentCash + state.currentSavings; }, }, actions: { // Member actions upsertMember(m: any) { const i = this.members.findIndex((x) => x.id === m.id); // Ensure all keys exist (prevents undefined stripping) const withDefaults = { id: m.id || Date.now().toString(), name: m.name || m.displayName || "", role: m.role ?? "", hoursPerMonth: m.hoursPerMonth ?? 0, minMonthlyNeeds: m.minMonthlyNeeds ?? 0, targetMonthlyPay: m.targetMonthlyPay ?? 0, externalMonthlyIncome: m.externalMonthlyIncome ?? 0, monthlyPayPlanned: m.monthlyPayPlanned ?? 0, }; if (i === -1) { this.members.push(withDefaults); } else { this.members[i] = withDefaults; } }, removeMember(id: string) { this.members = this.members.filter((m) => m.id !== id); }, // Stream actions upsertStream(s: any) { const i = this.streams.findIndex((x) => x.id === s.id); // Calculate monthly value based on amount type let monthlyValue = s.monthly || s.targetMonthlyAmount || 0; if (s.amountType === 'annual' && s.annual) { monthlyValue = Math.round(s.annual / 12); } const withDefaults = { id: s.id || Date.now().toString(), label: s.label || s.name || "", monthly: monthlyValue, annual: s.annual || s.targetAnnualAmount || monthlyValue * 12, amountType: s.amountType || 'monthly', category: s.category ?? "", certainty: s.certainty ?? "Probable", }; if (i === -1) { this.streams.push(withDefaults); } else { this.streams[i] = withDefaults; } }, removeStream(id: string) { this.streams = this.streams.filter((s) => s.id !== id); }, // Milestone actions addMilestone(label: string, date: string) { this.milestones.push({ id: Date.now().toString(), label, date, }); }, removeMilestone(id: string) { this.milestones = this.milestones.filter((m) => m.id !== id); }, // Operating mode setOperatingMode(mode: "min" | "target") { this.operatingMode = mode; }, // Scenario setScenario( scenario: "current" | "start-production" | "custom" ) { this.scenario = scenario; }, // Stress test updateStress(updates: Partial) { this.stress = { ...this.stress, ...updates }; }, // Policy updates setPolicy(relationship: "equal-pay" | "needs-weighted" | "hours-weighted") { this.policy.relationship = relationship; }, setEqualWage(wage: number) { this.equalHourlyWage = wage; }, setOncostPct(pct: number) { this.payrollOncostPct = pct; }, setCurrency(currency: string) { this.currency = currency; }, // Overhead costs addOverheadCost(cost: any) { // Calculate monthly value based on amount type let monthlyValue = cost.amount || 0; if (cost.amountType === 'annual' && cost.annualAmount) { monthlyValue = Math.round(cost.annualAmount / 12); } const withDefaults = { id: cost.id || Date.now().toString(), name: cost.name || "", amount: monthlyValue, annualAmount: cost.annualAmount || monthlyValue * 12, amountType: cost.amountType || 'monthly', category: cost.category ?? "", }; this.overheadCosts.push(withDefaults); }, upsertOverheadCost(cost: any) { const i = this.overheadCosts.findIndex((c) => c.id === cost.id); // Calculate monthly value based on amount type let monthlyValue = cost.amount || 0; if (cost.amountType === 'annual' && cost.annualAmount) { monthlyValue = Math.round(cost.annualAmount / 12); } const withDefaults = { id: cost.id || Date.now().toString(), name: cost.name || "", amount: monthlyValue, annualAmount: cost.annualAmount || monthlyValue * 12, amountType: cost.amountType || 'monthly', category: cost.category ?? "", }; if (i === -1) { this.overheadCosts.push(withDefaults); } else { this.overheadCosts[i] = withDefaults; } }, removeOverheadCost(id: string) { this.overheadCosts = this.overheadCosts.filter((c) => c.id !== id); }, // Initialize with default data if empty - DISABLED // NO automatic initialization - stores should start empty initializeDefaults() { // DISABLED: No automatic data loading // User must explicitly choose to load demo data return; }, // Clear ALL data - no exceptions clearAll() { // Reset ALL state to initial empty values this._wasCleared = true; this.operatingMode = "min"; this.currency = "EUR"; this.members = []; this.streams = []; this.milestones = []; this.scenario = "current"; this.stress = { revenueDelay: 0, costShockPct: 0, grantLost: false, }; this.policy = { relationship: "equal-pay", }; this.equalHourlyWage = 0; this.payrollOncostPct = 0; this.savingsTargetMonths = 0; this.minCashCushion = 0; this.currentCash = 0; this.currentSavings = 0; this.overheadCosts = []; // Clear ALL localStorage data if (typeof window !== "undefined") { // Save cleared flag first localStorage.setItem("urgent-tools-cleared-flag", "true"); // Remove all known keys const keysToRemove = [ "coop_builder_v1", "urgent-tools-members", "urgent-tools-policies", "urgent-tools-streams", "urgent-tools-budget", "urgent-tools-cash", "urgent-tools-schema-version", ]; keysToRemove.forEach((key) => localStorage.removeItem(key)); // Clear any other urgent-tools or coop keys const allKeys = Object.keys(localStorage); allKeys.forEach((key) => { if (key.startsWith("urgent-tools-") || key.startsWith("coop_")) { if (key !== "urgent-tools-cleared-flag") { localStorage.removeItem(key); } } }); } }, }, persist: { key: "coop_builder_v1", storage: typeof window !== "undefined" ? localStorage : undefined, }, });