import { describe, it, expect } from 'vitest';
import { applyConceptoEdits, AVISO_EDITADO } from '@/budget/edit';
import type { BudgetResult } from '@/budget/types';

const base: BudgetResult = {
  partidas: [
    { key: 'demolicion', label: 'Demolición', importe: 100000 },
    { key: 'alicatado', label: 'Alicatado y solado', importe: 200000 },
  ],
  subtotal: 300000,
  factorZona: 1.2,
  total: 360000,
  rango: { min: 324000, max: 396000 },
  confianza: 'media',
  materialesRender: ['azulejo blanco'],
  avisos: ['Sin precio para pintura'],
};

describe('applyConceptoEdits', () => {
  it('recalcula subtotal y total aplicando el factor de zona', () => {
    const result = applyConceptoEdits(base, [
      { key: 'demolicion', label: 'Demolición', importe: 150000 },
      { key: 'alicatado', label: 'Alicatado y solado', importe: 200000 },
    ]);
    expect(result.subtotal).toBe(350000);
    expect(result.total).toBe(420000); // 350000 * 1.2
  });

  it('permite añadir partidas libres y quitar existentes', () => {
    const result = applyConceptoEdits(base, [
      { key: 'demolicion', label: 'Demolición', importe: 100000 },
      { key: 'custom-1', label: 'Imprevistos de obra', importe: 50000 },
    ]);
    expect(result.partidas).toHaveLength(2);
    expect(result.partidas[1]).toEqual({ key: 'custom-1', label: 'Imprevistos de obra', importe: 50000 });
    expect(result.subtotal).toBe(150000);
  });

  it('descarta partidas sin etiqueta y normaliza importes (>=0, enteros)', () => {
    const result = applyConceptoEdits(base, [
      { key: 'a', label: '  ', importe: 999 },
      { key: 'b', label: 'Válida', importe: -500 },
      { key: 'c', label: 'Decimal', importe: 123.7 },
    ]);
    expect(result.partidas).toEqual([
      { key: 'b', label: 'Válida', importe: 0 },
      { key: 'c', label: 'Decimal', importe: 124 },
    ]);
  });

  it('marca el presupuesto como ajustado a mano (aviso idempotente, confianza alta, rango = total)', () => {
    const once = applyConceptoEdits(base, base.partidas);
    expect(once.confianza).toBe('alta');
    expect(once.avisos).toContain(AVISO_EDITADO);
    expect(once.rango).toEqual({ min: once.total, max: once.total });

    const twice = applyConceptoEdits(once, once.partidas);
    expect(twice.avisos.filter((a) => a === AVISO_EDITADO)).toHaveLength(1);
  });
});
