"""HTTP Adapter for Zalo Bridge Service.
Encapsulates all external network calls to the Node.js Fastify Zalo Bridge.
"""

from __future__ import annotations

import asyncio
import logging
from typing import Any

import httpx

from app.modules.zalo_crm.domain.ports.zalo_gateway_port import ZaloGatewayPort

logger = logging.getLogger("dscons.zalo_http_adapter")


class ZaloHttpAdapter(ZaloGatewayPort):
    """Outbound secondary adapter connecting to Zalo Bridge via HTTP."""

    def __init__(self, bridge_base_url: str = "http://127.0.0.1:3081") -> None:
        self.bridge_base_url = bridge_base_url.rstrip("/")

    async def send_message(
        self, target_id: str, message: str, is_group: bool = False
    ) -> dict[str, Any]:
        """Send message via Node.js Fastify Zalo Bridge."""
        url = f"{self.bridge_base_url}/api/send-message"
        payload = {"userId": target_id, "message": message, "isGroup": is_group}
        try:
            async with httpx.AsyncClient() as client:
                response = await client.post(url, json=payload, timeout=10.0)
                if response.status_code == 200:
                    return response.json()
                return {
                    "success": False,
                    "error": f"Bridge returned status {response.status_code}: {response.text}",
                }
        except Exception as exc:
            logger.error(f"Error sending Zalo reply to bridge: {exc}")
            return {"success": False, "error": str(exc)}

    async def get_qr(self) -> dict[str, Any]:
        """Proxy QR Code fetch to Node.js Zalo Bridge."""
        url = f"{self.bridge_base_url}/api/qr"
        try:
            async with httpx.AsyncClient() as client:
                response = await client.get(url, timeout=10.0)
                return response.json()
        except Exception as exc:
            logger.warning(f"Error fetching Zalo QR: {exc}")
            return {"error": str(exc)}

    async def get_status(self) -> dict[str, Any]:
        """Proxy status check to Node.js Zalo Bridge."""
        url = f"{self.bridge_base_url}/api/status"
        try:
            async with httpx.AsyncClient() as client:
                response = await client.get(url, timeout=5.0)
                return response.json()
        except Exception as exc:
            logger.debug(f"Error checking Zalo status: {exc}")
            return {"loggedIn": False, "error": str(exc)}

    async def get_friends_and_groups(
        self,
    ) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]:
        """Fetch friends and group lists from Zalo Bridge concurrently."""
        friends_url = f"{self.bridge_base_url}/api/friends"
        groups_url = f"{self.bridge_base_url}/api/groups"

        try:
            async with httpx.AsyncClient() as client:
                friends_resp, groups_resp = await asyncio.gather(
                    client.get(friends_url, timeout=10.0),
                    client.get(groups_url, timeout=10.0),
                    return_exceptions=True,
                )

                friends: list[dict[str, Any]] = []
                if (
                    not isinstance(friends_resp, Exception)
                    and hasattr(friends_resp, "status_code")
                    and friends_resp.status_code == 200
                ):
                    friends = friends_resp.json().get("friends", [])

                groups: list[dict[str, Any]] = []
                if (
                    not isinstance(groups_resp, Exception)
                    and hasattr(groups_resp, "status_code")
                    and groups_resp.status_code == 200
                ):
                    groups = groups_resp.json().get("groups", [])

                return friends, groups
        except Exception as exc:
            logger.error(f"Error fetching friends and groups: {exc}")
            return [], []
