/**
 * Tabelas 15–17 — Coeficientes de pressão externa para coberturas
 * curvas: abóbadas cilíndricas de seção circular (NBR 6123:2023, sec. 6.2.3).
 *
 *  - Tabela 15: vento ⊥ geratriz da cobertura (arco dividido em 6 partes)
 *  - Tabela 16: vento ∥ geratriz da cobertura (4 partes)
 *  - Tabela 17: vento oblíquo à geratriz (pontas de sucção)
 *
 * Modelo com superfície externa rugosa e 0,5 ≤ ℓ/b ≤ 3.
 *
 * Fonte: NBR 6123:2023, p. 36 (Tabelas 15, 16, 17).
 * Última auditoria: 2026-07-07 — ⚠️ PENDENTE: revisar valores por f/b
 *   e zona (1 a 6). PDF página 48.
 */

import { bilinearInterp } from '../bilinear-interp';

/** Razões f/ℓ: 0,5 / 1 / 2 (Tabela 15) */
const FL = [0.5, 1, 2] as const;
/** Zonas 1..6 (arco de barlavento → sotavento) */
const ZONES_15 = [1, 2, 3, 4, 5, 6] as const;

const T15: Record<number, Record<number, number>> = {
  0.5: { 1: 0.4, 2: -0.3, 3: -0.8, 4: -0.7, 5: -0.3, 6: 0.2 },
  1: { 1: -0.4, 2: -0.8, 3: -0.8, 4: -0.8, 5: -0.4, 6: 0.2 },
  2: { 1: -1.4, 2: -1.0, 3: -0.7, 4: -0.3, 5: 0, 6: 0.4 },
};

const T16: Readonly<Record<string, number>> = {
  A: -0.8,
  B: -0.6,
  C: -0.2,
  D: 0.2,
};

const T17: Readonly<Record<string, number>> = {
  DE: -1.8,
  DF: -1.8,
};

function lookupT15(fl: number, zone: number): number {
  const grid = {
    xs: ZONES_15,
    ys: FL,
    values: FL.map((f) => ZONES_15.map((z) => T15[f][z as 1 | 2 | 3 | 4 | 5 | 6])),
  };
  const fClamped = Math.max(0.5, Math.min(2, fl));
  const zClamped = Math.max(1, Math.min(6, zone));
  return bilinearInterp(grid, zClamped, fClamped);
}

export interface VaultCpeWindPerpendicular {
  zone1: number;
  zone2: number;
  zone3: number;
  zone4: number;
  zone5: number;
  zone6: number;
}

/** Tabela 15 — vento ⊥ geratriz */
export function getVaultCpeWindPerpendicularNBR6123(fl: number): VaultCpeWindPerpendicular {
  return {
    zone1: Number(lookupT15(fl, 1).toFixed(2)),
    zone2: Number(lookupT15(fl, 2).toFixed(2)),
    zone3: Number(lookupT15(fl, 3).toFixed(2)),
    zone4: Number(lookupT15(fl, 4).toFixed(2)),
    zone5: Number(lookupT15(fl, 5).toFixed(2)),
    zone6: Number(lookupT15(fl, 6).toFixed(2)),
  };
}

export interface VaultCpeWindParallel {
  A: number;
  B: number;
  C: number;
  D: number;
}

/** Tabela 16 — vento ∥ geratriz */
export function getVaultCpeWindParallelNBR6123(): VaultCpeWindParallel {
  return { A: T16.A, B: T16.B, C: T16.C, D: T16.D };
}

export interface VaultCpeWindOblique {
  DE: number;
  DF: number;
}

/** Tabela 17 — vento oblíquo (pontas de sucção) */
export function getVaultCpeWindObliqueNBR6123(): VaultCpeWindOblique {
  return { DE: T17.DE, DF: T17.DF };
}