"""
階段 4 會議流水線測試。

  1. 用 gTTS 合成一段中文「會議錄音」(關於決定 Q4 預算)
  2. 上傳到 /api/meetings/upload
  3. 等 status=completed(最多 5 分鐘)
  4. 抓 /api/meetings/{id} 看摘要 / 決策 / 待辦
  5. 看頻道是否出現 meeting_summary 訊息
"""

import asyncio
import json
import sys
import time
import urllib.request
from pathlib import Path

try:
    sys.stdout.reconfigure(encoding="utf-8")
except (AttributeError, ValueError):
    pass


HERE = Path(__file__).resolve().parent
OUT_DIR = HERE / "out"
OUT_DIR.mkdir(exist_ok=True)
BASE = "http://127.0.0.1:8000"


def login() -> str:
    req = urllib.request.Request(
        f"{BASE}/api/auth/login",
        data=json.dumps({"email": "ssbb30529@gmail.com", "password": "a183b729"}).encode(),
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    return json.loads(urllib.request.urlopen(req).read())["tokens"]["access_token"]


def synth_meeting_audio() -> Path:
    """用 gTTS 產一段測試會議錄音(若沒裝 gTTS 就 pip install)。"""
    out = OUT_DIR / "fake_meeting.mp3"
    if out.exists() and out.stat().st_size > 5000:
        print(f"重用既有測試音檔:{out}")
        return out
    try:
        from gtts import gTTS
    except ImportError:
        import subprocess
        print("安裝 gTTS...")
        subprocess.check_call([sys.executable, "-m", "pip", "install", "gTTS"])
        from gtts import gTTS

    text = (
        "今天的會議重點。第一,Q4 預算我們決定增加百分之二十,主要投入在新產品的研發。"
        "第二,Robert 你下週四前要把客戶 A 的合約修訂版完成。"
        "第三,我們同意導入新的 CRM 系統,但實際選哪一家還要再評估。"
        "第四,Member Test 麻煩在 11 月 20 號前整理好近三個月的客戶回饋報告。"
        "以上,大家有問題嗎?沒問題會議到此結束。"
    )
    print("用 gTTS 合成會議錄音...")
    tts = gTTS(text=text, lang="zh-tw")
    tts.save(str(out))
    print(f"已產生:{out} ({out.stat().st_size} bytes)")
    return out


def upload_meeting(token: str, audio: Path) -> str:
    """multipart 上傳音訊,回傳 meeting_id。"""
    import requests
    with audio.open("rb") as f:
        res = requests.post(
            f"{BASE}/api/meetings/upload",
            headers={"Authorization": f"Bearer {token}"},
            files={"audio": (audio.name, f, "audio/mpeg")},
            data={"title": "Q4 預算會議(自動測試)"},
            timeout=30,
        )
    res.raise_for_status()
    return res.json()["id"]


def poll_meeting(token: str, mid: str, max_wait_sec: int = 300):
    t0 = time.time()
    last_status = None
    while time.time() - t0 < max_wait_sec:
        req = urllib.request.Request(
            f"{BASE}/api/meetings/{mid}",
            headers={"Authorization": f"Bearer {token}"},
        )
        data = json.loads(urllib.request.urlopen(req).read())
        if data["status"] != last_status:
            print(f"  [{int(time.time()-t0):3d}s] status = {data['status']}")
            last_status = data["status"]
        if data["status"] in ("completed", "failed"):
            return data
        time.sleep(2)
    raise TimeoutError(f"{max_wait_sec} 秒內沒處理完")


def main() -> int:
    results = {"passes": [], "fails": []}
    print("=== 1. 登入 ===")
    token = login()
    print(f"   token: {token[:14]}...")

    print("\n=== 2. 合成會議錄音 ===")
    audio = synth_meeting_audio()

    print("\n=== 3. 上傳到 /api/meetings/upload ===")
    mid = upload_meeting(token, audio)
    print(f"   meeting_id: {mid}")
    results["passes"].append("Upload accepted")

    print("\n=== 4. Poll 等處理完成(最多 5 分鐘)===")
    try:
        final = poll_meeting(token, mid, max_wait_sec=300)
    except TimeoutError as e:
        results["fails"].append(f"Processing timeout: {e}")
        return 1

    if final["status"] != "completed":
        results["fails"].append(f"Final status = {final['status']} (期望 completed):{final.get('error_message')}")
        return 1
    results["passes"].append(f"Status reached completed in ~{int(final.get('audio_duration_seconds') or 0)}s audio")

    if final.get("summary"):
        results["passes"].append(f"Summary: {final['summary']['executive_summary'][:100]}...")
    else:
        results["fails"].append("沒產生 summary")

    if final.get("decisions"):
        results["passes"].append(f"Decisions: {len(final['decisions'])} 條")
        for d in final["decisions"]:
            print(f"   - 決策: {d['decision']}")
    else:
        results["fails"].append("沒抽到決策")

    if final.get("action_items"):
        results["passes"].append(f"Action items: {len(final['action_items'])} 個")
        for a in final["action_items"]:
            print(f"   - 待辦: {a['description']} (assignee={a.get('suggested_assignee_id')}, due={a.get('suggested_due_date')})")
    else:
        results["fails"].append("沒抽到待辦事項")

    print("\n=== 5. 檢查頻道有沒有 meeting_summary 訊息 ===")
    # 抓團隊對話的最新 10 則
    channels_req = urllib.request.Request(
        f"{BASE}/api/channels", headers={"Authorization": f"Bearer {token}"}
    )
    ch = json.loads(urllib.request.urlopen(channels_req).read())[0]
    msgs_req = urllib.request.Request(
        f"{BASE}/api/channels/{ch['id']}/messages?limit=10",
        headers={"Authorization": f"Bearer {token}"},
    )
    msgs = json.loads(urllib.request.urlopen(msgs_req).read())
    has_meeting_msg = any(m.get("message_type") == "meeting_summary" for m in msgs)
    if has_meeting_msg:
        results["passes"].append("頻道出現 meeting_summary 訊息 ✓")
    else:
        results["fails"].append("頻道沒看到 meeting_summary 訊息")

    # ── 5.b 試一鍵轉任務 ──
    if final.get("action_items"):
        first_action = final["action_items"][0]
        print(f"\n=== 6. 把第一個 action item 轉成任務 ===")
        import requests
        r = requests.post(
            f"{BASE}/api/meetings/{mid}/action-items/{first_action['id']}/convert",
            headers={"Authorization": f"Bearer {token}"},
        )
        if r.ok:
            results["passes"].append(f"Action item → task: task_id={r.json()['task_id']}")
        else:
            results["fails"].append(f"轉任務失敗: {r.status_code} {r.text}")

    print("\n" + "=" * 60)
    print(" 階段 4 測試結果")
    print("=" * 60)
    for p in results["passes"]:
        print(f"[PASS] {p}")
    for f in results["fails"]:
        print(f"[FAIL] {f}")
    print("=" * 60)
    return 0 if not results["fails"] else 1


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