import { test } from 'node:test';
import assert from 'node:assert/strict';
import { FitAdjustmentType } from '@prisma/client';
import { applyFitRule, applyFitRules } from './fit.logic';

test('INCHES adjustment is decimal-safe (no float drift)', () => {
  // 40.1 + 0.2 must equal exactly 40.3, not 40.300000000000004
  assert.equal(
    applyFitRule('40.1', { adjustmentType: FitAdjustmentType.INCHES, adjustmentValue: '0.2' }),
    '40.3',
  );
  assert.equal(
    applyFitRule('38', { adjustmentType: FitAdjustmentType.INCHES, adjustmentValue: '1.5' }),
    '39.5',
  );
  assert.equal(
    applyFitRule('42.25', { adjustmentType: FitAdjustmentType.INCHES, adjustmentValue: '-0.75' }),
    '41.5',
  );
});

test('PERCENTAGE adjustment is decimal-safe', () => {
  // 40 * 1.10 = 44
  assert.equal(
    applyFitRule('40', { adjustmentType: FitAdjustmentType.PERCENTAGE, adjustmentValue: '10' }),
    '44',
  );
  // 33.3 * 1.05 = 34.965
  assert.equal(
    applyFitRule('33.3', { adjustmentType: FitAdjustmentType.PERCENTAGE, adjustmentValue: '5' }),
    '34.965',
  );
});

test('zero adjustment / Regular preset leaves value unchanged', () => {
  assert.equal(
    applyFitRule('40', { adjustmentType: FitAdjustmentType.INCHES, adjustmentValue: '0' }),
    '40',
  );
});

test('non-numeric and empty values pass through untouched', () => {
  for (const v of [null, undefined, '', 'Round', 'L', '2 pcs']) {
    assert.equal(
      applyFitRule(v as string, {
        adjustmentType: FitAdjustmentType.INCHES,
        adjustmentValue: '1',
      }),
      v,
    );
  }
});

test('applyFitRules respects applicability and never mutates actuals', () => {
  const actual = { kCh: '40', kSh: '18', sPocket: 'yes' };
  const rules = [
    {
      fieldKey: 'kCh',
      adjustmentType: FitAdjustmentType.INCHES,
      adjustmentValue: '2',
      applicability: 'KS' as const,
    },
    {
      fieldKey: 'kSh',
      adjustmentType: FitAdjustmentType.INCHES,
      adjustmentValue: '1',
      applicability: 'CP' as const, // must NOT apply for KS
    },
  ];
  const finalKs = applyFitRules(actual, rules, 'KS');
  assert.equal(finalKs.kCh, '42');
  assert.equal(finalKs.kSh, '18'); // CP-only rule skipped for KS
  assert.equal(finalKs.sPocket, 'yes'); // free text untouched
  // original object unchanged
  assert.equal(actual.kCh, '40');
});
