#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Stage 7 API 客户端
用于调用深度解构分析 API
"""

import time
import logging
import requests
from datetime import datetime
from typing import Dict, List, Any, Optional

logger = logging.getLogger(__name__)


def map_note_to_api_format(
    note: Dict,
    note_card: Dict,
    evaluation: Dict,
    search_word: str,
    original_feature: str,
    start_points: List[str],
    processed_image_urls: Optional[List[str]] = None
) -> Dict:
    """
    将小红书笔记数据映射为 API 所需格式

    Args:
        note: 笔记原始数据
        note_card: 笔记卡片信息
        evaluation: 评估结果
        search_word: 搜索词
        original_feature: 原始特征
        start_points: 起点列表
        processed_image_urls: 处理后的图片URL列表(如果提供,将替代原始URL)

    Returns:
        API 请求格式的数据
    """
    # 构建小红书链接
    note_id = note.get('id', '')
    link = f"https://www.xiaohongshu.com/explore/{note_id}"

    # 获取用户信息
    user = note_card.get('user', {})
    interact_info = note_card.get('interact_info', {})

    # 获取发布时间（需要转换为毫秒时间戳）
    publish_ts = note_card.get('publish_timestamp', 0)
    publish_ts_ms = publish_ts * 1000 if publish_ts else 0

    # 格式化发布日期
    publish_date = ''
    if publish_ts:
        try:
            publish_date = datetime.fromtimestamp(publish_ts).strftime('%Y-%m-%d %H:%M:%S')
        except:
            publish_date = ''

    # 使用处理后的图片URL,如果没有则使用原始URL
    image_urls = processed_image_urls if processed_image_urls else note_card.get('image_list', [])

    return {
        "post_data": {
            "channel_content_id": note_id,
            "link": link,
            "xsec_token": "",  # 通常为空
            "comment_count": interact_info.get('comment_count', 0),
            "images": image_urls,
            "like_count": interact_info.get('liked_count', 0),
            "body_text": note_card.get('desc', ''),
            "title": note_card.get('display_title', ''),
            "collect_count": interact_info.get('collected_count', 0),
            "channel_account_id": user.get('user_id', ''),
            "channel_account_name": user.get('nick_name', ''),
            "publish_timestamp": publish_ts_ms,
            "modify_timestamp": publish_ts_ms,
            "update_timestamp": int(time.time() * 1000),
            "publish_date": publish_date,
            "content_type": "note",
            "video": {}  # 图文类型无视频
        },
        "question_data": {
            "target": original_feature,      # 例如: "墨镜"
            "start_points": start_points,    # 例如: ["墨镜", "猫咪服饰造型元素", "图片中猫咪佩戴墨镜"]
            "query": search_word             # 例如: "猫咪服饰造型元素"
        }
    }


class DeconstructionAPIClient:
    """解构分析 API 客户端"""

    def __init__(
        self,
        api_url: str = "http://192.168.245.150:7000/what/analysis/single",
        timeout: int = 800,
        max_retries: int = 3
    ):
        """
        初始化 API 客户端

        Args:
            api_url: API 地址
            timeout: 超时时间（秒）
            max_retries: 最大重试次数
        """
        self.api_url = api_url
        self.timeout = timeout
        self.max_retries = max_retries

    def call_api(
        self,
        api_payload: Dict
    ) -> Dict:
        """
        调用解构 API（带重试机制）

        Args:
            api_payload: API 请求数据

        Returns:
            {
                'status': 'success' | 'failed',
                'result': API响应数据（成功时）,
                'error': 错误信息（失败时）
            }
        """
        for attempt in range(self.max_retries):
            try:
                response = requests.post(
                    self.api_url,
                    json=api_payload,
                    headers={'Content-Type': 'application/json'},
                    timeout=self.timeout
                )

                if response.status_code == 200:
                    return {
                        'status': 'success',
                        'result': response.json(),
                        'error': None
                    }
                else:
                    error_msg = f"HTTP {response.status_code}: {response.text[:200]}"

                    # 如果还有重试机会，继续重试
                    if attempt < self.max_retries - 1:
                        wait_time = 2 ** attempt  # 指数退避: 1s, 2s, 4s
                        logger.warning(f"    API 调用失败，{wait_time}s 后重试 ({attempt + 1}/{self.max_retries})")
                        time.sleep(wait_time)
                        continue

                    # 最后一次重试也失败
                    return {
                        'status': 'failed',
                        'result': None,
                        'error': error_msg
                    }

            except requests.Timeout:
                if attempt < self.max_retries - 1:
                    wait_time = 2 ** attempt
                    logger.warning(f"    API 超时，{wait_time}s 后重试 ({attempt + 1}/{self.max_retries})")
                    time.sleep(wait_time)
                    continue

                return {
                    'status': 'failed',
                    'result': None,
                    'error': f'API timeout after {self.timeout}s'
                }

            except Exception as e:
                if attempt < self.max_retries - 1:
                    wait_time = 2 ** attempt
                    logger.warning(f"    API 异常，{wait_time}s 后重试 ({attempt + 1}/{self.max_retries}): {e}")
                    time.sleep(wait_time)
                    continue

                return {
                    'status': 'failed',
                    'result': None,
                    'error': f'Exception: {str(e)}'
                }

        # 理论上不会到这里
        return {
            'status': 'failed',
            'result': None,
            'error': 'Max retries exceeded'
        }


def test_api_client():
    """测试 API 客户端"""
    # 模拟数据
    test_note = {
        'id': '68ba3a27000000001c00f8fc'
    }

    test_note_card = {
        'display_title': '测试标题',
        'desc': '测试内容',
        'image_list': [
            'https://example.com/image1.jpg',
            'https://example.com/image2.jpg'
        ],
        'user': {
            'user_id': '123456',
            'nick_name': '测试用户'
        },
        'interact_info': {
            'liked_count': 100,
            'collected_count': 50,
            'comment_count': 10
        },
        'publish_timestamp': 1640000000
    }

    test_evaluation = {
        '综合得分': 9.0,
        '关键匹配点': ['测试匹配点1', '测试匹配点2']
    }

    # 数据映射测试
    api_payload = map_note_to_api_format(
        note=test_note,
        note_card=test_note_card,
        evaluation=test_evaluation,
        search_word='测试搜索词',
        original_feature='测试特征',
        start_points=['起点1', '起点2']
    )

    print("API Payload:")
    import json
    print(json.dumps(api_payload, ensure_ascii=False, indent=2))

    # API 调用测试（需要实际 API 服务）
    # client = DeconstructionAPIClient()
    # result = client.call_api(api_payload)
    # print("\nAPI Result:")
    # print(json.dumps(result, ensure_ascii=False, indent=2))


if __name__ == '__main__':
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    test_api_client()
