#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
模块名称：test_claude_enhanced_locate.py
模块描述：Claude 语义增强智能定位集成测试脚本

作者：czj
创建日期：2026-08-06
最后修改：2026-08-06
"""

import sys
import os
import json
import logging

# 添加项目路径
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# 设置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)


def test_claude_service_directly():
    """测试 Claude 服务直接调用"""
    from app.services.claude_service import ClaudeService

    print("=" * 60)
    print("测试1: Claude 服务直接调用")
    print("=" * 60)

    test_candidates = [
        {
            'index': 0,
            'tag': 'DIV',
            'text': '会议预约',
            'selector': 'div:has-text("会议预约")',
            'attributes': {},
            'position': {}
        },
        {
            'index': 1,
            'tag': 'BUTTON',
            'text': '新建会议',
            'selector': 'button:has-text("新建会议")',
            'attributes': {'type': 'button'},
            'position': {}
        },
        {
            'index': 2,
            'tag': 'INPUT',
            'text': '',
            'selector': 'input[placeholder]',
            'attributes': {'type': 'text', 'placeholder': '请输入会议名称'},
            'position': {}
        }
    ]

    service = ClaudeService()

    # 测试1: 点击按钮
    print("\n--- 场景1: 点击新建会议按钮 ---")
    try:
        idx, conf, reason = service.rank_candidates(
            step_name='点击新建会议按钮',
            action='click',
            params={},
            candidates=test_candidates
        )
        expected = 1  # 应该选择 BUTTON
        status = "[OK]" if idx == expected else "[FAIL]"
        print(f"{status} 结果: index={idx} (期望{expected}), confidence={conf:.2f}")
        print(f"   理由: {reason}")
        print(f"   选择器: {test_candidates[idx]['selector']}")
    except Exception as e:
        print(f"[FAIL] 失败: {e}")

    # 测试2: 输入会议名称
    print("\n--- 场景2: 会议名称输入：自动化测试 ---")
    try:
        idx, conf, reason = service.rank_candidates(
            step_name='会议名称输入：自动化测试',
            action='fill',
            params={'value': '自动化测试'},
            candidates=test_candidates
        )
        expected = 2  # 应该选择 INPUT
        status = "[OK]" if idx == expected else "[FAIL]"
        print(f"{status} 结果: index={idx} (期望{expected}), confidence={conf:.2f}")
        print(f"   理由: {reason}")
        print(f"   选择器: {test_candidates[idx]['selector']}")
    except Exception as e:
        print(f"[FAIL] 失败: {e}")

    # 测试3: 点击菜单
    print("\n--- 场景3: 点击会议预约分类 ---")
    try:
        idx, conf, reason = service.rank_candidates(
            step_name='点击会议预约分类',
            action='click',
            params={},
            candidates=test_candidates
        )
        expected = 0  # 应该选择 DIV "会议预约"
        status = "[OK]" if idx == expected else "[FAIL]"
        print(f"{status} 结果: index={idx} (期望{expected}), confidence={conf:.2f}")
        print(f"   理由: {reason}")
        print(f"   选择器: {test_candidates[idx]['selector']}")
    except Exception as e:
        print(f"[FAIL] 失败: {e}")


def test_claude_service_fallback():
    """测试 Claude 服务回退机制"""
    from app.services.claude_service import ClaudeService

    print("\n" + "=" * 60)
    print("测试2: Claude 服务回退机制")
    print("=" * 60)

    service = ClaudeService()
    service.enabled = False  # 禁用 Claude

    test_candidates = [
        {'index': 0, 'tag': 'DIV', 'text': '会议预约', 'selector': 'div', 'attributes': {}, 'position': {}},
        {'index': 1, 'tag': 'BUTTON', 'text': '新建会议', 'selector': 'button', 'attributes': {}, 'position': {}}
    ]

    # 多候选回退
    print("\n--- 场景1: 多候选回退（Claude 禁用）---")
    try:
        idx, conf, reason = service.rank_candidates(
            step_name='点击新建会议按钮',
            action='click',
            params={},
            candidates=test_candidates
        )
        print(f"[OK] 回退成功: index={idx}, confidence={conf:.2f}, reason={reason}")
    except Exception as e:
        print(f"[FAIL] 失败: {e}")

    # 单候选
    print("\n--- 场景2: 单候选（不调用 Claude）---")
    try:
        idx, conf, reason = service.rank_candidates(
            step_name='点击按钮',
            action='click',
            params={},
            candidates=[test_candidates[1]]
        )
        print(f"✅ 单候选: index={idx}, confidence={conf:.2f}, reason={reason}")
    except Exception as e:
        print(f"[FAIL] 失败: {e}")


def test_keyword_matcher_candidates():
    """测试关键词匹配返回候选列表"""
    from app.services.keyword_matcher import extract_keywords, get_candidate_details

    print("\n" + "=" * 60)
    print("测试3: 关键词匹配候选列表")
    print("=" * 60)

    # 测试关键词提取
    test_cases = [
        ("点击新建会议按钮", "click"),
        ("会议名称输入：自动化测试", "fill"),
        ("会议室选择：北京展厅会议室", "click"),
        ("等待页面加载", "wait"),
    ]

    for desc, action in test_cases:
        keywords = extract_keywords(desc)
        print(f"\n步骤: {desc}")
        print(f"  关键词: {keywords}")
        print(f"  动作: {action}")

    # 测试 get_candidate_details
    print("\n--- get_candidate_details 空列表测试 ---")
    details = get_candidate_details(None, [])
    print(f"空列表结果: {details}")


def test_smart_locate_api():
    """测试智能定位 API"""
    import requests

    print("\n" + "=" * 60)
    print("测试4: 智能定位 API（需要后端服务运行）")
    print("=" * 60)

    base_url = "http://localhost:8001"

    # 健康检查
    try:
        resp = requests.get(f"{base_url}/api/element/health", timeout=5)
        if resp.status_code == 200:
            print(f"✅ 健康检查通过")
        else:
            print(f"❌ 健康检查失败: {resp.status_code}")
            return
    except Exception as e:
        print(f"⚠️ 后端服务未启动，跳过 API 测试: {e}")
        return

    # 测试智能定位（不启用 Claude，快速测试）
    print("\n--- 测试智能定位（use_claude=false）---")
    try:
        payload = {
            "steps": [
                {"order": 1, "name": "等待页面加载", "action": "wait", "params": {}},
            ],
            "auto_login": False,
            "navigate_menu": "",
            "use_claude": False
        }
        resp = requests.post(f"{base_url}/api/element/smart-locate", json=payload, timeout=120)
        result = resp.json()
        print(f"状态码: {resp.status_code}")
        print(f"结果: 成功 {result.get('located_steps', 0)}/{result.get('total_steps', 0)} 步骤")
    except Exception as e:
        print(f"❌ API 测试失败: {e}")


def main():
    """主测试入口"""
    print("╔══════════════════════════════════════════════════════════╗")
    print("║     Claude 语义增强智能定位 - 集成测试                   ║")
    print("╚══════════════════════════════════════════════════════════╝")
    print()

    # 测试1: Claude 服务直接调用
    test_claude_service_directly()

    # 测试2: 回退机制
    test_claude_service_fallback()

    # 测试3: 关键词匹配候选列表
    test_keyword_matcher_candidates()

    # 测试4: 智能定位 API
    test_smart_locate_api()

    print("\n" + "=" * 60)
    print("测试完成!")
    print("=" * 60)


if __name__ == "__main__":
    main()
