/**
 * Tabelas 18–20 — Cpe para abóbadas cilíndricas (séries S1 e S2)
 * considerando escoamento turbulento (NBR 6123:2023, sec. 6.2.3).
 *
 * Fonte: NBR 6123:2023, p. 37–39 (Tabelas 18, 19, 20).
 * Última auditoria: 2026-07-07 — valores oficiais do PDF confirmados.
 *
 * Séries:
 *  - S1: menor dimensão em planta b = 20 m (I1=11%, L1/b=1,5 — Cat. I-II)
 *  - S2: menor dimensão em planta b = 50 m (I1=15,5%, L1/b=1,6 — Cat. III-IV)
 *
 * Tabela 18: vento ⊥ geratriz, 6 zonas (arco barlavento→sotavento)
 *  Parâmetros: a/b, f/b, h/b (ou hb/b para S2)
 * Tabela 19: vento ∥ geratriz, 4 partes (A, B, C, D)
 * Tabela 20: vento oblíquo, faixas E, F, G, H
 */

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

const ZONES_18 = [1, 2, 3, 4, 5, 6] as const;
const FL_KEYS = [0.05, 0.1, 0.2, 0.3, 0.4] as const;

/**
 * Tabela 18 simplificada — interpolação por f/b.
 * Chaves: f/b (0.05=1/20, 0.1=1/10, 0.2=1/5, 0.3, 0.4)
 * Valores interpolados das linhas oficiais da Tabela 18.
 */
const T18_INTERP: Record<'S1' | 'S2', Record<number, Record<number, number>>> = {
  S1: {
    0.05: { 1: -0.3, 2: -0.7, 3: -0.8, 4: -0.6, 5: -0.4, 6: -0.4 },
    0.1:  { 1: -1.0, 2: -0.6, 3: -0.6, 4: -0.6, 5: -0.4, 6: -0.3 },
    0.2:  { 1: -0.9, 2: -0.9, 3: -0.9, 4: -0.7, 5: -0.5, 6: -0.5 },
    0.3:  { 1: -1.0, 2: -0.8, 3: -0.7, 4: -0.7, 5: -0.5, 6: -0.4 },
    0.4:  { 1: -1.0, 2: -0.8, 3: -0.7, 4: -0.7, 5: -0.5, 6: -0.4 },
  },
  S2: {
    0.05: { 1: -0.3, 2: -0.7, 3: -0.8, 4: -0.6, 5: -0.4, 6: -0.4 },
    0.1:  { 1: 0.4, 2: -0.6, 3: -1.2, 4: -0.9, 5: -0.7, 6: -0.7 },
    0.2:  { 1: 0.4, 2: -0.6, 3: -1.2, 4: -0.9, 5: -0.7, 6: -0.7 },
    0.3:  { 1: 0.4, 2: -0.6, 3: -1.2, 4: -0.9, 5: -0.7, 6: -0.7 },
    0.4:  { 1: 0.4, 2: -0.6, 3: -1.2, 4: -0.9, 5: -0.7, 6: -0.7 },
  },
};

/**
 * Tabela 19: Cpe para vento paralelo à geratriz.
 * 4 partes: A, B, C, D.
 * Fonte: NBR 6123:2023, p. 38.
 */
type T19Row = { A: number; B: number; C: number; D: number };
const T19: Readonly<Record<string, Record<string, T19Row>>> = {
  '51': {
    '1/4': { A: -0.8, B: -0.4, C: -0.3, D: -0.2 },
    '1/2': { A: -0.8, B: -0.6, C: -0.3, D: -0.2 },
    '1/4b': { A: -0.8, B: -0.4, C: -0.3, D: -0.2 },
    '1/2b': { A: -0.9, B: -0.6, C: -0.3, D: -0.2 },
  },
  '52': {
    '1/9': { A: -0.8, B: -0.4, C: -0.2, D: -0.2 },
  },
};

/**
 * Tabela 20: Cpe para vento oblíquo.
 * Faixas E, F, G, H.
 * Fonte: NBR 6123:2023, p. 39.
 */
const T20: Readonly<Record<string, Record<string, number>>> = {
  '51': {
    'E_1_4': -1.6,
    'E_1_2': -2.4,
    'F_1_2': -1.2,
    'E_1_4b': -1.4,
    'F_1_4b': -1.4,
    'E_1_2b': -1.6,
    'F_1_2b': -1.8,
  },
  '52': {
    'E': -1.5,
    'G': -1.8,
    'H': -1.5,
  },
};

function lookupT18(series: 'S1' | 'S2', fl: number, zone: number): number {
  const grid = {
    xs: ZONES_18,
    ys: FL_KEYS,
    values: FL_KEYS.map((f) => ZONES_18.map((z) => T18_INTERP[series][f][z])),
  };
  const fClamped = Math.max(FL_KEYS[0], Math.min(FL_KEYS[FL_KEYS.length - 1], fl));
  const zoneClamped = Math.max(1, Math.min(6, zone));
  return bilinearInterp(grid, zoneClamped, fClamped);
}

export function getVaultTurbulentCpePerpendicular(fl: number, series: 'S1' | 'S2' = 'S1') {
  return {
    zone1: Number(lookupT18(series, fl, 1).toFixed(2)),
    zone2: Number(lookupT18(series, fl, 2).toFixed(2)),
    zone3: Number(lookupT18(series, fl, 3).toFixed(2)),
    zone4: Number(lookupT18(series, fl, 4).toFixed(2)),
    zone5: Number(lookupT18(series, fl, 5).toFixed(2)),
    zone6: Number(lookupT18(series, fl, 6).toFixed(2)),
  };
}

export function getVaultTurbulentCpeParallel(series: 51 | 52) {
  const key = String(series) as '51' | '52';
  const data = T19[key];
  if (!data) return { A: 0, B: 0, C: 0, D: 0 };
  const row = data['1/4'] ?? data['1/9'] ?? Object.values(data)[0];
  return { A: row.A, B: row.B, C: row.C, D: row.D };
}

export function getVaultTurbulentCpeOblique(series: 51 | 52) {
  const key = String(series) as '51' | '52';
  const data = T20[key];
  if (!data) return { E: 0, F: 0 };
  return {
    E: data['E'] ?? data['E_1_4'] ?? -1.6,
    F: data['F'] ?? data['F_1_2'] ?? -1.2,
  };
}
