import type { DraftField } from '../../src/domain/draft';
import type { StepFillStructure } from '../../src/domain/types';

import { describe, expect, it } from 'vitest';

import {
  checkboxGroupDeselections,
  checkboxGroupRuntimeIdentity,
  checkboxGroupTransition,
  checkboxGroupViolations,
} from '../../src/domain/checkbox-group';

const structure: StepFillStructure = {
  configuration: {
    singleStep: false,
    steps: [
      { id: 'step-1', name: '检验', order: 1 },
      { id: 'step-2', name: '复核', order: 2 },
    ],
  },
  controlSteps: {
    'eln.field.failed': 'step-1',
    'eln.field.passed': 'step-1',
    'eln.field.review': 'step-2',
  },
  repeatGroupSteps: { results: 'step-1' },
};

describe('checkbox groups', () => {
  it('builds identities from step or repeated runtime row and excludes ineligible fields', () => {
    expect(checkboxGroupRuntimeIdentity(field('eln.field.passed', false), structure))
      .toBe('step:step-1:inspection_result');
    expect(checkboxGroupRuntimeIdentity(field('eln.field.review', false), structure))
      .toBe('step:step-2:inspection_result');
    expect(checkboxGroupRuntimeIdentity(field('eln.repeat.results.row-1.passed', false), structure))
      .toBe('repeat:results:row-1:inspection_result');
    expect(checkboxGroupRuntimeIdentity(field('eln.repeat.results.row-2.passed', false), structure))
      .toBe('repeat:results:row-2:inspection_result');
    expect(checkboxGroupRuntimeIdentity(field('eln.ref.passed.copy-1', false), structure)).toBeUndefined();
    expect(checkboxGroupRuntimeIdentity({ ...field('eln.field.passed', false), readOnly: true }, structure)).toBeUndefined();
  });

  it('returns only currently selected peers from the same runtime group', () => {
    const fields = [
      field('eln.field.passed', false),
      field('eln.field.failed', true),
      field('eln.field.review', true),
      field('eln.repeat.results.row-1.passed', false),
      field('eln.repeat.results.row-1.failed', true),
      field('eln.repeat.results.row-2.failed', true),
    ];

    expect(checkboxGroupDeselections(fields, fields[0]!, true, structure)).toEqual([
      { tag: 'eln.field.failed', value: false },
    ]);
    expect(checkboxGroupDeselections(fields, fields[3]!, true, structure)).toEqual([
      { tag: 'eln.repeat.results.row-1.failed', value: false },
    ]);
    expect(checkboxGroupDeselections(fields, fields[0]!, false, structure)).toEqual([]);
  });

  it('accepts values within arbitrary bounds, rejects N+1, and supports unlimited groups', () => {
    const first = field('eln.field.passed', true, 0, 2);
    const second = field('eln.field.failed', true, 0, 2);
    const third = field('eln.field.reviewed', false, 0, 2);

    expect(checkboxGroupTransition([first, second, third], third, true)).toMatchObject({
      accepted: false,
      message: '选择组“inspection_result”最多选择 2 项',
    });
    expect(checkboxGroupTransition([first, { ...second, draftValue: false }, third], third, true)).toMatchObject({
      accepted: true,
      changes: [{ tag: 'eln.field.reviewed', value: true }],
    });
    expect(checkboxGroupTransition([
      { ...first, checkboxGroupMaxSelected: null },
      { ...second, checkboxGroupMaxSelected: null },
      { ...third, checkboxGroupMaxSelected: null },
    ], { ...third, checkboxGroupMaxSelected: null }, true).accepted).toBe(true);
  });

  it('reports minimum, maximum, and inconsistent-rule violations per runtime row', () => {
    const minimum = [
      field('eln.repeat.results.row-1.passed', false, 1, 2),
      field('eln.repeat.results.row-1.failed', false, 1, 2),
      field('eln.repeat.results.row-2.passed', true, 1, 2),
      field('eln.repeat.results.row-2.failed', false, 1, 2),
    ];
    expect(checkboxGroupViolations(minimum)).toMatchObject([
      { checkboxGroupCode: 'inspection_result', kind: 'minimum', maxSelected: 2, minSelected: 1, selectedCount: 0 },
    ]);

    const inconsistent = minimum.map((item, index) => index === 1 ? { ...item, checkboxGroupMaxSelected: 3 } : item);
    expect(checkboxGroupViolations(inconsistent)[0]?.kind).toBe('invalid');
  });
});

function field(tag: string, value: boolean, minSelected = 0, maxSelected: null | number = 1): DraftField {
  return {
    alias: tag,
    checkboxGroupCode: 'inspection_result',
    checkboxGroupMaxSelected: maxSelected,
    checkboxGroupMinSelected: minSelected,
    currentValue: value,
    documentValue: value,
    draftValue: value,
    internalId: tag,
    options: [],
    tag,
    type: 'checkbox',
  };
}
