"""OutputStandardizer - 标准化输出

Schema 验证、字段类型归一化、元数据附加。
"""

import logging
from dataclasses import dataclass
from datetime import datetime, timezone
from typing import Any

from agentkit.quality.gate import QualityResult
from agentkit.skills.base import Skill

logger = logging.getLogger(__name__)


@dataclass
class OutputMetadata:
    """输出元数据"""

    version: str
    produced_at: datetime
    quality_score: float


@dataclass
class StandardOutput:
    """标准化输出"""

    skill_name: str
    data: dict[str, Any]
    metadata: OutputMetadata


class OutputStandardizer:
    """标准化输出 — Schema 验证 + 类型归一化 + 元数据"""

    async def standardize(
        self,
        raw_output: dict[str, Any],
        skill: Skill,
        quality_result: QualityResult | None = None,
    ) -> StandardOutput:
        """标准化产出

        1. Schema 验证（如 output_schema 存在）
        2. 字段类型归一化（确保类型与 schema 一致）
        3. 附加元数据（version、produced_at、quality_score）
        """
        schema = skill.config.output_schema

        # 1 & 2: Schema 验证 + 类型归一化
        data = self._validate_schema(raw_output, schema)
        data = self._normalize_types(data, schema)

        # 3: 附加元数据
        metadata = OutputMetadata(
            version=skill.config.version,
            produced_at=datetime.now(timezone.utc),
            quality_score=self._calculate_quality_score(quality_result),
        )

        return StandardOutput(
            skill_name=skill.name,
            data=data,
            metadata=metadata,
        )

    def _validate_schema(self, output: dict, schema: dict | None) -> dict:
        """验证并返回 output。无 schema 时原样返回。"""
        if schema is None:
            return output

        try:
            import jsonschema

            jsonschema.validate(output, schema)
        except jsonschema.ValidationError:
            # 验证失败时仍返回原始数据，由 QualityGate 负责拦截
            logger.warning("Schema validation failed for output")
        except ImportError:
            pass

        return output

    def _normalize_types(self, output: dict, schema: dict | None) -> dict:
        """根据 schema 定义归一化字段类型"""
        if schema is None:
            return output

        properties = schema.get("properties", {})
        result = dict(output)

        for field_name, field_schema in properties.items():
            if field_name not in result:
                continue

            expected_type = field_schema.get("type")
            value = result[field_name]

            if expected_type == "integer" and isinstance(value, str):
                try:
                    result[field_name] = int(value)
                except (ValueError, TypeError):
                    pass  # 无法转换，保留原值
            elif expected_type == "number" and isinstance(value, str):
                try:
                    result[field_name] = float(value)
                except (ValueError, TypeError):
                    pass
            elif expected_type == "boolean" and isinstance(value, str):
                if value.lower() == "true":
                    result[field_name] = True
                elif value.lower() == "false":
                    result[field_name] = False

        return result

    def _calculate_quality_score(self, quality_result: QualityResult | None) -> float:
        """从 QualityResult 计算质量分数（0.0-1.0）"""
        if quality_result is None:
            return 1.0
        if not quality_result.checks:
            return 1.0
        return sum(1 for c in quality_result.checks if c.passed) / len(quality_result.checks)
