/**
 * Tabela 33 — Número de Strouhal (St) para diversas seções
 * (NBR 6123:2023, sec. 10.3).
 *
 * Fonte: NBR 6123:2023, p. 79 (Tabela 33).
 * Última auditoria: 2026-07-08 — auditado e condizente com a norma.
 */

import { linearInterp1D } from '../log-interp';

export type SectionShape =
  | 'circle'
  | 'rectangle-b-a-1-3'
  | 'rectangle-b-a-1-2'
  | 'rectangle-b-a-1-1'
  | 'rectangle-b-a-1-0-5'
  | 'rectangle-b-a-2-0';

interface StEntry {
  shape: SectionShape;
  ratio: number;
  st: number;
}

/** St por forma e relação b/a */
const ST_TABLE: readonly StEntry[] = [
  { shape: 'circle', ratio: 0, st: 0.20 },
  { shape: 'rectangle-b-a-1-3', ratio: 1 / 3, st: 0.16 },
  { shape: 'rectangle-b-a-1-3', ratio: 1 / 2, st: 0.12 },
  { shape: 'rectangle-b-a-1-3', ratio: 1, st: 0.11 },
  { shape: 'rectangle-b-a-1-3', ratio: 2, st: 0.10 },
  { shape: 'rectangle-b-a-1-2', ratio: 1, st: 0.12 },
  { shape: 'rectangle-b-a-1-2', ratio: 1.5, st: 0.10 },
  { shape: 'rectangle-b-a-1-2', ratio: 2, st: 0.08 },
  { shape: 'rectangle-b-a-1-1', ratio: 1, st: 0.12 },
  { shape: 'rectangle-b-a-1-1', ratio: 1.5, st: 0.08 },
  { shape: 'rectangle-b-a-1-1', ratio: 2, st: 0.08 },
  { shape: 'rectangle-b-a-1-1', ratio: 4, st: 0.08 },
  { shape: 'rectangle-b-a-1-0-5', ratio: 1, st: 0.12 },
  { shape: 'rectangle-b-a-1-0-5', ratio: 1.5, st: 0.06 },
  { shape: 'rectangle-b-a-1-0-5', ratio: 2, st: 0.05 },
  { shape: 'rectangle-b-a-2-0', ratio: 1, st: 0.10 },
  { shape: 'rectangle-b-a-2-0', ratio: 1.5, st: 0.08 },
  { shape: 'rectangle-b-a-2-0', ratio: 2, st: 0.08 },
  { shape: 'rectangle-b-a-2-0', ratio: 4, st: 0.08 },
];

export function getStrouhalNumber(shape: SectionShape, ratio: number): number {
  const entries = ST_TABLE.filter((e) => e.shape === shape);
  if (entries.length === 0) return 0.2;
  const xs = entries.map((e) => e.ratio);
  const ys = entries.map((e) => e.st);
  return Number(linearInterp1D(xs, ys, ratio).toFixed(3));
}

/** Velocidade crítica do vento: Vcr = fn · L / St */
export function criticalVelocity(fn: number, L: number, st: number): number {
  return Number((fn * L / Math.max(st, 0.001)).toFixed(2));
}

/** Verificação de dispensa: Vcr > 1,25 · V0 · S1 · S2(z, t=600s) · S3 (sec. 10.2) */
export function vortexDispenseCheck(vcr: number, v0: number, s1: number, s2: number, s3: number): boolean {
  return vcr > 1.25 * v0 * s1 * s2 * s3;
}

/** Número de Scruton: Sc = ξ · m_eq / (ρ · d) */
export function scrutonNumber(xi: number, mEq: number, rho: number, d: number): number {
  return Number((xi * mEq / (rho * d)).toFixed(2));
}

/** Susceptibilidade a vórtices: Sc < 20 indica susceptibilidade (sec. 10.5) */
export function isVortexSusceptible(scruton: number): boolean {
  return scruton < 20;
}

/** Tabela 34 — C e K_a0 em função de Re (para sec. 10.4) */
export interface VortexCParams {
  re: number;
  C: number;
  K_a0: number;
}

export const TABLE_34: readonly VortexCParams[] = [
  { re: 0, C: 0.0554, K_a0: 0.0281 },
  { re: 2.5e5, C: 0.0554, K_a0: 0.0281 },
  { re: 5e5, C: 0.1840, K_a0: 0.0807 },
  { re: 1e6, C: 0.0208, K_a0: 0.0008 },
  { re: 2e6, C: 0.0208, K_a0: 0.0008 },
  { re: 5e6, C: 0.0208, K_a0: 0.0008 },
];

/** Parâmetros C e K_a0 por interpolação em Re */
export function getVortexParams(re: number): { C: number; K_a0: number } {
  const xs = TABLE_34.map((e) => e.re);
  const cVals = TABLE_34.map((e) => e.C);
  const kVals = TABLE_34.map((e) => e.K_a0);
  const allKZero = kVals.every((v) => v === 0);
  return {
    C: Number(linearInterp1D(xs, cVals, re).toFixed(4)),
    K_a0: Number(linearInterp1D(xs, allKZero ? [0] : kVals, re).toFixed(4)),
  };
}