"""
WCAG 2.1色彩对比度验证工具

验证所有设计token中的颜色组合是否符合WCAG标准:
- AA级 (正文): 对比度 ≥ 4.5:1
- AA级 (大文字): 对比度 ≥ 3.0:1
- AAA级 (正文): 对比度 ≥ 7.0:1

使用方法:
python tools/validate_colors.py

或集成到CI/CD:
pytest tests/test_accessibility.py::test_color_contrast
"""

import math
import sys
from pathlib import Path
from typing import Dict, Tuple

# 添加项目根目录到Python路径
sys.path.insert(0, str(Path(__file__).parent.parent))

from app.design_tokens import DesignTokens


def hex_to_rgb(hex_color: str) -> Tuple[int, int, int]:
    """将十六进制颜色转换为RGB"""
    hex_color = hex_color.lstrip("#")
    return tuple(int(hex_color[i : i + 2], 16) for i in (0, 2, 4))


def relative_luminance(rgb: Tuple[int, int, int]) -> float:
    """
    计算相对亮度 (WCAG公式)
    https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
    """
    r, g, b = [x / 255.0 for x in rgb]

    def adjust(channel):
        if channel <= 0.03928:
            return channel / 12.92
        return math.pow((channel + 0.055) / 1.055, 2.4)

    r, g, b = adjust(r), adjust(g), adjust(b)
    return 0.2126 * r + 0.7152 * g + 0.0722 * b


def contrast_ratio(color1: str, color2: str) -> float:
    """
    计算两个颜色之间的对比度
    https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio

    Returns:
        对比度比值 (1:1 到 21:1)
    """
    lum1 = relative_luminance(hex_to_rgb(color1))
    lum2 = relative_luminance(hex_to_rgb(color2))

    lighter = max(lum1, lum2)
    darker = min(lum1, lum2)

    return (lighter + 0.05) / (darker + 0.05)


def check_wcag_compliance(
    foreground: str, background: str, level: str = "AA", text_size: str = "normal"
) -> Dict[str, any]:
    """
    检查颜色组合是否符合WCAG标准

    Args:
        foreground: 前景色 (文字)
        background: 背景色
        level: WCAG级别 ("AA" 或 "AAA")
        text_size: 文字大小 ("normal" 或 "large")

    Returns:
        {
            "ratio": 对比度,
            "passes": 是否通过,
            "level": 合规级别,
            "recommendation": 建议
        }
    """
    ratio = contrast_ratio(foreground, background)

    # WCAG标准阈值
    thresholds = {
        "AA": {"normal": 4.5, "large": 3.0},
        "AAA": {"normal": 7.0, "large": 4.5},
    }

    required_ratio = thresholds[level][text_size]
    passes = ratio >= required_ratio

    result = {
        "ratio": round(ratio, 2),
        "passes": passes,
        "level": level,
        "required": required_ratio,
        "foreground": foreground,
        "background": background,
    }

    # 生成建议
    if not passes:
        if ratio < required_ratio * 0.8:
            result["recommendation"] = "对比度严重不足,需要更换颜色"
        else:
            result["recommendation"] = "对比度略低,建议微调颜色深浅"
    else:
        if ratio >= thresholds["AAA"][text_size]:
            result["recommendation"] = "优秀！符合WCAG AAA级标准"
        else:
            result["recommendation"] = "符合WCAG AA级标准"

    return result


def validate_design_tokens():
    """验证所有设计token的色彩对比度"""
    results = []

    print("=" * 80)
    print("MeetSpot Design Tokens - WCAG 2.1色彩对比度验证报告")
    print("=" * 80)
    print()

    # 1. 验证品牌色在白色背景上
    print("📊 品牌色 vs 白色背景")
    print("-" * 80)
    white_bg = DesignTokens.BACKGROUND["primary"]

    for color_name, color_value in DesignTokens.BRAND.items():
        if color_name == "gradient":
            continue  # 跳过渐变

        result = check_wcag_compliance(color_value, white_bg, "AA", "normal")
        results.append(result)

        status = "✅ PASS" if result["passes"] else "❌ FAIL"
        print(
            f"{status} | {color_name:20s} | {color_value:10s} | {result['ratio']:5.2f}:1 | {result['recommendation']}"
        )

    print()

    # 2. 验证文字色在白色背景上
    print("📊 文字色 vs 白色背景")
    print("-" * 80)

    for color_name, color_value in DesignTokens.TEXT.items():
        if color_name == "inverse":
            continue  # 跳过反转色

        result = check_wcag_compliance(color_value, white_bg, "AA", "normal")
        results.append(result)

        status = "✅ PASS" if result["passes"] else "❌ FAIL"
        print(
            f"{status} | {color_name:20s} | {color_value:10s} | {result['ratio']:5.2f}:1 | {result['recommendation']}"
        )

    print()

    # 3. 验证场所主题色
    print("📊 场所主题色验证 (主色 vs 白色背景)")
    print("-" * 80)

    for venue_name, theme in DesignTokens.VENUE_THEMES.items():
        if venue_name == "default":
            continue

        # 主色 vs 白色背景 (用于大文字/按钮)
        result = check_wcag_compliance(
            theme["theme_primary"], white_bg, "AA", "large"  # 大文字标准 (3.0:1)
        )
        results.append(result)

        status = "✅ PASS" if result["passes"] else "❌ FAIL"
        print(
            f"{status} | {venue_name:12s} | {theme['theme_primary']:10s} | {result['ratio']:5.2f}:1 | {result['recommendation']}"
        )

        # 深色 vs 浅色背景 (用于卡片内文字)
        result_card = check_wcag_compliance(
            theme["theme_dark"], theme["theme_light"], "AA", "normal"
        )
        results.append(result_card)

        status_card = "✅ PASS" if result_card["passes"] else "❌ FAIL"
        print(
            f"  └─ {status_card} | 卡片文字 | {theme['theme_dark']:10s} on {theme['theme_light']:10s} | {result_card['ratio']:5.2f}:1"
        )

    print()
    print("=" * 80)

    # 统计结果
    total = len(results)
    passed = sum(1 for r in results if r["passes"])
    failed = total - passed

    print(f"验证总数: {total}")
    print(f"✅ 通过: {passed} ({passed/total*100:.1f}%)")
    print(f"❌ 失败: {failed} ({failed/total*100:.1f}%)")
    print("=" * 80)

    # 返回是否全部通过
    return failed == 0


if __name__ == "__main__":
    all_passed = validate_design_tokens()
    sys.exit(0 if all_passed else 1)
