/**
 * Tabela 32 — Expoente p e parâmetro bₘ para resposta dinâmica
 * na direção do vento (NBR 6123:2023, sec. 9.3.2).
 *
 * Fonte: NBR 6123:2023, p. 63 (Tabela 32).
 * Última auditoria: 2026-07-07 — valores conferidos com PDF oficial.
 *
 * Valores oficiais (categoria: p, bₘ):
 *   I:   0,095 / 1,23
 *   II:  0,15  / 1,00
 *   III: 0,185 / 0,86
 *   IV:  0,23  / 0,71
 *   V:   0,31  / 0,50
 */

import type { TerrainCategory } from '../wind-kernel';

export const TABLE_32: Readonly<Record<TerrainCategory, { p: number; bm: number }>> = {
  I: { p: 0.095, bm: 1.23 },
  II: { p: 0.15, bm: 1.00 },
  III: { p: 0.185, bm: 0.86 },
  IV: { p: 0.23, bm: 0.71 },
  V: { p: 0.31, bm: 0.50 },
};

export function getDynamicTable32(category: TerrainCategory): { p: number; bm: number } {
  return TABLE_32[category];
}

/**
 * Velocidade de projeto Vp para análise dinâmica:
 *   Vp = 0,69 · S₃ · Vo
 *
 * (média sobre 10 min, a 10 m, Categoria II)
 */
export function calculateVp(v0: number, s3: number): number {
  return Number((0.69 * s3 * v0).toFixed(2));
}

/**
 * Fator dinâmico ζ conforme Figura 20-24 (interpolação log em Vp/fL).
 * Como os gráficos são complexos, esta versão fornece valores típicos.
 */
export interface DynamicFactorInput {
  category: TerrainCategory;
  /** Velocidade de projeto Vp */
  vp: number;
  /** Frequência fundamental f (Hz) */
  freq: number;
  /** Altura h (m) */
  height: number;
  /** Taxa de amortecimento ξ (decimal, ex. 0.02 = 2%) */
  xi: number;
}

/** Versão simplificada: ζ ≈ 1 + 2·γ·Iₜ onde Iₜ ≈ bₘ(z/h)^p / ln(z/z₀) */
export function dynamicFactor(input: DynamicFactorInput): number {
  const { height, xi, category } = input;
  const { p, bm } = TABLE_32[category];

  // Intensidade de turbulência aproximada para Categoria II
  const It = bm * Math.pow(10 / height, -p) / Math.log(height / 0.07);
  const gamma = 1.0; // simplificado para modo fundamental

  // ζ ≈ 1 + 2γIt/(π·ξ) para amortecimento estrutural
  const xiDecimal = xi / 100;
  const zeta = 1 + (2 * gamma * It) / (Math.PI * Math.max(xiDecimal, 0.001));
  return Number(zeta.toFixed(3));
}

/** Pressão dinâmica com efeito dinâmico: q(z, t) = q₀ · b(z/h)ᵖ · [1 + 2γItζ] */
export function dynamicPressure(input: DynamicFactorInput, q0: number, z: number): number {
  const { height, category } = input;
  const { p, bm } = TABLE_32[category];
  const zeta = dynamicFactor(input);
  const profile = Math.pow(z / height, p);
  return Number((q0 * bm * profile * zeta).toFixed(4));
}