import type { BudgetInputs, BudgetResult, PartidaResult, TipoReforma } from '@/budget/types';
import type { AbstractedPreferences } from './preferences';

interface LeadInputsSource {
  tipoReforma: TipoReforma | null;
  m2Suelo: number | null;
  alturaTecho: number | null;
  provincia: string | null;
  anteriorA2000?: boolean;
  cambioDistribucion?: boolean;
}

export function mergeIntoBudgetInputs(
  prefs: AbstractedPreferences,
  lead: LeadInputsSource,
): BudgetInputs {
  return {
    tipoReforma: lead.tipoReforma ?? 'otro',
    m2Suelo: lead.m2Suelo,
    alturaTecho: lead.alturaTecho,
    calidadGlobal: prefs.calidadGlobal,
    estructural: prefs.estructural,
    provincia: lead.provincia,
    materialSelections: prefs.materialSelections,
    anteriorA2000: lead.anteriorA2000 ?? false,
    cambioDistribucion: lead.cambioDistribucion ?? false,
  };
}

export function applyPreferences(
  result: BudgetResult,
  prefs: AbstractedPreferences,
): BudgetResult {
  const extras: PartidaResult[] = prefs.elementos.map((e) => ({
    key: e.key,
    label: e.label,
    importe: e.importe,
  }));

  prefs.ajustes.forEach((a, i) => {
    const importe =
      a.tipo === 'fijo' ? a.valor : Math.round(result.subtotal * (a.valor - 1));
    if (importe === 0) return;
    extras.push({ key: `ajuste_${i}`, label: a.label, importe });
  });

  if (extras.length === 0 && prefs.estiloRender.length === 0) return result;

  const partidas = [...result.partidas, ...extras];
  const subtotal = partidas.reduce((s, p) => s + p.importe, 0);
  const total = Math.round(subtotal * result.factorZona);
  const scale = result.total > 0 ? total / result.total : 1;
  const rango = {
    min: Math.round(result.rango.min * scale),
    max: Math.round(result.rango.max * scale),
  };
  const materialesRender = [...result.materialesRender, ...prefs.estiloRender];

  return { ...result, partidas, subtotal, total, rango, materialesRender };
}
