import {
  EXPENSE_RULE_BLOCK_PATTERN,
  RULE_SPREADSHEET_BLOCK_PATTERN,
  RULE_TEMPLATE_LABELS
} from './auditViewMetadata.js'
import {
  isPlainObject,
  normalizeText,
  readConfigJson
} from './auditViewDataUtils.js'

export function cloneJsonObject(value) {
  if (!isPlainObject(value)) {
    return null
  }
  try {
    return JSON.parse(JSON.stringify(value))
  } catch {
    return { ...value }
  }
}

export function resolveRuleTemplateLabel(value) {
  const templateKey = normalizeText(value)
  return RULE_TEMPLATE_LABELS[templateKey] || templateKey || '未指定模板'
}

export function extractRuntimeRuleFromMarkdown(markdown) {
  const match = String(markdown || '').match(EXPENSE_RULE_BLOCK_PATTERN)
  if (!match) {
    return null
  }

  try {
    const payload = JSON.parse(match[1])
    return isPlainObject(payload) ? payload : null
  } catch {
    return null
  }
}

export function extractSpreadsheetMetaFromMarkdown(markdown) {
  const match = String(markdown || '').match(RULE_SPREADSHEET_BLOCK_PATTERN)
  if (!match) {
    return null
  }

  try {
    const payload = JSON.parse(match[1])
    return isPlainObject(payload) ? payload : null
  } catch {
    return null
  }
}

export function stripRuntimeRuleBlock(markdown) {
  return String(markdown || '')
    .replace(EXPENSE_RULE_BLOCK_PATTERN, '')
    .replace(/\n{3,}/g, '\n\n')
    .trim()
}

export function stringifyRuntimeRule(runtimeRule) {
  return JSON.stringify(isPlainObject(runtimeRule) ? runtimeRule : {}, null, 2)
}

export function parseRuntimeRuleText(runtimeRuleText) {
  const text = normalizeText(runtimeRuleText)
  if (!text) {
    return null
  }

  try {
    const payload = JSON.parse(text)
    return isPlainObject(payload) ? payload : null
  } catch {
    return null
  }
}

export function buildDefaultRuntimeRule(source) {
  const configJson = readConfigJson(source)
  const scenarioItems = Array.isArray(source?.scenario_json)
    ? source.scenario_json
    : Array.isArray(source?.scenarioList)
      ? source.scenarioList
      : []
  const configRuntimeRule = cloneJsonObject(configJson.runtime_rule)

  return {
    kind: normalizeText(configRuntimeRule?.kind || configJson.runtime_kind) || 'policy_rule_draft',
    version:
      typeof configRuntimeRule?.version === 'number' && Number.isFinite(configRuntimeRule.version)
        ? configRuntimeRule.version
        : 1,
    template_key:
      normalizeText(configRuntimeRule?.template_key || configJson.rule_template_key) || 'general_policy_v1',
    rule_name: normalizeText(configRuntimeRule?.rule_name || source?.name) || '未命名规则',
    scenario: normalizeText(configRuntimeRule?.scenario || scenarioItems[0]) || 'expense',
    review_required:
      typeof configRuntimeRule?.review_required === 'boolean' ? configRuntimeRule.review_required : true
  }
}

export function resolveRuntimeRuleForVersion(source, rawMarkdown, runtimeRuleFallback = null) {
  return (
    cloneJsonObject(extractRuntimeRuleFromMarkdown(rawMarkdown)) ||
    cloneJsonObject(runtimeRuleFallback) ||
    buildDefaultRuntimeRule(source)
  )
}

export function buildMarkdownVersionContent(markdownContent, runtimeRule) {
  const body = stripRuntimeRuleBlock(markdownContent)
  const runtimeBlock = ['```expense-rule', stringifyRuntimeRule(runtimeRule), '```'].join('\n')
  return body ? `${body}\n\n${runtimeBlock}` : runtimeBlock
}
