#!/usr/bin/env python3
"""
測試人臉識別 API 端點
"""

import requests
import json
import base64
import cv2
import numpy as np
import sys
import os

# API 配置
API_BASE_URL = "http://localhost:3002"
API_KEY = "muser_7ff810b88d6440c6ab31094ecae7dc32_1774870448_54b7c8e9"


def create_headers():
    """創建帶有 API 密鑰的請求頭部"""
    return {"X-API-Key": API_KEY, "Content-Type": "application/json"}


def test_health():
    """測試健康檢查端點"""
    print("測試健康檢查端點...")
    try:
        response = requests.get(f"{API_BASE_URL}/health")
        if response.status_code == 200:
            print(f"✅ 健康檢查通過: {response.json()}")
            return True
        else:
            print(f"❌ 健康檢查失敗: {response.status_code}")
            return False
    except Exception as e:
        print(f"❌ 健康檢查異常: {e}")
        return False


def test_list_faces():
    """測試列出人臉端點"""
    print("\n測試列出人臉端點...")
    try:
        response = requests.get(
            f"{API_BASE_URL}/api/v1/face/list", headers=create_headers()
        )

        if response.status_code == 200:
            data = response.json()
            print(f"✅ 列出人臉成功: 找到 {len(data.get('faces', []))} 個人臉")
            return True
        else:
            print(f"❌ 列出人臉失敗: {response.status_code} - {response.text}")
            return False
    except Exception as e:
        print(f"❌ 列出人臉異常: {e}")
        return False


def test_recognize_faces():
    """測試人臉識別端點"""
    print("\n測試人臉識別端點...")

    # 下載測試圖像
    try:
        import urllib.request

        test_image_url = "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/lena.jpg"
        test_image_path = "/tmp/lena_api_test.jpg"

        if not os.path.exists(test_image_path):
            print("下載測試圖像...")
            urllib.request.urlretrieve(test_image_url, test_image_path)

        # 讀取圖像並轉換為 base64
        image = cv2.imread(test_image_path)
        if image is None:
            print("❌ 無法讀取測試圖像")
            return False

        # 將圖像轉換為 base64
        _, buffer = cv2.imencode(".jpg", image)
        image_base64 = base64.b64encode(buffer).decode("utf-8")

        # 準備請求數據
        request_data = {
            "image": image_base64,
            "image_format": "jpg",
            "threshold": 0.6,
            "max_faces": 10,
        }

        response = requests.post(
            f"{API_BASE_URL}/api/v1/face/recognize",
            headers=create_headers(),
            json=request_data,
        )

        if response.status_code == 200:
            data = response.json()
            faces = data.get("faces", [])
            print(f"✅ 人臉識別成功: 檢測到 {len(faces)} 個人臉")

            if len(faces) > 0:
                for i, face in enumerate(faces):
                    print(f"  人臉 {i + 1}:")
                    print(
                        f"    - 位置: x={face.get('x')}, y={face.get('y')}, width={face.get('width')}, height={face.get('height')}"
                    )
                    print(f"    - 置信度: {face.get('confidence', 0):.4f}")
                    if "identity" in face and face["identity"]:
                        print(f"    - 身份: {face['identity']}")

            return True
        else:
            print(f"❌ 人臉識別失敗: {response.status_code} - {response.text}")
            return False

    except Exception as e:
        print(f"❌ 人臉識別異常: {e}")
        import traceback

        traceback.print_exc()
        return False


def test_search_faces():
    """測試人臉搜索端點"""
    print("\n測試人臉搜索端點...")

    # 創建一個測試向量
    test_vector = [0.1] * 512  # 512 維向量

    request_data = {"vector": test_vector, "threshold": 0.5, "limit": 5}

    try:
        response = requests.post(
            f"{API_BASE_URL}/api/v1/face/search",
            headers=create_headers(),
            json=request_data,
        )

        if response.status_code == 200:
            data = response.json()
            matches = data.get("matches", [])
            print(f"✅ 人臉搜索成功: 找到 {len(matches)} 個匹配")
            return True
        else:
            print(f"❌ 人臉搜索失敗: {response.status_code} - {response.text}")
            return False
    except Exception as e:
        print(f"❌ 人臉搜索異常: {e}")
        return False


def test_video_list():
    """測試視頻列表端點"""
    print("\n測試視頻列表端點...")
    try:
        response = requests.get(
            f"{API_BASE_URL}/api/v1/videos", headers=create_headers()
        )

        if response.status_code == 200:
            data = response.json()
            videos = data.get("videos", [])
            print(f"✅ 視頻列表成功: 找到 {len(videos)} 個視頻")

            if len(videos) > 0:
                for i, video in enumerate(videos[:2]):  # 只顯示前兩個
                    print(
                        f"  視頻 {i + 1}: {video.get('file_name')} (UUID: {video.get('uuid')})"
                    )

            return True
        else:
            print(f"❌ 視頻列表失敗: {response.status_code} - {response.text}")
            return False
    except Exception as e:
        print(f"❌ 視頻列表異常: {e}")
        return False


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

    tests = [
        ("健康檢查", test_health),
        ("視頻列表", test_video_list),
        ("列出人臉", test_list_faces),
        ("人臉識別", test_recognize_faces),
        ("人臉搜索", test_search_faces),
    ]

    results = []

    for test_name, test_func in tests:
        print(f"\n{test_name}:")
        print("-" * 40)
        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🎉 所有 API 測試通過！")
    else:
        print(f"\n⚠️  有 {len(results) - passed} 個測試失敗")

    return passed == len(results)


if __name__ == "__main__":
    success = main()
    sys.exit(0 if success else 1)
