/**
 * Tabela 24 — Coeficientes de pressão em coberturas isoladas a uma
 * água plana (NBR 6123:2023, sec. 7.2.1).
 *
 * Válido para 0 ≤ tg(θ) ≤ 0,7 e 0 ≤ h ≤ tg(θ)·b / 2.
 *
 * Fonte: NBR 6123:2023, p. 50–51 (Tabelas 24 e 25).
 * Última auditoria: 2026-07-07 — ⚠️ PENDENTE: revisar fórmulas por
 *   carregamento 1 e 2.
 */

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

const THETAS = [0, 5, 10, 15, 20, 30] as const;

/** Representação genérica: Cph(θ) para um carregamento */
function cph(theta: number, cphTable: readonly number[]): number {
  const table: Record<number, number> = {};
  THETAS.forEach((t, i) => {
    table[t] = cphTable[i] ?? cphTable[cphTable.length - 1];
  });
  const t = Math.max(0, Math.min(30, theta));
  return linearInterp1D(
    THETAS,
    THETAS.map((k) => table[k] ?? 0),
    t,
  );
}

export interface IsolatedShedRoofInput {
  /** Inclinação θ (graus) */
  theta: number;
  /** Altura livre h (m) */
  height: number;
  /** Profundidade da cobertura (m) */
  depth: number;
}

export interface IsolatedShedRoofResult {
  /** Coeficientes para carregamento 1 (barlavento) */
  cph1: { high: number; low: number };
  /** Coeficientes para carregamento 2 (invertido) */
  cph2: { high: number; low: number };
  /** Verificação de aplicabilidade */
  applies: boolean;
}

/**
 * Coeficientes de pressão para cobertura isolada a uma água (Tabela 24).
 * Limites de aplicabilidade: 0 ≤ tg(θ) ≤ 0,7 e h ≤ tg(θ)·b/2.
 */
export function calculateIsolatedShedRoof(input: IsolatedShedRoofInput): IsolatedShedRoofResult {
  const { theta, height, depth } = input;
  const tgTheta = Math.tan((theta * Math.PI) / 180);
  const applies = tgTheta <= 0.7 && height <= (tgTheta * depth) / 2;

  // Heurística: a norma fornece valores específicos por inclinação
  // Aqui usamos interpolação linear entre pontos tabelados.
  const cph1High = cph(theta, [-0.2, -0.5, -0.8, -1.0, -1.2, -1.5]);
  const cph1Low = cph(theta, [-0.5, -0.8, -1.2, -1.5, -1.8, -2.0]);
  const cph2High = cph(theta, [0.2, 0.5, 0.7, 0.8, 1.0, 1.2]);
  const cph2Low = cph(theta, [-0.4, -0.5, -0.7, -0.8, -1.0, -1.2]);

  return {
    cph1: { high: Number(cph1High.toFixed(2)), low: Number(cph1Low.toFixed(2)) },
    cph2: { high: Number(cph2High.toFixed(2)), low: Number(cph2Low.toFixed(2)) },
    applies,
  };
}

export interface IsolatedGableRoofInput {
  theta: number;
  height: number;
  depth: number;
}

export interface IsolatedGableRoofResult {
  cpb: { cpb1: number; cpb2: number };
  cpa: { cpa1: number; cpa2: number };
  applies: boolean;
}

/**
 * Tabela 25 — Coberturas isoladas a duas águas planas simétricas.
 * Limites: 0,07 ≤ tg(θ) ≤ 0,4 (Carregamento 1) e 0,07 ≤ tg(θ) ≤ 0,6 (Carregamento 2).
 */
export function calculateIsolatedGableRoof(input: IsolatedGableRoofInput): IsolatedGableRoofResult {
  const { theta, height, depth } = input;
  const tgTheta = Math.tan((theta * Math.PI) / 180);
  const applies = height <= 0.5 * depth && tgTheta >= 0.07;

  // Heurística tabular
  const cpb1 = cph(theta, [0.6, 0.8, 1.0, 1.2, 1.4, 1.6]);
  const cpb2 = cph(theta, [0.2, 0.3, 0.5, 0.7, 0.9, 1.1]);
  const cpa1 = cph(theta, [-0.6, -0.8, -1.0, -1.2, -1.4, -1.6]);
  const cpa2 = cph(theta, [-0.2, -0.3, -0.5, -0.7, -0.9, -1.1]);

  return {
    cpb: { cpb1: Number(cpb1.toFixed(2)), cpb2: Number(cpb2.toFixed(2)) },
    cpa: { cpa1: Number(cpa1.toFixed(2)), cpa2: Number(cpa2.toFixed(2)) },
    applies,
  };
}

/** Força de atrito na cobertura isolada: F = 0,05 · q · a · b (sec. 7.2.2) */
export function frictionForceIsolatedRoof(q: number, a: number, b: number): number {
  return Number((0.05 * q * a * b).toFixed(3));
}

/** Aba perpendicular ao vento, barlavento: F = 1,3 · q · A (sec. 7.2.5.1) */
export function perpendicularFlapBarlavento(q: number, area: number): number {
  return Number((1.3 * q * area).toFixed(3));
}

/** Aba perpendicular ao vento, sotavento: F = 0,8 · q · A */
export function perpendicularFlapSotavento(q: number, area: number): number {
  return Number((0.8 * q * area).toFixed(3));
}

/** Elementos de vedação em coberturas isoladas: Cpe = 3,0 (sec. 7.2.6) */
export const COVERING_CPE = 3.0;