from __future__ import annotations

import json
import shutil
import subprocess
from datetime import datetime
from pathlib import Path

import split_order_status_initial_branches as split


ROOT = Path(__file__).resolve().parents[1]
WORKBOOK = ROOT / "SaaS_E2E测试用例_单Sheet用例测试列表.xlsx"
PATCH_JSON = ROOT / "runtime" / "order_status_branch_split_cases.json"
BACKUP_DIR = ROOT / "runtime" / "excel_backups"


def ps_single(value: str) -> str:
    return "'" + value.replace("'", "''") + "'"


def main() -> None:
    BACKUP_DIR.mkdir(parents=True, exist_ok=True)
    backup = BACKUP_DIR / f"{WORKBOOK.stem}_before_com_branch_split_{datetime.now():%Y%m%d_%H%M%S}.xlsx"
    shutil.copy2(WORKBOOK, backup)

    with split.zipfile.ZipFile(WORKBOOK, "r") as archive:
        _, rows, _ = split.load_rows(archive)
    updated = split.transform(rows)
    PATCH_JSON.parent.mkdir(parents=True, exist_ok=True)
    PATCH_JSON.write_text(json.dumps(updated, ensure_ascii=False, indent=2), encoding="utf-8-sig")

    ps_script = rf"""
$ErrorActionPreference = "Stop"
$WorkbookPath = {ps_single(str(WORKBOOK))}
$CasesPath = {ps_single(str(PATCH_JSON))}
$Cases = Get-Content -LiteralPath $CasesPath -Raw -Encoding UTF8 | ConvertFrom-Json
$Headers = @(
  "用例编号",
  "用例层级",
  "来源/组合依据",
  "所属模块",
  "用例标题",
  "登录平台/角色账号",
  "前置条件",
  "测试数据",
  "执行步骤",
  "预期结果",
  "跨端/状态断言",
  "可组合/被引用关系",
  "自动化状态",
  "备注"
)

$Excel = $null
$Workbook = $null
try {{
    $Excel = New-Object -ComObject Excel.Application
    $Excel.Visible = $false
    $Excel.DisplayAlerts = $false
    $Workbook = $Excel.Workbooks.Open($WorkbookPath)
    if ($Workbook.ReadOnly) {{
        throw "Workbook is read-only. Please close it in Excel and retry: $WorkbookPath"
    }}

    $Sheet = $Workbook.Worksheets.Item("订单状态流转")
    $Used = $Sheet.UsedRange
    if ($Used.Rows.Count -gt 1) {{
        $Sheet.Range($Sheet.Rows.Item(2), $Sheet.Rows.Item($Used.Rows.Count)).Clear()
    }}

    for ($Column = 1; $Column -le $Headers.Count; $Column++) {{
        $Sheet.Cells.Item(1, $Column).Value2 = $Headers[$Column - 1]
    }}

    $Row = 2
    foreach ($Case in $Cases) {{
        for ($Column = 1; $Column -le $Headers.Count; $Column++) {{
            $Header = $Headers[$Column - 1]
            $Cell = $Sheet.Cells.Item($Row, $Column)
            $Cell.Value2 = [string]$Case.$Header
            $Cell.WrapText = $true
            $Cell.VerticalAlignment = -4160
        }}
        $Row++
    }}

    $LastRow = [Math]::Max(1, $Cases.Count + 1)
    $LastColumn = $Headers.Count
    $Range = $Sheet.Range($Sheet.Cells.Item(1, 1), $Sheet.Cells.Item($LastRow, $LastColumn))
    $Range.Borders.LineStyle = 1
    $Range.Borders.Weight = 2
    $Sheet.Columns.AutoFit() | Out-Null
    $Sheet.Columns.Item(9).ColumnWidth = 55
    $Sheet.Columns.Item(10).ColumnWidth = 45
    $Sheet.Columns.Item(11).ColumnWidth = 45
    for ($R = 2; $R -le $LastRow; $R++) {{
        $Sheet.Rows.Item($R).AutoFit() | Out-Null
    }}
    $Sheet.Activate()
    $Excel.ActiveWindow.SplitRow = 1
    $Excel.ActiveWindow.FreezePanes = $true

    $Workbook.Save()
    Write-Host "backup=$backup"
    Write-Host "old_count=$($Cases.Count)"
    Write-Host "updated_count=$($Cases.Count)"
}}
finally {{
    if ($Workbook -ne $null) {{
        $Workbook.Close($false)
        [System.Runtime.InteropServices.Marshal]::ReleaseComObject($Workbook) | Out-Null
    }}
    if ($Excel -ne $null) {{
        $Excel.Quit()
        [System.Runtime.InteropServices.Marshal]::ReleaseComObject($Excel) | Out-Null
    }}
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
}}
"""

    result = subprocess.run(
        [
            r"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe",
            "-NoProfile",
            "-ExecutionPolicy",
            "Bypass",
            "-Command",
            ps_script,
        ],
        cwd=ROOT,
        text=True,
        capture_output=True,
        encoding="utf-8",
        errors="replace",
    )
    print(result.stdout)
    if result.returncode != 0:
        print(result.stderr)
        raise SystemExit(result.returncode)


if __name__ == "__main__":
    main()
