"""
Bilibili uploader using biliup library
"""
import json
import asyncio
from pathlib import Path
from typing import Optional, List, Dict, Any
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor

try:
    from biliup.plugins.bili_webup import BiliBili, Data
    BILIUP_AVAILABLE = True
except ImportError:
    BILIUP_AVAILABLE = False

from loguru import logger
from .base_uploader import BaseUploader

# Thread pool for running sync biliup code
_executor = ThreadPoolExecutor(max_workers=2)


class BilibiliUploader(BaseUploader):
    """Bilibili video uploader using biliup library"""
    
    def __init__(
        self,
        title: str,
        file_path: str,
        tags: List[str],
        publish_date: Optional[datetime] = None,
        account_file: Optional[str] = None,
        description: str = "",
        tid: int = 122,  # 分区ID: 122=国内原创
        copyright: int = 1  # 1=原创, 2=转载
    ):
        """
        Initialize Bilibili uploader
        
        Args:
            tid: Bilibili category ID (default: 122 for 国内原创)
            copyright: 1 for original, 2 for repost
        """
        super().__init__(title, file_path, tags, publish_date, account_file, description)
        self.tid = tid
        self.copyright = copyright
        
        if not BILIUP_AVAILABLE:
            raise ImportError(
                "biliup library not installed. Please run: pip install biliup"
            )
    
    async def main(self) -> Dict[str, Any]:
        """
        Upload video to Bilibili
        
        Returns:
            dict: Upload result
        """
        # Run sync upload in thread pool to avoid asyncio.run() conflict
        loop = asyncio.get_event_loop()
        return await loop.run_in_executor(_executor, self._upload_sync)
    
    def _upload_sync(self) -> Dict[str, Any]:
        """Synchronous upload logic (runs in thread pool)"""
        try:
            # 1. Load cookie data
            if not self.account_file or not Path(self.account_file).exists():
                logger.error(f"[B站] Cookie 文件不存在: {self.account_file}")
                return {
                    "success": False,
                    "message": "Cookie 文件不存在，请先登录",
                    "url": None
                }
            
            with open(self.account_file, 'r', encoding='utf-8') as f:
                cookie_data = json.load(f)
            
            # Convert simple cookie format to biliup format if needed
            if 'cookie_info' not in cookie_data and 'SESSDATA' in cookie_data:
                # Transform to biliup expected format
                cookie_data = {
                    'cookie_info': {
                        'cookies': [
                            {'name': k, 'value': v} for k, v in cookie_data.items()
                        ]
                    },
                    'token_info': {
                        'access_token': cookie_data.get('access_token', ''),
                        'refresh_token': cookie_data.get('refresh_token', '')
                    }
                }
                logger.info("[B站] Cookie格式已转换")
            
            # 2. Prepare video data
            data = Data()
            data.copyright = self.copyright
            data.title = self.title
            data.desc = self.description or f"标签: {', '.join(self.tags)}"
            data.tid = self.tid
            data.set_tag(self.tags)
            data.dtime = self._get_timestamp(self.publish_date)
            
            logger.info(f"[B站] 开始上传: {self.file_path.name}")
            logger.info(f"[B站] 标题: {self.title}")
            logger.info(f"[B站] 定时发布: {'是' if data.dtime > 0 else '否'}")
            
            # 3. Upload video
            with BiliBili(data) as bili:
                # Login with cookies
                bili.login_by_cookies(cookie_data)
                bili.access_token = cookie_data.get('access_token', '')
                
                # Upload file (3 threads, auto line selection)
                video_part = bili.upload_file(
                    str(self.file_path),
                    lines='AUTO',
                    tasks=3
                )
                video_part['title'] = self.title
                data.append(video_part)
                
                # Submit
                ret = bili.submit()
                
                # Debug: log full response
                logger.debug(f"[B站] API响应: {ret}")
                
                if ret.get('code') == 0:
                    # Try multiple keys for bvid (API may vary)
                    bvid = ret.get('data', {}).get('bvid') or ret.get('bvid', '')
                    aid = ret.get('data', {}).get('aid') or ret.get('aid', '')
                    
                    if bvid:
                        logger.success(f"[B站] 上传成功: {bvid}")
                        return {
                            "success": True,
                            "message": "发布成功，待审核" if data.dtime == 0 else "已设置定时发布",
                            "url": f"https://www.bilibili.com/video/{bvid}"
                        }
                    elif aid:
                        logger.success(f"[B站] 上传成功: av{aid}")
                        return {
                            "success": True,
                            "message": "发布成功，待审核" if data.dtime == 0 else "已设置定时发布",
                            "url": f"https://www.bilibili.com/video/av{aid}"
                        }
                    else:
                        # No bvid/aid but code=0, still consider success
                        logger.warning(f"[B站] 上传返回code=0但无bvid/aid: {ret}")
                        return {
                            "success": True,
                            "message": "发布成功，待审核",
                            "url": None
                        }
                else:
                    error_msg = ret.get('message', '未知错误')
                    logger.error(f"[B站] 上传失败: {error_msg} (完整响应: {ret})")
                    return {
                        "success": False,
                        "message": f"上传失败: {error_msg}",
                        "url": None
                    }
        
        except Exception as e:
            logger.exception(f"[B站] 上传异常: {e}")
            return {
                "success": False,
                "message": f"上传异常: {str(e)}",
                "url": None
            }
