param(
  [string]$ProjectRoot = "",
  [switch]$AsJson,
  [switch]$AllowWarningsOnly
)

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

if ([string]::IsNullOrWhiteSpace($ProjectRoot)) {
  $ProjectRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot "..\..\..\.."))
}

function New-Issue {
  param(
    [string]$Severity,
    [string]$File,
    [string]$Section,
    [string]$Message
  )

  [PSCustomObject]@{
    severity = $Severity
    file = $File
    section = $Section
    message = $Message
  }
}

function Get-FileContentOrNull {
  param([string]$Path)

  if (-not (Test-Path -LiteralPath $Path)) {
    return $null
  }

  Get-Content -LiteralPath $Path -Raw
}

function Test-ContainsAll {
  param(
    [string]$Content,
    [string[]]$Terms
  )

  foreach ($term in $Terms) {
    if ($Content -notmatch [regex]::Escape($term)) {
      return $false
    }
  }

  return $true
}

$issues = @()

$componentMapPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\design\component-map.md"
$frontendArchitecturePath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\design\frontend-architecture.md"
$frontendQualityPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\docs\frontend-quality-rules.md"
$currentTaskPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\context\CURRENT_TASK.md"
$imageSpecPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\design\image-to-frontend-spec.md"

$componentMap = Get-FileContentOrNull -Path $componentMapPath
$frontendArchitecture = Get-FileContentOrNull -Path $frontendArchitecturePath
$frontendQuality = Get-FileContentOrNull -Path $frontendQualityPath
$currentTask = Get-FileContentOrNull -Path $currentTaskPath
$imageSpec = Get-FileContentOrNull -Path $imageSpecPath

if ($null -eq $componentMap) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/design/component-map.md" -Section "file" -Message "缺少 component-map 模板，无法承载第六章公共组件复用盘点。"
}
else {
  if (-not (Test-ContainsAll -Content $componentMap -Terms @("复用与新增规则", "组件复用决策", "existing / new / generated", "两个真实使用场景", "公共组件改动影响面"))) {
    $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/design/component-map.md" -Section "reuse-rules" -Message "component-map 模板缺少复用规则、复用决策、existing/new 来源、双场景约束或公共组件改动影响面。"
  }
}

if ($null -eq $frontendArchitecture) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/design/frontend-architecture.md" -Section "file" -Message "缺少 frontend-architecture 模板。"
}
else {
  if (-not (Test-ContainsAll -Content $frontendArchitecture -Terms @("## 11. 复用决策", "第二个真实使用场景", "业务组件默认留在 feature 内", "受影响调用方", "兼容策略"))) {
    $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/design/frontend-architecture.md" -Section "reuse-decision" -Message "frontend-architecture 模板缺少第六章要求的复用决策、抽象阈值或公共组件兼容约束。"
  }
}

if ($null -eq $frontendQuality) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/docs/frontend-quality-rules.md" -Section "file" -Message "缺少 frontend-quality-rules 模板。"
}
else {
  if (-not (Test-ContainsAll -Content $frontendQuality -Terms @("## 5. 组件复用边界", "新通用组件必须至少有两个明确使用场景", "generated types 可以作为数据输入类型", "修改 existing 公共组件时，必须列出受影响调用方", "wrapper、variant、slot、可选 props"))) {
    $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/docs/frontend-quality-rules.md" -Section "shared-component-guard" -Message "frontend-quality-rules 模板缺少复用边界、双场景门槛、generated types 限制或公共组件变更保护规则。"
  }
}

if ($null -eq $currentTask) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/context/CURRENT_TASK.md" -Section "file" -Message "缺少 CURRENT_TASK 模板。"
}
else {
  if (-not (Test-ContainsAll -Content $currentTask -Terms @("类似组件", "复用决定", "不复用理由", "如果修改公共组件，组件名称", "如果修改公共组件，受影响页面 / 模块", "如果修改公共组件，props 兼容性影响"))) {
    $issues += New-Issue -Severity "warning" -File "docs/codex-harness-engineering/templates/context/CURRENT_TASK.md" -Section "reuse-fields" -Message "CURRENT_TASK 模板缺少类似组件搜索、复用决策或公共组件改动影响面字段。"
  }
}

if ($null -eq $imageSpec) {
  $issues += New-Issue -Severity "warning" -File "docs/codex-harness-engineering/templates/design/image-to-frontend-spec.md" -Section "file" -Message "缺少 image-to-frontend-spec 模板，前端组件复用映射链路不完整。"
}
else {
  if (-not (Test-ContainsAll -Content $imageSpec -Terms @("复用来源", "page / feature / primitive", "每个组件都声明了 page / feature / primitive 层级和复用边界", "如果 `复用来源 = existing`"))) {
    $issues += New-Issue -Severity "warning" -File "docs/codex-harness-engineering/templates/design/image-to-frontend-spec.md" -Section "component-mapping" -Message "image-to-frontend-spec 模板还没有完整约束 existing 组件的复用映射和兼容策略。"
  }
}

$errors = @($issues | Where-Object { $_.severity -eq "error" })
$warnings = @($issues | Where-Object { $_.severity -eq "warning" })
$exitCode = if ($errors.Count -gt 0) { 1 } elseif ($warnings.Count -gt 0 -and -not $AllowWarningsOnly) { 2 } else { 0 }

if ($AsJson) {
  [PSCustomObject]@{
    ok = ($exitCode -eq 0)
    errors = $errors
    warnings = $warnings
  } | ConvertTo-Json -Depth 6
  exit $exitCode
}

if ($errors.Count -eq 0 -and $warnings.Count -eq 0) {
  Write-Output "Component lint passed."
  exit 0
}

if ($errors.Count -gt 0) {
  Write-Output "Component lint failed."
  foreach ($issue in $errors) {
    Write-Output ("- [ERROR] {0} :: {1} :: {2}" -f $issue.file, $issue.section, $issue.message)
  }
}

if ($warnings.Count -gt 0) {
  if ($errors.Count -eq 0) {
    Write-Output "Component lint passed with warnings."
  }
  foreach ($issue in $warnings) {
    Write-Output ("- [WARNING] {0} :: {1} :: {2}" -f $issue.file, $issue.section, $issue.message)
  }
}

exit $exitCode
