import assert from 'node:assert/strict';
import test from 'node:test';

import type { VersionWithContext } from './derive';
import type { V22XiaobaoWarningSummary } from './v22-api';
import {
  buildXiaobaoRisksFromV22Summaries,
  filterV22XiaobaoSummariesForVisibleVersions,
  shouldLoadXiaobaoAppDataFallback,
} from './xiaobao-v22-summary';

test('buildXiaobaoRisksFromV22Summaries preserves precomputed risk details with version context', () => {
  const risks = buildXiaobaoRisksFromV22Summaries({
    summaries: [{
      versionId: 'version-1',
      riskLevel: 'likely_delayed',
      riskScore: 86,
      confidence: 72,
      forecastReleaseDate: '2026-07-09T00:00:00.000Z',
      riskSignature: 'signature-1',
      recomputedAt: '2026-07-03T09:00:00.000Z',
      updatedAt: '2026-07-03T09:05:00.000Z',
      summary: {
        delayDays: 2,
        remainingWorkHours: 30,
        reasons: [{
          key: 'forecast_delay',
          title: 'Forecast delay',
          detail: 'Forecast release date moved after the expected release date.',
          severity: 'danger',
          count: 1,
        }],
        silentRisks: [{
          key: 'no_activity',
          title: 'No activity',
          detail: 'No work activity for four days.',
          itemId: 'dev-1',
          itemType: 'dev_task',
        }],
        signals: {
          unfinishedCount: 5,
          openBugCount: 2,
          criticalBugCount: 1,
          failedTestCount: 1,
          blockedCount: 0,
          silentRiskCount: 1,
          daysToExpectedRelease: 1,
        },
        dailyEvidence: {
          todayDeliveries: [{ id: 'ev-1', title: 'Delivery', summary: 'Submitted core task.', occurredAt: '2026-07-03T08:00:00.000Z' }],
          todayProgress: [],
          todayCreations: [],
          todayRisks: [],
          progressNotes: [],
          needsProgressItems: [],
          recentActivityCount: 3,
          totalActivityCount: 1,
          todayActualHours: 2,
          lastActivityAt: '2026-07-03T08:00:00.000Z',
        },
        trend: {
          direction: 'up',
          delta: 16,
          summary: 'Risk rose by 16 points.',
          pattern: 'score_delta',
        },
        currentSnapshot: {
          date: '2026-07-03',
          openBugCount: 2,
          criticalBugCount: 1,
          failedTestCount: 1,
          blockedCount: 0,
          silentRiskCount: 1,
          createdAt: '2026-07-03T09:00:00.000Z',
        },
      },
    }],
    versions: [version()],
    snapshots: [],
    now: new Date('2026-07-03T10:00:00.000Z'),
  });

  assert.equal(risks.length, 1);
  assert.equal(risks[0].versionName, 'Payments V1.0');
  assert.equal(risks[0].productName, 'Payments');
  assert.equal(risks[0].projectName, 'Wallet');
  assert.equal(risks[0].expectedReleaseDate, '2026-07-07');
  assert.equal(risks[0].riskLevel, 'likely_delayed');
  assert.equal(risks[0].riskScore, 86);
  assert.equal(risks[0].confidence, 72);
  assert.equal(risks[0].confidenceLevel, 'medium');
  assert.equal(risks[0].forecastReleaseDate, '2026-07-09T00:00:00.000Z');
  assert.equal(risks[0].delayDays, 2);
  assert.equal(risks[0].remainingWorkHours, 30);
  assert.equal(risks[0].reasons[0].key, 'forecast_delay');
  assert.equal(risks[0].silentRisks[0].itemType, 'dev_task');
  assert.equal(risks[0].signals.openBugCount, 2);
  assert.equal(risks[0].dailyEvidence?.todayDeliveries[0].summary, 'Submitted core task.');
  assert.equal(risks[0].currentSnapshot.date, '2026-07-03');
  assert.equal(risks[0].currentSnapshot.riskScore, 86);
  assert.equal(risks[0].currentSnapshot.riskLevel, 'likely_delayed');
  assert.equal(risks[0].trend.summary, 'Risk rose by 16 points.');
});

test('buildXiaobaoRisksFromV22Summaries builds compatible defaults from sparse summaries', () => {
  const risks = buildXiaobaoRisksFromV22Summaries({
    summaries: [{
      versionId: 'version-1',
      riskLevel: 'at_risk',
      riskScore: 66,
      confidence: 48,
      forecastReleaseDate: '2026-07-09T00:00:00.000Z',
      riskSignature: 'signature-1',
      updatedAt: '2026-07-03T09:05:00.000Z',
      summary: { reasons: 'not-an-array' },
    }],
    versions: [version({ expectedReleaseDate: '2026-07-07' })],
    snapshots: [{
      versionId: 'version-1',
      date: '2026-07-01',
      riskScore: 40,
      riskLevel: 'attention',
      openBugCount: 1,
      criticalBugCount: 0,
      failedTestCount: 0,
      blockedCount: 0,
      silentRiskCount: 0,
      confidence: 80,
      createdAt: '2026-07-01T09:00:00.000Z',
    }],
    now: new Date('2026-07-03T10:00:00.000Z'),
  });

  assert.equal(risks[0].delayDays, 2);
  assert.equal(risks[0].remainingWorkHours, 0);
  assert.equal(risks[0].confidenceLevel, 'low');
  assert.equal(risks[0].reasons.length, 1);
  assert.equal(risks[0].reasons[0].key, 'precomputed_risk');
  assert.equal(risks[0].signals.unfinishedCount, 0);
  assert.equal(risks[0].currentSnapshot.openBugCount, 0);
  assert.equal(risks[0].currentSnapshot.createdAt, '2026-07-03T09:05:00.000Z');
  assert.equal(risks[0].trend.direction, 'up');
});

test('shouldLoadXiaobaoAppDataFallback waits for V2.2 summary before loading heavy AppData stores', () => {
  assert.equal(shouldLoadXiaobaoAppDataFallback('idle'), false);
  assert.equal(shouldLoadXiaobaoAppDataFallback('loading'), false);
  assert.equal(shouldLoadXiaobaoAppDataFallback('ready'), false);
  assert.equal(shouldLoadXiaobaoAppDataFallback('empty'), true);
  assert.equal(shouldLoadXiaobaoAppDataFallback('failed'), true);
});

test('filterV22XiaobaoSummariesForVisibleVersions keeps only visible version summaries', () => {
  const summaries = [
    summary({ versionId: 'visible-1', riskScore: 80 }),
    summary({ versionId: 'hidden-1', riskScore: 95 }),
    summary({ versionId: 'visible-2', riskScore: 70 }),
  ];

  const result = filterV22XiaobaoSummariesForVisibleVersions(summaries, [
    version({ id: 'visible-1' }),
    version({ id: 'visible-2' }),
  ]);

  assert.deepEqual(result.map((item) => item.versionId), ['visible-1', 'visible-2']);
});

function summary(patch: Partial<V22XiaobaoWarningSummary> = {}): V22XiaobaoWarningSummary {
  return {
    versionId: 'version-1',
    riskLevel: 'at_risk',
    riskScore: 60,
    confidence: 80,
    riskSignature: 'signature',
    summary: {},
    updatedAt: '2026-07-03T09:00:00.000Z',
    ...patch,
  };
}

function version(patch: Partial<VersionWithContext> = {}): VersionWithContext {
  return {
    id: 'version-1',
    name: 'Payments V1.0',
    status: 'developing',
    releaseDate: null,
    createdAt: '2026-07-01T00:00:00.000Z',
    productId: 'product-1',
    productName: 'Payments',
    projectId: 'project-1',
    projectName: 'Wallet',
    expectedReleaseDate: '2026-07-07',
    members: [{ name: 'Alice', role: 'frontend' }],
    ...patch,
  } as VersionWithContext;
}
