# app/ws/visitor.py

from sqlalchemy import select
from app.core.database import get_db
from app.models.client import Client
from app.models.visitor import Visitor
from app.models.message import Message
from app.services.chat import ChatService
from sqlalchemy.ext.asyncio import AsyncSession
from app.ws.connection_manager import visitor_manager, agent_manager,admin_manager
from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Depends

router = APIRouter()

@router.websocket("/ws/visitor/{visitor_uid}")
async def visitor_ws(
    websocket: WebSocket,
    visitor_uid: str,
    db: AsyncSession = Depends(get_db),
):
    await websocket.accept()

    # store WS
    visitor_manager.connect(visitor_uid, websocket)
    print(f"Visitor connected: {visitor_uid}")

    # fetch visitor + client
    res = await db.execute(
        select(Visitor, Client)
        .join(Client, Visitor.client_id == Client.id)
        .where(Visitor.visitor_id == visitor_uid)
    )
    row = res.first()
    visitor = client = None
    if row:
        visitor, client = row

        payload = {
            "type": "visitor_connected",
            "visitor_uid": visitor.visitor_id,
            "name": visitor.name,
            "city": visitor.city,
            "country": visitor.country,
            "region": visitor.region,
            "ip_address": visitor.ip_address,
            "client_id": visitor.client_id,
            "client_name": client.client_name if client else None,
            "assigned_agent_id": None,  # will be updated by assignment
        }

        # notify all agents & admins
        await agent_manager.broadcast(payload)
        await admin_manager.broadcast(payload)

    try:
        while True:
            data = await websocket.receive_json()
            msg_type = data.get("type")
            text = data.get("text", "")

            # -------------------------
            # VISITOR TYPING
            # -------------------------
            if msg_type == "typing":
                is_typing = data.get("isTyping", bool(text))

                payload = {
                    "type": "typing",
                    "from": "visitor",
                    "visitor_uid": visitor_uid,
                    "text": text,
                    "isTyping": is_typing,
                }

                await agent_manager.broadcast(payload)
                await admin_manager.broadcast(payload)
            
            # -------------------------
            # VISITOR MESSAGE
            # -------------------------
            elif msg_type == "message":
                msg_text = (text or "").strip()
                if not msg_text or not visitor:
                    continue

                chat_service = ChatService(db)
                await chat_service.save_message(
                    client_id=visitor.client_id,
                    visitor_id=visitor.id,
                    sender="visitor",
                    text=msg_text,
                )

                payload = {
                    "type": "visitor_message",
                    "visitor_uid": visitor_uid,
                    "text": msg_text,
                }

                await agent_manager.broadcast(payload)
                await admin_manager.broadcast(payload)

    except WebSocketDisconnect:
        print("Visitor disconnected:", visitor_uid)

    finally:
        visitor_manager.disconnect(visitor_uid)

        payload = {
            "type": "visitor_disconnected",
            "visitor_uid": visitor_uid,
        }
        await agent_manager.broadcast(payload)
        await admin_manager.broadcast(payload)


