"""
Playbook Seed Service — 從 alert_rules.yaml 初始化 Playbook 資料
=================================================================
職責:
  - 啟動時讀取 alert_rules.yaml
  - 將每條規則轉換為 APPROVED Playbook 寫入 DB（冪等：已存在則跳過）
  - 確保自動修復鏈路有資料可用

呼叫方: main.py lifespan (asyncio.create_task — 非阻塞)

2026-04-10 Claude Sonnet 4.6 Asia/Taipei
"""
from __future__ import annotations

from pathlib import Path

import structlog
import yaml

logger = structlog.get_logger(__name__)

_RULES_PATH = Path(__file__).parent.parent.parent / "alert_rules.yaml"


async def seed_playbooks_from_rules() -> None:
    """從 alert_rules.yaml 匯入 APPROVED Playbook（冪等）"""
    try:
        if not _RULES_PATH.exists():
            logger.warning("playbook_seed_rules_not_found", path=str(_RULES_PATH))
            return

        data = yaml.safe_load(_RULES_PATH.read_text())
        rules = data.get("rules", [])
        if not rules:
            return

        from src.models.playbook import (
            ActionType, Playbook, PlaybookSource, PlaybookStatus,
            RepairStep, RiskLevel, SymptomPattern,
        )
        from src.repositories.playbook_repository import get_playbook_repository

        repo = get_playbook_repository()

        # 取得現有 YAML_RULE playbook，依 name 去重避免重複建立
        # 2026-04-15 ogt: 不再用 list_playbooks（舊格式 repair_steps 會 validation error）
        #                  改用 raw SQL 只撈 name 欄位，更穩健
        # 2026-04-24 ogt + Claude Sonnet 4.6: 修復重複建立/封存迴圈
        #   舊邏輯 status != 'deprecated' 導致：deprecated 歷史記錄永遠存在 →
        #   每次啟動都重建同名 Playbook（C1 保護後不再封存，但 deprecated 不清除）
        #   修：不管 status，同名 yaml_rule 任何狀態存在即視為已存在，不重建
        from src.db.base import get_db_context
        from sqlalchemy import text as sa_text
        async with get_db_context() as db:
            rows = await db.execute(
                sa_text(
                    "SELECT name FROM playbooks WHERE source = 'yaml_rule'"
                )
            )
            existing_names = {r[0] for r in rows.fetchall()}

        seeded = 0
        for rule in rules:
            rule_id = rule.get("id", "")
            rule_name = rule.get("description", rule_id)
            if rule_name in existing_names:
                continue

            resp = rule.get("response", {})
            kubectl_cmd = resp.get("kubectl_command", "").strip()
            if not kubectl_cmd:
                continue

            risk_str = resp.get("risk", "medium").lower()
            risk_map = {"low": RiskLevel.LOW, "medium": RiskLevel.MEDIUM, "critical": RiskLevel.HIGH}
            risk = risk_map.get(risk_str, RiskLevel.MEDIUM)

            alertnames = rule.get("match", {}).get("alertname", [])
            action_type = ActionType.KUBECTL
            if kubectl_cmd.startswith("ssh"):
                action_type = ActionType.SSH_COMMAND

            playbook = Playbook(
                name=rule.get("description", rule_id),
                description=resp.get("description", rule.get("description", "")),
                status=PlaybookStatus.APPROVED,
                source=PlaybookSource.YAML_RULE,
                symptom_pattern=SymptomPattern(
                    alert_names=alertnames,
                    affected_services=[],
                    severity_range=["P2", "P3"],
                ),
                repair_steps=[
                    RepairStep(
                        step_number=1,
                        action_type=action_type,
                        command=kubectl_cmd,
                        expected_result=resp.get("action_title", ""),
                        risk_level=risk,
                        requires_approval=False,
                    )
                ],
                ai_confidence=1.0,
                approved_by="alert_rules_yaml",
            )

            try:
                await repo.create(playbook)
                seeded += 1
                logger.info("playbook_seeded", rule_id=rule_id, name=playbook.name)
            except Exception as e:
                logger.warning("playbook_seed_failed", rule_id=rule_id, error=str(e))

        logger.info("playbook_seed_complete", seeded=seeded, total=len(rules))

    except Exception as e:
        logger.error("playbook_seed_error", error=str(e))
