from __future__ import annotations

import copy
import shutil
from datetime import datetime
from pathlib import Path

from openpyxl import load_workbook
from openpyxl.styles import PatternFill


ROOT = Path(__file__).resolve().parents[1]
SOURCE_EXCEL = ROOT / "订单状态流转_链路流程线整理.xlsx"
TARGET_EXCEL = ROOT / "SaaS_E2E测试用例_单Sheet用例测试列表.xlsx"
BACKUP_DIR = ROOT / "runtime" / "excel_backups"
CASE_IDS = ["S-FLOW-061", "S-FLOW-062", "S-FLOW-063", "S-FLOW-064"]
ORDER_STATUS_SHEET = "订单状态流转"


def header_map(ws) -> dict[str, int]:
    return {str(cell.value).strip(): cell.column for cell in ws[1] if cell.value}


def find_case_col(ws) -> int:
    headers = header_map(ws)
    for name in ("用例编号", "用例ID", "编号"):
        if name in headers:
            return headers[name]
    for col in range(1, ws.max_column + 1):
        value = str(ws.cell(1, col).value or "")
        if "用例" in value and ("编号" in value or "ID" in value):
            return col
    raise RuntimeError(f"{ws.title} 未找到用例编号列")


def find_row(ws, case_id: str) -> int | None:
    case_col = find_case_col(ws)
    for row in range(2, ws.max_row + 1):
        if str(ws.cell(row, case_col).value or "").strip() == case_id:
            return row
    return None


def copy_row_style(ws, source_row: int, target_row: int) -> None:
    ws.row_dimensions[target_row].height = ws.row_dimensions[source_row].height
    for col in range(1, ws.max_column + 1):
        source = ws.cell(source_row, col)
        target = ws.cell(target_row, col)
        if source.has_style:
            target._style = copy.copy(source._style)
        target.number_format = source.number_format
        target.alignment = copy.copy(source.alignment)
        target.font = copy.copy(source.font)
        target.fill = PatternFill(fill_type=None)
        target.border = copy.copy(source.border)


def row_as_dict(ws, row: int) -> dict[str, object]:
    headers = header_map(ws)
    return {name: ws.cell(row, col).value for name, col in headers.items()}


def source_cases() -> list[dict[str, object]]:
    wb = load_workbook(SOURCE_EXCEL)
    ws = wb["原始用例索引"]
    cases = []
    for case_id in CASE_IDS:
        row = find_row(ws, case_id)
        if row is None:
            raise RuntimeError(f"源表 原始用例索引 未找到 {case_id}")
        cases.append(row_as_dict(ws, row))
    return cases


def delete_existing_rows(ws, case_ids: list[str] | None = None) -> None:
    case_col = find_case_col(ws)
    targets = set(case_ids or CASE_IDS)
    for row in range(ws.max_row, 1, -1):
        if str(ws.cell(row, case_col).value or "").strip() in targets:
            ws.delete_rows(row, 1)


def sync_target() -> list[tuple[int, str, str]]:
    cases = source_cases()
    BACKUP_DIR.mkdir(parents=True, exist_ok=True)
    backup = BACKUP_DIR / f"{TARGET_EXCEL.stem}.before_s_flow_061_064_{datetime.now():%Y%m%d-%H%M%S}.xlsx"
    shutil.copy2(TARGET_EXCEL, backup)

    wb = load_workbook(TARGET_EXCEL)
    if ORDER_STATUS_SHEET not in wb.sheetnames:
        raise RuntimeError(f"目标 Excel 未找到 {ORDER_STATUS_SHEET} Sheet")
    ws = wb[ORDER_STATUS_SHEET]
    target_headers = header_map(ws)

    delete_existing_rows(ws)
    # Remove rows that were accidentally inserted into the generic list sheet by older script versions.
    if "用例测试列表" in wb.sheetnames:
        delete_existing_rows(wb["用例测试列表"], ["S-FLOW-034", "S-FLOW-035", *CASE_IDS])

    source_row = find_row(ws, "S-FLOW-035")
    if source_row is None:
        raise RuntimeError(f"{ORDER_STATUS_SHEET} Sheet 未找到 S-FLOW-035，无法按流程位置插入")

    insert_after = source_row
    inserted: list[tuple[int, str, str]] = []
    for case in cases:
        insert_after += 1
        ws.insert_rows(insert_after, 1)
        copy_row_style(ws, source_row, insert_after)
        for name, value in case.items():
            col = target_headers.get(name)
            if col:
                ws.cell(insert_after, col).value = value
        case_id = str(case.get("用例编号") or "")
        title = str(case.get("用例标题") or "")
        inserted.append((insert_after, case_id, title))

    wb.save(TARGET_EXCEL)
    print(f"updated: {TARGET_EXCEL}")
    print(f"backup: {backup}")
    for row, case_id, title in inserted:
        print(f"{row}: {case_id} {title}")
    return inserted


if __name__ == "__main__":
    inserted_rows = sync_target()
    wb = load_workbook(TARGET_EXCEL, read_only=False)
    ws = wb[ORDER_STATUS_SHEET]
    print("verify:")
    for row, _, _ in inserted_rows:
        print(
            f"{row}: {ws.cell(row, 1).value} | {ws.cell(row, 4).value} | "
            f"height={ws.row_dimensions[row].height}"
        )
