"""
階段 3e + 3f 整合測試。

測試:
  1. 登入後對話介面只有「團隊對話」一個頻道(側欄隱藏)
  2. 發訊息後 Coba 自動加 tag(message_tagged 事件抵達 → tag chip 顯示)
  3. Filter pill 出現對應 tag,點下去能過濾
  4. @庫柏 觸發 RAG → 回應裡能看到 Coba 引用過去訊息語意
"""

import asyncio
import sys
import time
from pathlib import Path

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

from playwright.async_api import async_playwright


HERE = Path(__file__).resolve().parent
PROFILE_DIR = HERE / "profile"
OUT_DIR = HERE / "out"
OUT_DIR.mkdir(exist_ok=True)

BASE_URL = "http://localhost:8000"
ROBERT = {"email": "ssbb30529@gmail.com", "password": "a183b729"}


async def main():
    async with async_playwright() as pw:
        ctx = await pw.chromium.launch_persistent_context(
            user_data_dir=str(PROFILE_DIR / "robert"),
            headless=False,
            args=["--disable-blink-features=AutomationControlled"],
            viewport={"width": 1280, "height": 900},
        )
        results = {"passes": [], "fails": []}

        try:
            page = await ctx.new_page()
            page.set_default_timeout(15000)

            await page.goto(BASE_URL, wait_until="domcontentloaded")
            await page.evaluate("localStorage.clear()")
            await page.reload(wait_until="domcontentloaded")
            await page.wait_for_selector("#login-view", state="visible")
            await page.fill("#email", ROBERT["email"])
            await page.fill("#password", ROBERT["password"])
            await page.click("#login-btn")
            await page.wait_for_selector("#dashboard-view", state="visible")

            await page.click('button.section-tab[data-section="chat"]')
            await asyncio.sleep(0.7)

            # ── TEST 1:側欄應該被隱藏 ──
            sidebar_visible = await page.locator(".chat-sidebar").is_visible()
            if not sidebar_visible:
                results["passes"].append("TEST 1: 側欄隱藏 ✓")
            else:
                results["fails"].append("TEST 1: 側欄還在,應該被 display:none")

            # ── TEST 2:filter bar 存在 + 至少有「全部」pill ──
            await page.wait_for_selector(".chat-filter-pill", timeout=5000)
            pill_count = await page.locator(".chat-filter-pill").count()
            if pill_count >= 1:
                results["passes"].append(f"TEST 2: filter bar 已渲染({pill_count} 個 pill)✓")
            else:
                results["fails"].append("TEST 2: filter bar 沒看到任何 pill")

            # ── TEST 3:發一則「求助」訊息,Coba 應該標成「🆘 求助」 ──
            stamp = int(time.time())
            help_text = f"我 React useEffect 一直噴 warning 怎麼修啊 [test {stamp}]"
            await page.fill("#chat-input", help_text)
            await page.press("#chat-input", "Enter")
            await asyncio.sleep(0.3)

            # 等 message_tagged 事件抵達
            try:
                # 找剛才那則訊息的 tag chip(用內容搜尋)
                msg_locator = page.locator(".chat-message", has_text=str(stamp))
                # 等 tag chip 不再是「分類中...」
                await page.wait_for_function(
                    f"""() => {{
                        const msgs = document.querySelectorAll('.chat-message');
                        for (const m of msgs) {{
                            if (m.innerText.includes('{stamp}')) {{
                                const tags = m.querySelectorAll('.chat-msg-tag:not(.tagging)');
                                return tags.length > 0;
                            }}
                        }}
                        return false;
                    }}""",
                    timeout=15000,
                )
                # 抓 tag 內容
                tags_in_msg = await msg_locator.locator(".chat-msg-tag").all_inner_texts()
                clean_tags = [t.strip() for t in tags_in_msg if t.strip() and "分類中" not in t]
                if any("求助" in t for t in clean_tags):
                    results["passes"].append(f"TEST 3: 求助訊息被標為 {clean_tags} ✓")
                else:
                    results["fails"].append(f"TEST 3: 預期「🆘 求助」,實際 tag = {clean_tags}")
            except Exception as e:
                results["fails"].append(f"TEST 3: 等 tag 出現超時 ({e})")

            # ── TEST 4:filter pill 應該包含「🆘 求助」(因為剛剛標了)──
            await asyncio.sleep(0.3)
            pill_texts = await page.locator(".chat-filter-pill").all_inner_texts()
            help_pill = [p for p in pill_texts if "求助" in p]
            if help_pill:
                results["passes"].append(f"TEST 4: filter bar 出現「{help_pill[0].strip()}」✓")
            else:
                results["fails"].append(f"TEST 4: filter pill 沒「求助」({pill_texts})")

            # ── TEST 5:點「🆘 求助」filter,只看到求助訊息 ──
            try:
                await page.locator(".chat-filter-pill", has_text="求助").click()
                await asyncio.sleep(0.3)
                visible = await page.locator(".chat-message").count()
                if visible >= 1:
                    results["passes"].append(f"TEST 5: 套用「求助」filter 顯示 {visible} 則訊息 ✓")
                else:
                    results["fails"].append(f"TEST 5: filter 後沒訊息")
                # 切回全部
                await page.locator(".chat-filter-pill", has_text="全部").click()
                await asyncio.sleep(0.3)
            except Exception as e:
                results["fails"].append(f"TEST 5: 套用 filter 失敗 ({e})")

            # ── TEST 6:@庫柏 詢問剛才求助的問題 → RAG 應該幫他找回 ──
            stamp2 = int(time.time())
            q_text = f"@庫柏 剛才 React 那個問題你有印象嗎,大概要怎處理? [test {stamp2}]"
            # 紀錄目前 Coba 訊息數,等到 > 這個值才算新回應
            coba_before = await page.locator(".chat-message.coba").count()
            await page.fill("#chat-input", q_text)
            await page.press("#chat-input", "Enter")

            try:
                t0 = time.time()
                await page.wait_for_function(
                    f"""() => document.querySelectorAll('.chat-message.coba').length > {coba_before}""",
                    timeout=30000,
                )
                elapsed = (time.time() - t0) * 1000
                last_coba = page.locator(".chat-message.coba").last
                bubble = await last_coba.locator(".chat-msg-bubble").inner_text()
                results["passes"].append(f"TEST 6: 庫柏在 {elapsed/1000:.1f} 秒內回應(RAG 模式)")
                print(f"\n>>> 庫柏回應內容:\n{bubble}\n")
                # 庫柏的回應應該提到 React 或 useEffect(代表 RAG 撈到剛才訊息)
                lower = bubble.lower()
                if "react" in lower or "useeffect" in lower or "use effect" in lower or "依賴" in bubble or "dependency" in lower or "warning" in lower:
                    results["passes"].append(f"TEST 7: 庫柏回應命中 React/useEffect 上下文 → RAG 有效 ✓")
                else:
                    results["fails"].append(f"TEST 7: 回應沒提 React/useEffect/warning:{bubble[:200]!r}")
            except Exception as e:
                results["fails"].append(f"TEST 6: 庫柏沒回應 ({e})")

            await page.screenshot(path=str(OUT_DIR / "stage_3ef.png"), full_page=False)

        finally:
            await ctx.close()

        print("\n" + "=" * 60)
        print(" Stage 3e + 3f 測試結果")
        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(asyncio.run(main()))
