"""
ws_server.py — سرور WebSocket که caption ها را از افزونه‌ی Chrome می‌گیرد.

افزونه (service worker → bridge.js) هر caption را با این پیام می‌فرستد:
    {type:"TRANSCRIPT_UPDATE", sessionId, speaker, text, startedAt, endedAt}
و heartbeat هم:
    {type:"PING", ts}

این فایل را می‌توان مستقل اجرا کرد (فقط WebSocket، برای تست با _smoke_test.py):
    python ws_server.py
ولی در حالت عادی mcp_server.py همین را به‌عنوان background task بالا می‌آورد.
"""

import asyncio
import json
from datetime import datetime

import websockets

from storage import upsert_segment, log

HOST = "127.0.0.1"
PORT = 8765


async def handle_client(websocket):
    peer = getattr(websocket, "remote_address", "?")
    log(f"🔌 افزونه وصل شد: {peer}")
    try:
        async for raw in websocket:
            try:
                data = json.loads(raw)
            except (json.JSONDecodeError, TypeError):
                log(f"⚠️  پیام نامعتبر: {raw!r}")
                continue

            msg_type = data.get("type")

            if msg_type == "PING":
                await websocket.send(json.dumps({"type": "PONG", "ts": data.get("ts")}))
                continue

            if msg_type == "TRANSCRIPT_UPDATE":
                text = (data.get("text") or "").strip()
                if not text:
                    continue
                session_id = data.get("sessionId", "default")
                speaker = data.get("speaker", "Unknown")
                upsert_segment(session_id, speaker, text,
                               data.get("startedAt"), data.get("endedAt"))
                stamp = datetime.now().strftime("%H:%M:%S")
                log(f"[{stamp}] ({session_id[:8]}) {speaker}: {text[:60]}")
                await websocket.send(json.dumps({"type": "ACK", "ok": True}))
                continue

            log(f"❓ نوع ناشناخته: {msg_type}")
    except websockets.ConnectionClosed:
        pass
    finally:
        log(f"❌ افزونه قطع شد: {peer}")


async def run_forever():
    """WebSocket را بالا می‌آورد. اگر پورت اشغال بود (نمونه‌ی دیگری بالاست) graceful رد می‌شود."""
    try:
        async with websockets.serve(handle_client, HOST, PORT):
            log(f"🚀 WebSocket روی ws://{HOST}:{PORT} گوش می‌دهد …")
            await asyncio.Future()
    except OSError as e:
        log(f"⚠️  نتوانست ws://{HOST}:{PORT} را بگیرد ({e}).")
        log("   این نمونه فقط MCP را سرو می‌کند و transcript ها را از روی دیسک می‌خواند.")
        await asyncio.Future()


if __name__ == "__main__":
    try:
        asyncio.run(run_forever())
    except KeyboardInterrupt:
        log("\n👋 خاموش شد.")
