/**
 * Coeficientes de força de atrito — NBR 6123:2023, sec. 6.1.5
 *
 * Para edificações correntes de planta retangular, a força de atrito
 * deve ser considerada somente quando l₀/h ou l₀/b > 4.
 *
 * F_f = C_f · q · [A_roof + A_walls_paralelas]
 *
 * C_f = 0,01 (sem nervuras); 0,02 (nervuras arredondadas);
 *      0,04 (nervuras retangulares).
 */

export type SurfaceRoughness = 'smooth' | 'rounded-ribs' | 'rectangular-ribs';

export const FRICTION_CF: Readonly<Record<SurfaceRoughness, number>> = {
  smooth: 0.01,
  'rounded-ribs': 0.02,
  'rectangular-ribs': 0.04,
};

export interface FrictionInput {
  roughness: SurfaceRoughness;
  /** Comprimento da estrutura (face a) (m) */
  length: number;
  /** Altura h */
  height: number;
  /** Largura da estrutura (face b) (m) */
  width: number;
  /** Inclinação do telhado (graus) */
  roofPitch: number;
  /** Pressão dinâmica q em kN/m² */
  q: number;
  /** Ângulo do vento: 0 (perpendicular à face a) ou 90 (perpendicular à face b) */
  windAngle: 0 | 90;
}

export interface FrictionResult {
  /** true se a condição l0/h > 4 ou l0/b > 4 foi atendida */
  applies: boolean;
  /** Área do telhado (m²) — depende do tipo de telhado */
  roofArea: number;
  /** Área das paredes paralelas ao vento (m²) */
  wallsArea: number;
  /** Cf usado */
  cf: number;
  /** Força de atrito total (kN) */
  forceKN: number;
}

/** Calcula a área do telhado em função da geometria (galpão retangular) */
export function roofArea(a: number, b: number, pitchDeg: number): number {
  const theta = (pitchDeg * Math.PI) / 180;
  const slantHalf = (b / 2) / Math.cos(theta);
  return 2 * slantHalf * a;
}

export function calculateFriction(input: FrictionInput): FrictionResult {
  const { length, width, height, roofPitch, windAngle, roughness, q } = input;
  
  // l0: comprimento da superfície paralela ao vento (profundidade)
  // b0: dimensão perpendicular ao vento (largura da face frontal)
  const l0 = windAngle === 90 ? width : length;
  const b0 = windAngle === 90 ? length : width;

  const ratioLh = l0 / height;
  const ratioLb = l0 / b0;
  const applies = ratioLh > 4 || ratioLb > 4;
  const cf = FRICTION_CF[roughness];

  if (!applies) {
    return { applies, roofArea: 0, wallsArea: 0, cf, forceKN: 0 };
  }

  const ratioH_b0 = height / b0;

  // Áreas das paredes paralelas ao vento
  const wallsArea = 2 * l0 * height;

  // Área da cobertura
  const roofSlant = roofArea(length, width, roofPitch);

  let totalArea = 0;
  // Conforme NBR 6123 sec. 6.1.5 (interpretação padrão):
  // h/b0 <= 1: atrito atua na cobertura
  // h/b0 > 1: atrito atua nas paredes laterais
  if (ratioH_b0 <= 1) {
    totalArea = roofSlant;
  } else {
    totalArea = wallsArea;
  }

  const forceKN = cf * q * totalArea;

  return {
    applies,
    roofArea: roofSlant,
    wallsArea,
    cf,
    forceKN: Number(forceKN.toFixed(3)),
  };
}