import { create } from 'zustand'; import { calculateGlobalWindData, type TerrainCategory, type StructureClass, } from '../lib/wind-kernel'; import { computeCpiSimplified, clampCpi, type PermeabilityCase } from '../lib/internal-pressure'; export interface GlobalWindState { // Entradas (Inputs) v0: number; s1: number; s3: number; s3Group: 1 | 2 | 3 | 4 | 5; terrainCategory: TerrainCategory; largestDimension: number; heightZ: number; // Saídas (Calculados) structureClass: StructureClass; s2: number; vk: number; q: number; // Pressão interna e Vento windAngle: 0 | 90; permeabilityCase: PermeabilityCase; cpiRatio: number; cpi: number; // Ações updateCalculations: () => void; setV0: (val: number) => void; setS1: (val: number) => void; setS3: (val: number) => void; setS3Group: (group: 1 | 2 | 3 | 4 | 5) => void; setTerrainCategory: (cat: TerrainCategory) => void; setDimensions: (largestDim: number, z: number) => void; setWindAngle: (angle: 0 | 90) => void; setPermeabilityCase: (c: PermeabilityCase) => void; setCpiRatio: (r: number) => void; setCpiManual: (c: number) => void; } function calcCpi(permeabilityCase: PermeabilityCase, ratio: number, windAngle: 0 | 90): number { if (permeabilityCase === 'airtight') return 0; // Just as an example, computeCpiSimplified handles it const value = computeCpiSimplified({ case: permeabilityCase, ratio, windAngle, }); return clampCpi(value); } export const useWindStore = create((set, get) => { const recalc = (state: GlobalWindState): Partial => { const calc = calculateGlobalWindData( state.v0, state.s1, state.s3, state.terrainCategory, state.largestDimension, state.heightZ, ); return { structureClass: calc.structClass, s2: calc.s2, vk: calc.vk, q: calc.q, cpi: calcCpi(state.permeabilityCase, state.cpiRatio, state.windAngle), }; }; return { v0: 40, s1: 1.0, s3: 1.0, s3Group: 3, terrainCategory: 'II', largestDimension: 30, heightZ: 10, structureClass: 'B', s2: 1.06, vk: 42.4, q: 1.1024, windAngle: 0, permeabilityCase: 'four-equally-permeable', cpiRatio: 1.0, cpi: calcCpi('four-equally-permeable', 1.0, 0), updateCalculations: () => set((state) => recalc(state)), setV0: (val) => { set({ v0: val }); get().updateCalculations(); }, setS1: (val) => { set({ s1: val }); get().updateCalculations(); }, setS3: (val) => { set({ s3: val }); get().updateCalculations(); }, setS3Group: (group) => { const newS3 = group === 1 ? 1.10 : group === 2 ? 1.08 : group === 3 ? 1.0 : group === 4 ? 0.95 : 0.83; set({ s3Group: group, s3: newS3 }); get().updateCalculations(); }, setTerrainCategory: (cat) => { set({ terrainCategory: cat }); get().updateCalculations(); }, setDimensions: (largestDim, z) => { set({ largestDimension: largestDim, heightZ: z }); get().updateCalculations(); }, setWindAngle: (angle) => { set({ windAngle: angle }); get().updateCalculations(); }, setPermeabilityCase: (c) => { set({ permeabilityCase: c }); get().updateCalculations(); }, setCpiRatio: (r) => { set({ cpiRatio: r }); get().updateCalculations(); }, setCpiManual: (c) => { set({ cpi: clampCpi(c) }); // Not calling updateCalculations to avoid overriding it immediately if permeabilityCase applies, // but if the user overrides manually we might want to switch permeabilityCase to 'custom' ? // Wait, there is no 'custom'. We just set the value. }, }; });