const DEFAULT_OUTLINE_TITLE = '系统模块设计'
const FALLBACK_GROUP_TITLE = '未分组模块'

function cleanText(value, fallback = '') {
  const text = String(value ?? '').trim()
  return text || fallback
}

function textFromFields(value, fallback = '') {
  if (!value || typeof value !== 'object') return cleanText(value, fallback)
  return cleanText(value.title ?? value.name ?? value.code, fallback)
}

function menuToItem(menu) {
  if (!menu || typeof menu !== 'object') return null
  const title = cleanText(menu.name ?? menu.title ?? menu.code)
  return title ? { title } : null
}

function warning(code, line) {
  return line === undefined ? { code } : { code, line }
}

function createGroup(title) {
  return {
    title,
    items: []
  }
}

export function normalizeModuleOutline(outline = {}) {
  const groups = Array.isArray(outline.groups) ? outline.groups : []
  return {
    title: textFromFields(outline),
    groups: groups.map((group) => {
      const items = (Array.isArray(group?.items) ? group.items : []).map((item) => ({
        title: textFromFields(item)
      })).filter((item) => item.title)
      return {
        title: textFromFields(group, items.length ? FALLBACK_GROUP_TITLE : ''),
        items
      }
    }).filter((group) => group.title || group.items.length)
  }
}

export function parseModuleOutlineText(text = '') {
  const warnings = []
  const lines = String(text ?? '').replace(/\t/g, '  ').split(/\r?\n/)
  const contentLines = lines
    .map((line, index) => ({ line, number: index + 1, title: line.trim() }))
    .filter((entry) => entry.title)

  if (!contentLines.length) {
    return {
      outline: { title: '', groups: [] },
      warnings: [warning('EMPTY_OUTLINE')]
    }
  }

  const outline = {
    title: contentLines[0].title,
    groups: []
  }
  let currentGroup = null

  contentLines.slice(1).forEach((entry) => {
    const indent = entry.line.match(/^ */)?.[0].length ?? 0

    if (indent < 2) {
      currentGroup = createGroup(entry.title)
      outline.groups.push(currentGroup)
      warnings.push(warning('GROUP_WITHOUT_INDENT', entry.number))
      return
    }

    if (indent < 4) {
      currentGroup = createGroup(entry.title)
      outline.groups.push(currentGroup)
      return
    }

    if (!currentGroup) {
      currentGroup = createGroup(FALLBACK_GROUP_TITLE)
      outline.groups.push(currentGroup)
      warnings.push(warning('LEAF_WITHOUT_GROUP', entry.number))
    }
    currentGroup.items.push({ title: entry.title })
  })

  return {
    outline: normalizeModuleOutline(outline),
    warnings
  }
}

export function blueprintToModuleOutline(blueprint = {}, options = {}) {
  const title = cleanText(options.projectName, cleanText(blueprint.projectName, DEFAULT_OUTLINE_TITLE))
  const groups = [
    {
      title: '管理员端',
      items: (Array.isArray(blueprint.adminMenus) ? blueprint.adminMenus : []).map(menuToItem).filter(Boolean)
    },
    {
      title: '普通用户端',
      items: (Array.isArray(blueprint.frontendMenus) ? blueprint.frontendMenus : []).map(menuToItem).filter(Boolean)
    }
  ].filter((group) => group.items.length)

  return normalizeModuleOutline({
    title,
    groups
  })
}

export function moduleOutlineToText(outline = {}) {
  const normalized = normalizeModuleOutline(outline)
  const lines = []

  if (normalized.title) {
    lines.push(normalized.title)
  }

  normalized.groups.forEach((group) => {
    lines.push(`  ${group.title}`)
    group.items.forEach((item) => {
      lines.push(`    ${item.title}`)
    })
  })

  return lines.join('\n')
}
