# app/ws/chat.py

# from fastapi import APIRouter, WebSocket, Depends
# from sqlalchemy.ext.asyncio import AsyncSession
# from app.services.chat import ChatService
# from app.core.database import get_db
# from app.ws.connection_manager import visitor_manager, admin_manager

# router = APIRouter()

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

#     visitor_manager.connect(visitor_uid, websocket)

#     service = ChatService(db)

#     # Create/find visitor
#     visitor = await service.get_or_create_visitor(widget_id, visitor_uid)

#     # Notify admin
#     await admin_manager.broadcast({
#         "type": "client_connected",
#         "visitor_uid": visitor_uid,
#         "widget_id": widget_id
#     })

#     try:
#         while True:
#             data = await websocket.receive_json()

#             # typing
#             if data["type"] == "typing":
#                 await admin_manager.broadcast({ "type": "typing", "visitor_uid": visitor_uid, "text": data["text"] })

#             # message
#             elif data["type"] == "message":
#                 text = data["text"]

#                 await service.save_message(
#                     client_id=visitor.client_id,
#                     visitor_id=visitor.id,
#                     sender="visitor",
#                     text=text
#                 )

#                 await admin_manager.broadcast({
#                     "type": "user_message",
#                     "visitor_uid": visitor_uid,
#                     "text": text
#                 })

#     except:
#         pass
#     finally:
#         visitor_manager.disconnect(visitor_uid)

#         await admin_manager.broadcast({
#             "type": "client_disconnected",
#             "visitor_uid": visitor_uid
#         })

# ---------------------------------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------------------------------

# app/ws/chat.py

# from app.core.database import get_db
# from app.services.chat import ChatService
# from sqlalchemy.ext.asyncio import AsyncSession
# from app.ws.connection_manager import visitor_manager, admin_manager
# from fastapi import APIRouter, WebSocket, Depends, WebSocketDisconnect

# router = APIRouter()


# @router.websocket("/ws/client/{widget_id}/{visitor_uid}")
# async def client_ws(
#     websocket: WebSocket,
#     widget_id: str,
#     visitor_uid: str,
#     db: AsyncSession = Depends(get_db),
# ):
#     """
#     WebSocket used by the widget on client websites.

#     URL shape:
#       ws://localhost:8000/ws/client/{widget_id}/{visitor_uid}

#     - widget_id = client_widget_id (like XRG-4b429ac6)
#     - visitor_uid = browser UUID stored in localStorage
#     """
#     await websocket.accept()
#     service = ChatService(db)
#     print("1111111111111111111",service)
#     # 1) Find or create Visitor row
#     try:
#         print("------------------------------------", widget_id , visitor_uid)
#         visitor = await service.get_or_create_visitor(widget_id, visitor_uid)
#         print("2222222222222222222222222")
#     except Exception as e:
#         # Invalid widget id or DB error -> close WS
#         await websocket.close(code=1008)
#         return

#     # 2) Register in connection manager
#     visitor_manager.connect(visitor_uid, websocket)
#     print("333333333333333333333333")

#     # 3) Notify all admins that this visitor is online
#     await admin_manager.broadcast(
#         {
#             "type": "client_connected",
#             "from": visitor_uid,          # used as key in admin UI
#             "widget_id": widget_id,
#             "client_id": visitor.client_id,
#             # You can add more info later (city, region, etc.)
#             "info": {
#                 "city": getattr(visitor, "city", None),
#                 "region": getattr(visitor, "region", None),
#                 "country": getattr(visitor, "country", None),
#             },
#         }
#     )
#     print("-----------------4444444444444444-----------------")

#     try:
#         while True:
#             data = await websocket.receive_json()
#             print("data------------------------------------",data)
#             msg_type = data.get("type")
#             print("msg_type",msg_type)
#             print("5555555555555555555555555555555")

#             # -------------------------
#             # Visitor typing
#             # -------------------------
#             if msg_type == "typing":
#                 print("66666666666666666666666666666")
                
#                 text = data.get("text", "")
#                 print("text -->",text)
                
#                 is_typing = data.get("isTyping", bool(text))

#                 print("77777777777777777777777777777777")
#                 await admin_manager.broadcast(
#                     {
#                         "type": "typing",
#                         "from": visitor_uid,
#                         "text": text,
#                         "isTyping": is_typing,
#                     }
#                 )

#             # -------------------------
#             # Visitor sends a message
#             # -------------------------
#             elif msg_type == "message":

#                 print("888888888888888888888888888888888")

#                 text = (data.get("text") or "").strip()
#                 if not text:
#                     continue

#                 print("99999999999999999999999999999999")
#                 print("text",text)
                
#                 # print("visitor.client_id",visitor.client_id)
#                 # print("visitor.id",visitor.id)
                
#                 # Save to DB
#                 await service.save_message(
#                     client_id=visitor.client_id,
#                     visitor_id=visitor.id,
#                     sender="visitor",
#                     text=text,
#                 )

#                 print("101010101010101010101010101010")
#                 # Send to all admins
#                 await admin_manager.broadcast(
#                     {
#                         "type": "user_message",
#                         "from": visitor_uid,
#                         "text": text,
#                     }
#                 )
#                 print(">->->->->->->->->->->->->->->->->->")

#     except WebSocketDisconnect:
#         # normal disconnect
#         print(">>>>>>>>>>>>>>>> WebSocketDisconnect")
#         pass
#     except Exception as e:
#         # you can log this if you want
#         print(">>>>>>>>>>>>>>>> Exception",e)
#         pass
#     finally:
#         # Remove from connection map
#         visitor_manager.disconnect(visitor_uid)

#         # Notify admins that visitor left
#         await admin_manager.broadcast(
#             {
#                 "type": "client_disconnected",
#                 "from": visitor_uid,
#             }
#         )


# ---------------------------------------------------------------------------

# app/ws/chat.py

from app.core.database import get_db
from app.services.chat import ChatService
from sqlalchemy.ext.asyncio import AsyncSession
from app.ws.connection_manager import visitor_manager, agent_manager
from fastapi import APIRouter, WebSocket, Depends, WebSocketDisconnect

router = APIRouter()


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

    service = ChatService(db)

    try:
        # create/get visitor
        visitor = await service.get_or_create_visitor(widget_id, visitor_uid)
        if not visitor:
            await websocket.close(code=1008)
            return

        # remember connection
        visitor_manager.connect(visitor_uid, websocket)

        # notify all agents
        await agent_manager.broadcast(
            {
                "type": "visitor_online",
                "visitor_uid": visitor_uid,
                "visitor_db_id": visitor.id,
                "client_id": visitor.client_id,
                "info": {
                    "name": getattr(visitor, "name", None),
                    "ip_address": visitor.ip_address,
                },
            }
        )

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

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

                await agent_manager.broadcast(
                    {
                        "type": "typing",
                        "from_visitor": visitor_uid,
                        "text": text,
                        "isTyping": is_typing,
                    }
                )

            # visitor sends message
            elif msg_type == "message":
                text = (data.get("text") or "").strip()
                if not text:
                    continue

                # save
                await service.save_message(
                    client_id=visitor.client_id,
                    visitor_id=visitor.id,
                    sender="visitor",
                    text=text,
                )

                # send to all agents
                await agent_manager.broadcast(
                    {
                        "type": "visitor_message",
                        "from_visitor": visitor_uid,
                        "text": text,
                    }
                )

    except WebSocketDisconnect:
        pass
    except Exception as e:
        print("WS client exception:", e)
    finally:
        visitor_manager.disconnect(visitor_uid)
        await agent_manager.broadcast(
            {
                "type": "visitor_offline",
                "visitor_uid": visitor_uid,
            }
        )
