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<GlobalWindState>((set, get) => {
  const recalc = (state: GlobalWindState): Partial<GlobalWindState> => {
    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.
    },
  };
});