#!/usr/bin/env python3
"""
測試人臉識別完整集成流程
"""

import os
import sys
import json
import numpy as np
from pathlib import Path

# 添加項目根目錄到 Python 路徑
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# 測試數據庫連接
try:
    import psycopg2
    from psycopg2.extras import Json

    print("✅ psycopg2 已安裝")
except ImportError:
    print("❌ psycopg2 未安裝，請運行: pip install psycopg2-binary")
    sys.exit(1)

# 測試 InsightFace
try:
    import insightface

    print("✅ insightface 已安裝")
except ImportError:
    print("❌ insightface 未安裝，請運行: pip install insightface")
    sys.exit(1)

# 測試 ONNX Runtime
try:
    import onnxruntime as ort

    print("✅ onnxruntime 已安裝")

    # 檢查可用的執行提供者
    available_providers = ort.get_available_providers()
    print(f"✅ 可用的執行提供者: {available_providers}")

    # 檢查 MPS 支援
    if "CoreMLExecutionProvider" in available_providers:
        print("✅ CoreML (MPS) 支援可用")
    elif "CUDAExecutionProvider" in available_providers:
        print("✅ CUDA 支援可用")
    else:
        print("⚠️  僅 CPU 支援可用")

except ImportError:
    print("❌ onnxruntime 未安裝，請運行: pip install onnxruntime")
    sys.exit(1)


def test_database_connection():
    """測試數據庫連接"""
    print("\n=== 測試數據庫連接 ===")
    try:
        conn = psycopg2.connect(
            host="localhost",
            port=5432,
            database="momentry",
            user="accusys",
            password="accusys",
        )

        cursor = conn.cursor()

        # 檢查表是否存在
        cursor.execute("""
            SELECT table_name 
            FROM information_schema.tables 
            WHERE table_schema = 'public' 
            AND table_name LIKE 'face_%'
            ORDER BY table_name;
        """)

        tables = cursor.fetchall()
        print(f"✅ 找到 {len(tables)} 個人臉相關表:")
        for table in tables:
            print(f"  - {table[0]}")

        # 檢查函數是否存在
        cursor.execute("""
            SELECT proname 
            FROM pg_proc 
            WHERE proname LIKE '%face%' 
            ORDER BY proname;
        """)

        functions = cursor.fetchall()
        print(f"✅ 找到 {len(functions)} 個人臉相關函數:")
        for func in functions:
            print(f"  - {func[0]}")

        # 測試插入和查詢
        cursor.execute("""
            SELECT find_or_create_face_identity(
                'integration_test_001',
                'Integration Test Person',
                NULL,
                '{"age": 25, "gender": "female", "test": true}'::jsonb,
                '{"source": "integration_test"}'::jsonb
            ) AS identity_id;
        """)

        identity_id = cursor.fetchone()[0]
        print(f"✅ 成功創建人臉身份，ID: {identity_id}")

        # 檢查插入的數據
        cursor.execute("""
            SELECT id, face_id, name, attributes->>'gender' as gender, 
                   attributes->>'age' as age, attributes->>'test' as test
            FROM face_identities 
            WHERE face_id = 'integration_test_001';
        """)

        result = cursor.fetchone()
        print(
            f"✅ 查詢結果: ID={result[0]}, FaceID={result[1]}, Name={result[2]}, Gender={result[3]}, Age={result[4]}, Test={result[5]}"
        )

        # 清理測試數據
        cursor.execute(
            "DELETE FROM face_identities WHERE face_id = 'integration_test_001';"
        )
        conn.commit()
        print("✅ 清理測試數據完成")

        cursor.close()
        conn.close()

        return True

    except Exception as e:
        print(f"❌ 數據庫連接測試失敗: {e}")
        return False


def test_insightface_model():
    """測試 InsightFace 模型"""
    print("\n=== 測試 InsightFace 模型 ===")

    try:
        # 創建測試圖像（隨機數據）
        test_image = np.random.randint(0, 255, (640, 480, 3), dtype=np.uint8)
        print(f"✅ 創建測試圖像: {test_image.shape}")

        # 初始化模型
        print("正在初始化 InsightFace 模型...")
        model = insightface.app.FaceAnalysis(name="buffalo_l")
        model.prepare(ctx_id=-1)  # -1 表示 CPU

        print("✅ InsightFace 模型初始化成功")

        # 測試模型推理（使用隨機圖像）
        print("正在進行模型推理測試...")
        faces = model.get(test_image)
        print(f"✅ 模型推理完成，檢測到 {len(faces)} 個人臉")

        if len(faces) > 0:
            face = faces[0]
            print(f"✅ 人臉屬性:")
            print(f"  - 邊界框: {face.bbox}")
            print(f"  - 置信度: {face.det_score:.4f}")
            print(
                f"  - 嵌入向量維度: {face.embedding.shape if hasattr(face, 'embedding') else 'N/A'}"
            )

            if hasattr(face, "age"):
                print(f"  - 年齡: {face.age}")
            if hasattr(face, "gender"):
                print(f"  - 性別: {face.gender}")
            if hasattr(face, "pose"):
                print(f"  - 姿態: {face.pose}")

        return True

    except Exception as e:
        print(f"❌ InsightFace 模型測試失敗: {e}")
        return False


def test_face_processor():
    """測試人臉處理器"""
    print("\n=== 測試人臉處理器 ===")

    try:
        # 導入處理器
        from scripts.face_recognition_processor import FaceRecognitionProcessor

        # 初始化處理器
        print("正在初始化人臉識別處理器...")
        processor = FaceRecognitionProcessor()

        # 加載模型（不使用 MPS）
        print("正在加載模型...")
        processor.load_models(use_mps=False)

        print(f"✅ 處理器初始化成功")
        print(f"  - 啟用識別: {processor.enable_recognition}")
        print(f"  - 啟用追蹤: {processor.enable_tracking}")
        print(f"  - 啟用聚類: {processor.enable_clustering}")

        # 創建測試視頻數據
        test_video_data = {
            "video_path": "/tmp/test_video.mp4",  # 虛擬路徑
            "video_uuid": "test_video_001",
            "frame_count": 100,
            "fps": 30.0,
        }

        print(f"✅ 創建測試視頻數據: {test_video_data['video_uuid']}")

        # 測試處理器方法
        print("測試處理器方法...")

        # 測試人臉檢測
        test_image = np.random.randint(0, 255, (640, 480, 3), dtype=np.uint8)
        detections = processor.detect_faces(test_image)
        print(f"✅ 人臉檢測測試完成，檢測到 {len(detections)} 個人臉")

        if len(detections) > 0:
            detection = detections[0]
            print(f"✅ 檢測結果示例:")
            print(
                f"  - 位置: x={detection['x']}, y={detection['y']}, width={detection['width']}, height={detection['height']}"
            )
            print(f"  - 置信度: {detection['confidence']:.4f}")
            if "embedding" in detection and detection["embedding"] is not None:
                embedding = detection["embedding"]
                if hasattr(embedding, "shape"):
                    print(f"  - 嵌入向量: {embedding.shape}")
                else:
                    print(f"  - 嵌入向量長度: {len(embedding)}")
            else:
                print(f"  - 嵌入向量: N/A")

        return True

    except Exception as e:
        print(f"❌ 人臉處理器測試失敗: {e}")
        import traceback

        traceback.print_exc()
        return False


def test_api_endpoints():
    """測試 API 端點配置"""
    print("\n=== 測試 API 端點配置 ===")

    try:
        # 檢查 Rust 代碼編譯
        print("檢查 Rust 代碼編譯狀態...")

        # 讀取 API 代碼
        api_file = os.path.join(
            os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
            "src",
            "api",
            "face_recognition.rs",
        )

        if os.path.exists(api_file):
            with open(api_file, "r") as f:
                content = f.read()

            # 檢查關鍵函數是否存在（根據實際代碼）
            endpoints = [
                "register_face_api",
                "recognize_faces",
                "search_faces",
                "get_face_details",
                "list_faces",
                "delete_face",
                "get_recognition_results",
                "store_recognition_results",
            ]

            found_endpoints = []
            for endpoint in endpoints:
                if endpoint in content:
                    found_endpoints.append(endpoint)

            print(f"✅ 找到 {len(found_endpoints)}/{len(endpoints)} 個 API 端點:")
            for endpoint in found_endpoints:
                print(f"  - {endpoint}")

            if len(found_endpoints) == len(endpoints):
                print("✅ 所有 API 端點都已定義")
            else:
                missing = set(endpoints) - set(found_endpoints)
                print(f"⚠️  缺少端點: {missing}")

        # 檢查路由配置
        server_file = os.path.join(
            os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
            "src",
            "api",
            "server.rs",
        )

        if os.path.exists(server_file):
            with open(server_file, "r") as f:
                content = f.read()

            if "face_recognition" in content and "merge" in content:
                print("✅ API 路由已正確配置")
            else:
                print("⚠️  API 路由配置可能不完整")

        return True

    except Exception as e:
        print(f"❌ API 端點測試失敗: {e}")
        return False


def main():
    """主測試函數"""
    print("=" * 60)
    print("人臉識別集成測試")
    print("=" * 60)

    tests = [
        ("數據庫連接", test_database_connection),
        ("InsightFace 模型", test_insightface_model),
        ("人臉處理器", test_face_processor),
        ("API 端點配置", test_api_endpoints),
    ]

    results = []

    for test_name, test_func in tests:
        try:
            success = test_func()
            results.append((test_name, success))
        except Exception as e:
            print(f"❌ {test_name} 測試異常: {e}")
            results.append((test_name, False))

    print("\n" + "=" * 60)
    print("測試結果摘要")
    print("=" * 60)

    passed = 0
    for test_name, success in results:
        status = "✅ 通過" if success else "❌ 失敗"
        print(f"{test_name}: {status}")
        if success:
            passed += 1

    print(f"\n總計: {passed}/{len(results)} 個測試通過")

    if passed == len(results):
        print("\n🎉 所有測試通過！人臉識別集成準備就緒。")
        return 0
    else:
        print(f"\n⚠️  有 {len(results) - passed} 個測試失敗，請檢查問題。")
        return 1


if __name__ == "__main__":
    sys.exit(main())
