import test from 'node:test'
import assert from 'node:assert/strict'
import {
  blueprintToModuleOutline,
  moduleOutlineToText,
  normalizeModuleOutline,
  parseModuleOutlineText
} from './appModuleOutline.js'

const studentClubText = `学生社团管理系统
  管理员端
    注册登录
    用户管理
    社团管理
    成员管理
    活动管理
    公告管理
    系统管理
  普通用户端
    注册登录
    社团浏览
    社团申请
    活动浏览
    活动报名
    个人中心`

test('parseModuleOutlineText parses the reference student club outline', () => {
  const result = parseModuleOutlineText(studentClubText)

  assert.deepEqual(result.warnings, [])
  assert.equal(result.outline.title, '学生社团管理系统')
  assert.deepEqual(result.outline.groups.map((group) => group.title), ['管理员端', '普通用户端'])
  assert.deepEqual(result.outline.groups[0].items.map((item) => item.title), [
    '注册登录',
    '用户管理',
    '社团管理',
    '成员管理',
    '活动管理',
    '公告管理',
    '系统管理'
  ])
  assert.deepEqual(result.outline.groups[1].items.map((item) => item.title), [
    '注册登录',
    '社团浏览',
    '社团申请',
    '活动浏览',
    '活动报名',
    '个人中心'
  ])
})

test('parseModuleOutlineText normalizes tabs as two-space indentation', () => {
  const result = parseModuleOutlineText('图书借阅系统\n\t管理端\n\t\t图书管理')

  assert.equal(result.outline.title, '图书借阅系统')
  assert.equal(result.outline.groups[0].title, '管理端')
  assert.equal(result.outline.groups[0].items[0].title, '图书管理')
})

test('parseModuleOutlineText accepts imperfect indentation with warnings', () => {
  const result = parseModuleOutlineText('客户管理系统\n客户模块\n    客户列表\n      客户详情')

  assert.equal(result.outline.title, '客户管理系统')
  assert.equal(result.outline.groups[0].title, '客户模块')
  assert.deepEqual(result.outline.groups[0].items.map((item) => item.title), ['客户列表', '客户详情'])
  assert.equal(result.warnings.some((warning) => warning.code === 'GROUP_WITHOUT_INDENT'), true)
})

test('parseModuleOutlineText returns empty outline warnings for blank input', () => {
  const result = parseModuleOutlineText('  \n\t')

  assert.equal(result.outline.title, '')
  assert.deepEqual(result.outline.groups, [])
  assert.equal(result.warnings.some((warning) => warning.code === 'EMPTY_OUTLINE'), true)
})

test('blueprintToModuleOutline maps project menus into standard groups', () => {
  const outline = blueprintToModuleOutline({
    projectName: '社团系统',
    adminMenus: [
      { code: 'users', name: '用户管理' },
      { code: 'clubs', title: '社团管理' }
    ],
    frontendMenus: [
      { code: 'browse', name: '社团浏览' },
      { code: 'profile' }
    ]
  }, {
    projectName: '学生社团管理系统'
  })

  assert.equal(outline.title, '学生社团管理系统')
  assert.deepEqual(outline.groups.map((group) => group.title), ['管理员端', '普通用户端'])
  assert.deepEqual(outline.groups[0].items.map((item) => item.title), ['用户管理', '社团管理'])
  assert.deepEqual(outline.groups[1].items.map((item) => item.title), ['社团浏览', 'profile'])
})

test('blueprintToModuleOutline skips invalid menus while preserving code-only menus', () => {
  const outline = blueprintToModuleOutline({
    adminMenus: [
      null,
      '菜单',
      {},
      { name: ' ', title: '', code: '\t' },
      { code: 'users' }
    ],
    frontendMenus: [
      undefined,
      { title: '  ' },
      { code: 'browse' }
    ]
  })

  assert.deepEqual(outline.groups.map((group) => group.title), ['管理员端', '普通用户端'])
  assert.deepEqual(outline.groups[0].items.map((item) => item.title), ['users'])
  assert.deepEqual(outline.groups[1].items.map((item) => item.title), ['browse'])
})

test('normalizeModuleOutline gives untitled groups with items the fallback group title', () => {
  const outline = normalizeModuleOutline({
    title: '客户管理系统',
    groups: [
      { title: ' ', items: [{ title: '客户列表' }] }
    ]
  })

  assert.equal(outline.groups[0].title, '未分组模块')
  assert.equal(moduleOutlineToText(outline), '客户管理系统\n  未分组模块\n    客户列表')
})

test('moduleOutlineToText serializes normalized outlines with two-space levels', () => {
  const outline = normalizeModuleOutline({
    title: '学生社团管理系统',
    groups: [
      { title: '管理员端', items: [{ title: '用户管理' }] },
      { title: '普通用户端', items: [{ title: '社团浏览' }] }
    ]
  })

  assert.equal(moduleOutlineToText(outline), '学生社团管理系统\n  管理员端\n    用户管理\n  普通用户端\n    社团浏览')
})
