import logging
import uuid
from datetime import datetime
from typing import Any

import httpx

from app.core.postgres import PostgresClient
from app.core.settings import get_settings

logger = logging.getLogger("dscons.telegram_bridge")


class TelegramBridge:
    def __init__(self):
        self.settings = get_settings()
        self.bot_token = self.settings.telegram_bot_token
        self.api_url = f"https://api.telegram.org/bot{self.bot_token}"
        self.db_client = PostgresClient()
        self.main_group_id = self.settings.telegram_chat_id or "-1000000000000"
        self.zalo_bridge_url = "http://127.0.0.1:3081/api/send-message"

    async def forward_inbound_message(
        self, sender_name: str, sender_id: str, text: str, is_internal: bool = False
    ):
        """Forward an inbound Zalo message to Telegram group immediately."""
        if not self.bot_token:
            logger.warning("Telegram Bot Token is not configured.")
            return

        icon = (
            "🚨 <b>[VIP GIÁM ĐỐC ZALO]</b>"
            if is_internal
            else "💬 <b>[KHÁCH HÀNG ZALO]</b>"
        )
        msg_text = (
            f"{icon}\n"
            f"👤 <b>Người gửi:</b> {sender_name} (ID: <code>{sender_id}</code>)\n"
            f"📝 <b>Nội dung:</b> {text}\n"
            f"⏱ <b>Thời gian:</b> {datetime.now().strftime('%H:%M:%S %d/%m/%Y')}"
        )

        conv_id = f"conv_company_{sender_id}"
        topic_id = None
        try:
            topic_map = self.db_client.get_telegram_topic_by_conversation(conv_id)
            if topic_map:
                topic_id = topic_map.get("telegram_topic_id")
        except Exception:
            pass

        payload: dict[str, Any] = {
            "chat_id": self.main_group_id,
            "text": msg_text,
            "parse_mode": "HTML",
        }
        if topic_id and str(topic_id).isdigit():
            payload["message_thread_id"] = int(topic_id)

        try:
            async with httpx.AsyncClient() as client:
                resp = await client.post(
                    f"{self.api_url}/sendMessage", json=payload, timeout=10.0
                )
                data = resp.json()
                if not data.get("ok"):
                    # Fallback to general chat if topic sending fails
                    payload.pop("message_thread_id", None)
                    await client.post(
                        f"{self.api_url}/sendMessage", json=payload, timeout=10.0
                    )
        except Exception as e:
            logger.error(f"Error forwarding inbound message to Telegram: {e}")

    async def create_topic(self, conversation_id: str, topic_name: str) -> str | None:
        """Create a forum topic on Telegram group for the given conversation."""
        if not self.bot_token:
            return None
        async with httpx.AsyncClient() as client:
            resp = await client.post(
                f"{self.api_url}/createForumTopic",
                json={"chat_id": self.main_group_id, "name": topic_name},
                timeout=10.0,
            )
            data = resp.json()
            if data.get("ok"):
                topic_id = str(data["result"]["message_thread_id"])
                mapping_data = {
                    "id": str(uuid.uuid4()),
                    "conversation_id": conversation_id,
                    "telegram_topic_id": topic_id,
                    "telegram_group_id": str(self.main_group_id),
                    "created_at": datetime.now(),
                }
                self.db_client.upsert_telegram_topic_map(mapping_data)
                return topic_id
            logger.error(f"Failed to create topic: {data}")
            return None

    async def send_draft_for_approval(
        self, contact_id: str, topic_id: str, draft_text: str
    ):
        """Phase 4: AI sends Draft Message to Telegram with Approve button."""
        if not self.bot_token:
            return None
        keyboard = {
            "inline_keyboard": [
                [
                    {
                        "text": "Duyệt & Gửi Zalo (Approve)",
                        "callback_data": f"approve_{contact_id}",
                    }
                ]
            ]
        }
        async with httpx.AsyncClient() as client:
            resp = await client.post(
                f"{self.api_url}/sendMessage",
                json={
                    "chat_id": self.main_group_id,
                    "message_thread_id": int(topic_id)
                    if str(topic_id).isdigit()
                    else None,
                    "text": f"🤖 <b>[AI SOẠN NHÁP TRẢ LỜI]</b>\n{draft_text}",
                    "parse_mode": "HTML",
                    "reply_markup": keyboard,
                },
                timeout=10.0,
            )
            return resp.json()

    async def process_webhook(self, update: dict[str, Any]):
        """Process incoming webhook from Telegram."""
        if "callback_query" in update:
            cb = update["callback_query"]
            data = cb.get("data", "")
            if data.startswith("approve_"):
                contact_id = data.split("approve_")[1]
                msg_text = (
                    cb.get("message", {})
                    .get("text", "")
                    .replace("🤖 [AI SOẠN NHÁP TRẢ LỜI]\n", "")
                    .replace("AI DRAFT:\n", "")
                )

                # Send to Zalo via Zalo Bridge API
                await self.send_to_zalo(contact_id, msg_text)

                # Answer callback query to acknowledge
                async with httpx.AsyncClient() as client:
                    await client.post(
                        f"{self.api_url}/answerCallbackQuery",
                        json={
                            "callback_query_id": cb["id"],
                            "text": "Đã duyệt và gửi tới Zalo!",
                        },
                        timeout=10.0,
                    )

        elif "message" in update:
            msg = update["message"]
            chat_id = str(msg.get("chat", {}).get("id", ""))

            if chat_id == str(self.main_group_id) and not msg.get("from", {}).get(
                "is_bot"
            ):
                thread_id = str(msg.get("message_thread_id", ""))
                text = msg.get("text")
                if text and thread_id:
                    # Look up conversation by telegram_topic_id
                    try:
                        mapping = self.db_client.get_telegram_topic_by_id(thread_id)
                        if mapping:
                            contact_id = mapping.get("contact_id") or mapping.get(
                                "conversation_id", ""
                            ).replace("conv_company_", "")
                            await self.send_to_zalo(contact_id, text)
                    except Exception as e:
                        logger.error(f"Error mapping telegram message to Zalo: {e}")

    async def send_to_zalo(self, contact_id: str, text: str):
        """Send a message to Zalo via Zalo Bridge Microservice API."""
        try:
            async with httpx.AsyncClient() as client:
                resp = await client.post(
                    self.zalo_bridge_url,
                    json={"userId": contact_id, "message": text},
                    timeout=10.0,
                )
                logger.info(f"Sent to Zalo: {resp.status_code}")
                return resp
        except Exception as e:
            logger.error(f"Error sending to Zalo: {e}")
            return None
