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

import type { Requirement } from './requirement';
import {
  buildRequirementScopeTree,
  filterRequirementScopeTreeByKeyword,
  filterRequirementsByScope,
  type RequirementScopeSelection,
} from './requirement-scope';

const baseRequirement = {
  code: 'REQ-001',
  title: 'Requirement',
  description: '',
  sourceType: 'internal',
  sourceTarget: '',
  platforms: [] as string[],
  typeId: '',
  priority: 'P2',
  effort: 'M',
  creator: 'tester',
  createdAt: '2026-06-29T00:00:00.000Z',
};

function req(id: string, productId: string, projectId: string, status: Requirement['status'] = 'pending_review'): Requirement {
  return {
    ...baseRequirement,
    id,
    code: id.toUpperCase(),
    productId,
    projectId,
    status,
  } as Requirement;
}

const overview = [
  {
    id: 'product-1',
    name: 'CRM',
    projects: [
      { id: 'project-1', name: 'Mobile', description: '', createdAt: '2026-06-29T00:00:00.000Z' },
      { id: 'project-2', name: 'Admin', description: '', createdAt: '2026-06-29T00:00:00.000Z' },
    ],
    versions: [],
  },
  {
    id: 'product-2',
    name: 'BI',
    projects: [
      { id: 'project-3', name: 'Dashboard', description: '', createdAt: '2026-06-29T00:00:00.000Z' },
    ],
    versions: [],
  },
];

test('filters requirements by all product and project scopes', () => {
  const requirements = [
    req('req-1', 'product-1', 'project-1'),
    req('req-2', 'product-1', 'project-2'),
    req('req-3', 'product-2', 'project-3'),
  ];

  const allScope: RequirementScopeSelection = { type: 'all' };
  const productScope: RequirementScopeSelection = { type: 'product', productId: 'product-1' };
  const projectScope: RequirementScopeSelection = { type: 'project', projectId: 'project-2' };

  assert.deepEqual(filterRequirementsByScope(requirements, allScope).map((item) => item.id), ['req-1', 'req-2', 'req-3']);
  assert.deepEqual(filterRequirementsByScope(requirements, productScope).map((item) => item.id), ['req-1', 'req-2']);
  assert.deepEqual(filterRequirementsByScope(requirements, projectScope).map((item) => item.id), ['req-2']);
});

test('builds product and project tree counts from requirements', () => {
  const tree = buildRequirementScopeTree(overview, [
    req('req-1', 'product-1', 'project-1', 'pending_review'),
    req('req-2', 'product-1', 'project-1', 'developing'),
    req('req-3', 'product-1', 'project-2', 'closed'),
    req('req-4', 'product-2', 'project-3', 'adopted'),
  ]);

  assert.equal(tree[0].count.total, 3);
  assert.equal(tree[0].count.byStatus.pending_review, 1);
  assert.equal(tree[0].projects[0].count.total, 2);
  assert.equal(tree[0].projects[0].count.byStatus.developing, 1);
  assert.equal(tree[0].projects[1].count.total, 1);
  assert.equal(tree[1].count.total, 1);
});

test('filters requirement scope tree by product or project keyword', () => {
  const tree = buildRequirementScopeTree(overview, [
    req('req-1', 'product-1', 'project-1', 'pending_review'),
    req('req-2', 'product-1', 'project-2', 'developing'),
    req('req-3', 'product-2', 'project-3', 'closed'),
  ]);

  const productMatched = filterRequirementScopeTreeByKeyword(tree, 'crm');
  assert.deepEqual(productMatched.map((product) => product.id), ['product-1']);
  assert.deepEqual(productMatched[0].projects.map((project) => project.id), ['project-1', 'project-2']);

  const projectMatched = filterRequirementScopeTreeByKeyword(tree, 'admin');
  assert.deepEqual(projectMatched.map((product) => product.id), ['product-1']);
  assert.deepEqual(projectMatched[0].projects.map((project) => project.id), ['project-2']);

  assert.equal(filterRequirementScopeTreeByKeyword(tree, 'missing').length, 0);
});
