"""
台灣停車場 API 測試腳本
測試多個來源的停車場即時資訊 API

資料來源：
1. 台北市開放資料平台 (data.taipei) - 免認證
2. TDX 運輸資料平台 - 需認證

使用方式：python -X utf8 test_tdx_api.py
"""

import sys
sys.stdout.reconfigure(encoding='utf-8')

import requests
import json
from datetime import datetime

# ============================================================
# 台北市開放資料平台 API（免認證）
# ============================================================

# 台北市停車場資料 API 端點
TAIPEI_PARKING_STATIC = "https://tcgbusfs.blob.core.windows.net/blobtcmsv/TCMSV_alldesc.json"
TAIPEI_PARKING_DYNAMIC = "https://tcgbusfs.blob.core.windows.net/blobtcmsv/TCMSV_allavailable.json"


def get_taipei_parking_static() -> dict:
    """取得台北市停車場靜態資料（基本資訊）"""
    response = requests.get(TAIPEI_PARKING_STATIC)
    response.raise_for_status()
    return response.json()


def get_taipei_parking_dynamic() -> dict:
    """取得台北市停車場動態資料（即時車位）"""
    response = requests.get(TAIPEI_PARKING_DYNAMIC)
    response.raise_for_status()
    return response.json()


# ============================================================
# TDX API（需認證）
# ============================================================

TDX_AUTH_URL = "https://tdx.transportdata.tw/auth/realms/TDXConnect/protocol/openid-connect/token"
TDX_API_BASE = "https://tdx.transportdata.tw/api/basic"

CITY_CODES = {
    "台北市": "Taipei",
    "新北市": "NewTaipei",
    "桃園市": "Taoyuan",
    "台中市": "Taichung",
    "台南市": "Tainan",
    "高雄市": "Kaohsiung",
}


def get_tdx_token(client_id: str, client_secret: str) -> str:
    """取得 TDX Access Token"""
    data = {
        "grant_type": "client_credentials",
        "client_id": client_id,
        "client_secret": client_secret
    }
    response = requests.post(TDX_AUTH_URL, data=data)
    response.raise_for_status()
    return response.json()["access_token"]


def get_tdx_parking(city: str, token: str) -> dict:
    """取得 TDX 停車場即時車位資料"""
    url = f"{TDX_API_BASE}/v1/Parking/OffStreet/Availability/City/{city}"
    headers = {
        "Authorization": f"Bearer {token}",
        "Accept-Encoding": "gzip",
        "Accept": "application/json"
    }
    params = {"$top": 20, "$format": "JSON"}
    response = requests.get(url, headers=headers, params=params)
    response.raise_for_status()
    return response.json()


# ============================================================
# 輔助函式
# ============================================================

def print_separator(title: str):
    """印出分隔線"""
    print(f"\n{'='*70}")
    print(f"  {title}")
    print(f"{'='*70}\n")


def format_availability_status(value: int) -> str:
    """格式化車位狀態指標"""
    status_map = {
        -9: "無資料",
        -11: "充裕(>50%)",
        -12: "有限(<50%)",
        -13: "額滿"
    }
    return status_map.get(value, str(value))


# ============================================================
# 主程式
# ============================================================

def main():
    import os

    print_separator("台灣停車場 API 測試")
    print(f"測試時間: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")

    # ========================================
    # 測試 1: 台北市開放資料平台（免認證）
    # ========================================
    print_separator("測試 1: 台北市開放資料平台 - 停車場靜態資料（免認證）")

    try:
        static_data = get_taipei_parking_static()
        parks = static_data.get("data", {}).get("park", [])

        print(f"資料來源: {TAIPEI_PARKING_STATIC}")
        print(f"取得 {len(parks)} 筆停車場資料\n")

        # 顯示前 5 筆
        print(f"{'編號':<8} {'名稱':<25} {'行政區':<8} {'總汽車位':>10}")
        print("-" * 60)

        for park in parks[:5]:
            park_id = park.get("id", "N/A")
            name = park.get("name", "N/A")[:23]
            area = park.get("area", "N/A")
            total_car = park.get("totalcar", 0)
            print(f"{park_id:<8} {name:<25} {area:<8} {total_car:>10}")

        print(f"\n... 共 {len(parks)} 筆資料")

    except Exception as e:
        print(f"錯誤: {e}")

    # ========================================
    # 測試 2: 台北市即時車位資料（免認證）
    # ========================================
    print_separator("測試 2: 台北市開放資料平台 - 即時車位資料（免認證）")

    try:
        dynamic_data = get_taipei_parking_dynamic()
        parks = dynamic_data.get("data", {}).get("park", [])

        print(f"資料來源: {TAIPEI_PARKING_DYNAMIC}")
        print(f"取得 {len(parks)} 筆即時資料\n")

        # 顯示前 10 筆
        print(f"{'編號':<8} {'名稱':<25} {'剩餘汽車位':>12} {'狀態':>12}")
        print("-" * 65)

        for park in parks[:10]:
            park_id = park.get("id", "N/A")
            name = park.get("name", "N/A")[:23]
            available_car = park.get("availablecar", -9)
            available_status = park.get("availablecarstatus", -9)

            # 處理特殊值
            if available_car == -9:
                available_str = "無資料"
            else:
                available_str = str(available_car)

            status_str = format_availability_status(available_status)

            print(f"{park_id:<8} {name:<25} {available_str:>12} {status_str:>12}")

        print(f"\n... 共 {len(parks)} 筆資料")

        # 統計各狀態數量
        print("\n車位狀態統計:")
        status_counts = {}
        for park in parks:
            status = park.get("availablecarstatus", -9)
            status_str = format_availability_status(status)
            status_counts[status_str] = status_counts.get(status_str, 0) + 1

        for status, count in sorted(status_counts.items()):
            print(f"  {status}: {count} 處")

    except Exception as e:
        print(f"錯誤: {e}")

    # ========================================
    # 測試 3: 合併靜態與動態資料
    # ========================================
    print_separator("測試 3: 合併靜態與動態資料 - 計算使用率")

    try:
        static_data = get_taipei_parking_static()
        dynamic_data = get_taipei_parking_dynamic()

        static_parks = {p["id"]: p for p in static_data.get("data", {}).get("park", [])}
        dynamic_parks = {p["id"]: p for p in dynamic_data.get("data", {}).get("park", [])}

        print(f"{'名稱':<25} {'總車位':>8} {'剩餘':>8} {'使用率':>10}")
        print("-" * 60)

        count = 0
        for park_id, dynamic in dynamic_parks.items():
            if park_id not in static_parks:
                continue

            static = static_parks[park_id]
            name = static.get("name", "N/A")[:23]
            total = static.get("totalcar", 0)
            available = dynamic.get("availablecar", -9)

            if total > 0 and available >= 0:
                occupancy = (1 - available / total) * 100
                print(f"{name:<25} {total:>8} {available:>8} {occupancy:>9.1f}%")
                count += 1
                if count >= 15:
                    break

    except Exception as e:
        print(f"錯誤: {e}")

    # ========================================
    # 測試 4: TDX API（需認證）
    # ========================================
    print_separator("測試 4: TDX API（需認證）")

    client_id = os.environ.get("TDX_CLIENT_ID")
    client_secret = os.environ.get("TDX_CLIENT_SECRET")

    if client_id and client_secret:
        try:
            print("正在取得 TDX Token...")
            token = get_tdx_token(client_id, client_secret)
            print("Token 取得成功!\n")

            for city_name, city_code in list(CITY_CODES.items())[:3]:
                try:
                    data = get_tdx_parking(city_code, token)
                    count = len(data.get("ParkingAvailabilities", []))
                    print(f"  {city_name}: {count} 筆資料")
                except Exception as e:
                    print(f"  {city_name}: 錯誤 - {e}")

        except Exception as e:
            print(f"TDX 認證失敗: {e}")
    else:
        print("未設定 TDX 認證資訊，跳過此測試")
        print("\n提示: 若需使用 TDX API，請設定環境變數:")
        print("  set TDX_CLIENT_ID=your_client_id")
        print("  set TDX_CLIENT_SECRET=your_client_secret")
        print("\n註冊網址: https://tdx.transportdata.tw/")

    # ========================================
    # 總結
    # ========================================
    print_separator("測試總結")
    print("可用的免認證 API:")
    print(f"  1. 靜態資料: {TAIPEI_PARKING_STATIC}")
    print(f"  2. 動態資料: {TAIPEI_PARKING_DYNAMIC}")
    print("\n這些 API 可直接用於建立定時收集系統，無需註冊或認證。")


if __name__ == "__main__":
    main()
