"""
K8s Repository - 首席架構師 P1 改進
===================================
實作 IK8sRepository Protocol

設計原則:
- 封裝 kubernetes_asyncio 操作
- Service 層不直接依賴 K8s client
- 符合 leWOOOgo 積木化原則

版本: v1.0
建立: 2026-03-30 (台北時區)
建立者: Claude Code (首席架構師 P1 改進)
"""

from datetime import UTC, datetime

import structlog

from src.core.config import settings

logger = structlog.get_logger(__name__)

# Lazy import kubernetes_asyncio to avoid import errors when not installed
_k8s_client = None
_k8s_config_loaded = False


async def _get_k8s_client():
    """Lazy load kubernetes client (內部用)"""
    global _k8s_client, _k8s_config_loaded

    if _k8s_client is not None:
        return _k8s_client

    try:
        from kubernetes_asyncio import client, config

        if not _k8s_config_loaded:
            try:
                # 優先使用 in-cluster 配置
                config.load_incluster_config()
                logger.info("k8s_repository_incluster_config")
            except config.ConfigException:
                # Fallback 到 kubeconfig
                await config.load_kube_config(config_file=settings.KUBECONFIG_PATH)
                logger.info("k8s_repository_kubeconfig", path=settings.KUBECONFIG_PATH)
            _k8s_config_loaded = True

        _k8s_client = client
        return _k8s_client

    except Exception as e:
        logger.error("k8s_repository_init_failed", error=str(e))
        return None


class K8sRepository:
    """
    K8s Repository 實作

    實作 IK8sRepository Protocol
    封裝 kubernetes_asyncio 操作
    """

    async def list_pods(
        self,
        namespace: str = "awoooi",
    ) -> list[dict]:
        """
        列出 Namespace 下的 Pods

        Returns:
            list[{name, phase, ready, restarts, age}]
        """
        client = await _get_k8s_client()
        if not client:
            logger.warning("k8s_list_pods_unavailable")
            return []

        try:
            v1 = client.CoreV1Api()
            pods = await v1.list_namespaced_pod(namespace=namespace)

            result = []
            now = datetime.now(UTC)

            for pod in pods.items:
                # 計算 restarts
                restarts = 0
                ready = True
                if pod.status.container_statuses:
                    for cs in pod.status.container_statuses:
                        restarts += cs.restart_count
                        if not cs.ready:
                            ready = False

                # 計算 age
                age_seconds = 0
                if pod.metadata.creation_timestamp:
                    age_seconds = (now - pod.metadata.creation_timestamp.replace(tzinfo=UTC)).total_seconds()

                result.append({
                    "name": pod.metadata.name,
                    "phase": pod.status.phase,
                    "ready": ready,
                    "restarts": restarts,
                    "age_seconds": int(age_seconds),
                })

            return result

        except Exception as e:
            logger.error("k8s_list_pods_failed", namespace=namespace, error=str(e))
            return []

    async def list_deployments(
        self,
        namespace: str = "awoooi",
    ) -> list[dict]:
        """
        列出 Namespace 下的 Deployments

        Returns:
            list[{name, ready_replicas, replicas, available}]
        """
        client = await _get_k8s_client()
        if not client:
            logger.warning("k8s_list_deployments_unavailable")
            return []

        try:
            apps_v1 = client.AppsV1Api()
            deployments = await apps_v1.list_namespaced_deployment(namespace=namespace)

            result = []
            for deploy in deployments.items:
                ready = deploy.status.ready_replicas or 0
                replicas = deploy.spec.replicas or 0
                available = deploy.status.available_replicas or 0

                result.append({
                    "name": deploy.metadata.name,
                    "ready_replicas": ready,
                    "replicas": replicas,
                    "available": available,
                })

            return result

        except Exception as e:
            logger.error("k8s_list_deployments_failed", namespace=namespace, error=str(e))
            return []

    async def get_pod_status_summary(
        self,
        namespace: str = "awoooi",
    ) -> dict:
        """
        取得 Pod 狀態摘要

        Returns:
            {total, running, pending, failed, problem_pods: [...]}
        """
        pods = await self.list_pods(namespace)

        total = len(pods)
        running = sum(1 for p in pods if p["phase"] == "Running" and p["ready"])
        pending = sum(1 for p in pods if p["phase"] == "Pending")
        failed = sum(1 for p in pods if p["phase"] == "Failed")

        # 找出有問題的 Pods
        problem_pods = []
        for pod in pods:
            is_problem = (
                pod["phase"] != "Running" or
                not pod["ready"] or
                pod["restarts"] > 5
            )
            if is_problem:
                problem_pods.append({
                    "name": pod["name"],
                    "phase": pod["phase"],
                    "ready": pod["ready"],
                    "restarts": pod["restarts"],
                })

        return {
            "total": total,
            "running": running,
            "pending": pending,
            "failed": failed,
            "problem_pods": problem_pods,
        }

    async def is_available(self) -> bool:
        """
        檢查 K8s API 是否可用

        Returns:
            True 如果 K8s 連線正常
        """
        client = await _get_k8s_client()
        if not client:
            return False

        try:
            v1 = client.CoreV1Api()
            # 嘗試取得 namespace 驗證連線
            await v1.read_namespace(name="default")
            return True
        except Exception as e:
            logger.warning("k8s_availability_check_failed", error=str(e))
            return False


# Singleton instance
_k8s_repository: K8sRepository | None = None


def get_k8s_repository() -> K8sRepository:
    """
    取得 K8sRepository 實例 (Singleton)

    Returns:
        K8sRepository 實例
    """
    global _k8s_repository
    if _k8s_repository is None:
        _k8s_repository = K8sRepository()
    return _k8s_repository
