import assert from 'node:assert/strict';
import test from 'node:test';
import {
  VERSION_DEVELOPMENT_TYPE_OPTIONS,
  buildVersionName,
  canSubmitNewVersionForm,
  canSubmitVersionEditForm,
  getEditableVersionNumber,
  getRecommendedExpectedReleaseDate,
  getVersionDevelopmentTypeOption,
} from './version-form';

test('canSubmitNewVersionForm requires expected release date', () => {
  assert.equal(canSubmitNewVersionForm({
    productId: 'prod-1',
    projectId: 'proj-1',
    versionNumber: '1.0',
    developmentType: 'agile',
    expectedReleaseDate: '',
    submitting: false,
  }), false);

  assert.equal(canSubmitNewVersionForm({
    productId: 'prod-1',
    projectId: 'proj-1',
    versionNumber: '1.0',
    developmentType: 'agile',
    expectedReleaseDate: '2026-07-15',
    submitting: false,
  }), true);
});

test('canSubmitNewVersionForm requires project development type', () => {
  assert.equal(canSubmitNewVersionForm({
    productId: 'prod-1',
    projectId: 'proj-1',
    versionNumber: '1.0',
    developmentType: '',
    expectedReleaseDate: '2026-07-15',
    submitting: false,
  }), false);
});

test('canSubmitNewVersionForm blocks duplicate submits', () => {
  assert.equal(canSubmitNewVersionForm({
    productId: 'prod-1',
    projectId: 'proj-1',
    versionNumber: '1.0',
    developmentType: 'agile',
    expectedReleaseDate: '2026-07-15',
    submitting: true,
  }), false);
});

test('canSubmitVersionEditForm requires version number and expected release date', () => {
  assert.equal(canSubmitVersionEditForm({
    versionNumber: '',
    expectedReleaseDate: '2026-07-15',
    submitting: false,
  }), false);

  assert.equal(canSubmitVersionEditForm({
    versionNumber: '1.2',
    expectedReleaseDate: '',
    submitting: false,
  }), false);

  assert.equal(canSubmitVersionEditForm({
    versionNumber: '1.2',
    expectedReleaseDate: '2026-07-15',
    submitting: false,
  }), true);
});

test('version edit helpers keep the project prefix and editable version number separate', () => {
  assert.equal(getEditableVersionNumber('小白项目', '小白项目V1.2.3'), '1.2.3');
  assert.equal(getEditableVersionNumber('小白项目', '其他项目V2.0'), '2.0');
  assert.equal(buildVersionName('小白项目', '1.2.3'), '小白项目V1.2.3');
});

test('version development type estimates include product design development and testing', () => {
  const agile = getVersionDevelopmentTypeOption('agile');

  assert.deepEqual(agile?.stages.map((stage) => stage.label), ['产品设计', '开发', '测试']);
  assert.equal(agile?.totalWorkDays, 13);
  assert.ok(VERSION_DEVELOPMENT_TYPE_OPTIONS.some((option) => option.key === 'waterfall'));
});

test('getRecommendedExpectedReleaseDate skips non-workdays from the stage total', () => {
  assert.equal(getRecommendedExpectedReleaseDate('hotfix', new Date('2026-06-30T09:00:00')), '2026-07-02');
  assert.equal(getRecommendedExpectedReleaseDate('agile', new Date('2026-06-30T09:00:00')), '2026-07-16');
});

test('getRecommendedExpectedReleaseDate excludes product design when it is already completed', () => {
  assert.equal(
    getRecommendedExpectedReleaseDate('agile', new Date('2026-06-30T09:00:00'), { productDesignCompleted: true }),
    '2026-07-14',
  );
});
