import logging
from typing import Optional

import httpx

from app.config import settings
from app.services.distribution.publishers.base import ContentPublisher, PublishResult
from app.services.distribution.publishers.mock_publisher import MockPublisher
from app.services.distribution.formatter import ContentFormatter

logger = logging.getLogger(__name__)


class WeChatPublisher(ContentPublisher):
    platform: str = "wechat"

    API_BASE = "https://api.weixin.qq.com/cgi-bin"

    def __init__(self):
        self._formatter = ContentFormatter()

    def is_configured(self) -> bool:
        return bool(settings.WECHAT_OFFICIAL_APP_ID and settings.WECHAT_OFFICIAL_APP_SECRET)

    async def publish(self, title: str, content: str, **kwargs) -> PublishResult:
        formatted = self._formatter.format_for_platform(content, "wechat")

        if not self.is_configured():
            return PublishResult(
                success=True,
                platform=self.platform,
                article_id=f"wechat_copy_ready_{id(content)}",
                article_url=None,
                raw_response={
                    "mode": "semi_auto",
                    "formatted_content": formatted,
                    "instructions": (
                        "1. 登录微信公众号后台\n"
                        "2. 新建图文消息\n"
                        "3. 将 formatted_content 粘贴到编辑器中\n"
                        "4. 检查排版并发布"
                    ),
                },
            )

        try:
            access_token = await self._get_access_token()
            if not access_token:
                return PublishResult(
                    success=False,
                    platform=self.platform,
                    error="Failed to obtain WeChat access token",
                )

            headers = {"Content-Type": "application/json"}
            payload = {
                "access_token": access_token,
                "articles": [
                    {
                        "title": title,
                        "content": formatted,
                        "thumb_media_id": kwargs.get("thumb_media_id", ""),
                        "author": kwargs.get("author", ""),
                        "digest": kwargs.get("digest", content[:120]),
                        "content_source_url": kwargs.get("content_source_url", ""),
                    }
                ],
            }

            async with httpx.AsyncClient(timeout=30) as client:
                resp = await client.post(
                    f"{self.API_BASE}/draft/add",
                    headers=headers,
                    json=payload,
                )
                data = resp.json()

                if data.get("media_id"):
                    return PublishResult(
                        success=True,
                        platform=self.platform,
                        article_id=data["media_id"],
                        raw_response=data,
                    )
                else:
                    return PublishResult(
                        success=False,
                        platform=self.platform,
                        error=data.get("errmsg", str(data)),
                        raw_response=data,
                    )
        except Exception as e:
            logger.error(f"WeChat publish error: {e}")
            return PublishResult(
                success=False,
                platform=self.platform,
                error=str(e),
            )

    async def _get_access_token(self) -> Optional[str]:
        if not self.is_configured():
            return None
        try:
            async with httpx.AsyncClient(timeout=10) as client:
                resp = await client.get(
                    f"{self.API_BASE}/token",
                    params={
                        "grant_type": "client_credential",
                        "appid": settings.WECHAT_OFFICIAL_APP_ID,
                        "secret": settings.WECHAT_OFFICIAL_APP_SECRET,
                    },
                )
                data = resp.json()
                return data.get("access_token")
        except Exception as e:
            logger.error(f"WeChat access token error: {e}")
            return None

    async def verify_credentials(self) -> bool:
        if not self.is_configured():
            return False
        token = await self._get_access_token()
        return token is not None

    async def get_article_status(self, article_id: str) -> dict:
        if not self.is_configured():
            mock = MockPublisher(platform="wechat")
            return await mock.get_article_status(article_id)
        try:
            access_token = await self._get_access_token()
            async with httpx.AsyncClient(timeout=10) as client:
                resp = await client.post(
                    f"{self.API_BASE}/draft/get",
                    params={"access_token": access_token},
                    json={"media_id": article_id},
                )
                return resp.json()
        except Exception as e:
            return {"article_id": article_id, "error": str(e)}
