import time
import logging
from typing import Dict, List, Tuple, Any, Optional
from pydantic import BaseModel, Field
from typing import Type
from langchain_core.tools import BaseTool

from .http_tools import RateClient, const_base_url
from .code import AreaCodeTool
from ..utils.logger import get_logger

code_tool = AreaCodeTool()

class BaseRateTool(BaseTool):
    """设备在线率分析基础工具类"""
    logger: logging.Logger = Field(None, exclude=True)
    
    def __init__(self, **data):
        super().__init__(**data)
        self.logger = get_logger(self.__class__.__name__)
        
    def format_response(self, data: Dict[str, Any], chart: Any) -> Dict[str, Any]:
        """格式化返回结果"""
        self.logger.debug("格式化返回结果")
        return {
            'data': data,
            'summary': self._generate_summary(data)
        }
    
    def _generate_summary(self, data: Dict[str, Any]) -> str:
        """生成数据分析总结文本"""
        self.logger.debug("生成数据分析总结")
        if 'trend_data' in data:  # 全国趋势数据
            summary = (
                f"在{data['date_range']['start']}至{data['date_range']['end']}期间,"
                f"全国平均在线率为{data['statistics']['average_rate']:.2%},"
                f"最高达到{data['statistics']['max_rate']:.2%},"
                f"最低为{data['statistics']['min_rate']:.2%}。"
                f"平均设备总数约{data['statistics']['average_devices']:,}台。"
            )
        elif 'rankings' in data:  # 排名数据
            if 'total_provinces' in data:  # 省份排名
                summary = (
                    f"共分析了{data['total_provinces']}个省份的在线率数据,"
                    f"平均在线率为{data['average_rate']:.2%}。"
                    f"{data['best_province']['name']}的表现最好,"
                    f"在线率达到{data['best_province']['rate']:.2%}。"
                )
            else:  # 厂商排名
                summary = (
                    f"共分析了{data['total_manufacturers']}个厂商的在线率数据,"
                    f"平均在线率为{data['average_rate']:.2%}。"
                    f"{data['best_manufacturer']['name']}的表现最好,"
                    f"在线率达到{data['best_manufacturer']['rate']:.2%}。"
                )
        else:  # 地区在线率数据
            summary = (
                f"{data['region']}在{data['date_range']['start']}至{data['date_range']['end']}期间,"
                f"平均在线率为{data['average_rate']:.2%},"
                f"最高达到{data['max_rate']:.2%},"
                f"最低为{data['min_rate']:.2%}。"
                f"平均设备数约{int(data['total_devices']):,}台。"
            )
        self.logger.debug(f"生成的总结: {summary}")
        return summary

class RegionRateArgs(BaseModel):
    """地区在线率查询参数"""
    region_name: str = Field(..., description="地区名称,如果要查询全国数据,请输入空字符串")
    start_time: str = Field(..., description="开始时间 (YYYY-MM-DD)")
    end_time: str = Field(..., description="结束时间 (YYYY-MM-DD)")

class RegionRateTool(BaseRateTool):
    """查询全国或者特定地区设备在线率的工具"""
    name:str = "region_online_rate"
    description:str = "查询指定地区在指定时间段内的设备在线率"
    args_schema: Type[BaseModel] = RegionRateArgs
    client: Any = Field(None, exclude=True)
    
    def __init__(self, base_url: str = const_base_url, **data):
        super().__init__(**data)
        self.client = RateClient(base_url=base_url)
        self.logger.info(f"初始化 RegionRateTool,base_url: {base_url}")
    
    def _run(self, start_time: str, end_time: str, region_name: str="") -> Dict[str, Any]:
        return self.get_region_online_rate(start_time, end_time, region_name)
        
    def get_region_online_rate(self, start_time: str, end_time: str, region_name: str="") -> Dict[str, Any]:
        agent_start = time.time()
        self.logger.info(f"查询地区在线率: {region_name}, 时间范围: {start_time} 至 {end_time}")
        
        code = ""
        if region_name != "":
            self.logger.debug(f"查找区域代码: {region_name}")
            codes = code_tool.find_code(region_name)
            if codes is None or len(codes) == 0:
                error_msg = f'未找到匹配的区域代码: {region_name}'
                self.logger.warning(error_msg)
                return {'code': 400, 'message': error_msg}
            code = codes[0][1]
            self.logger.debug(f"找到区域代码: {code}")

        try:
            start = time.time()
            df = self.client.query_rates_sync(code, start_time, end_time)
            query_time = time.time() - start
            self.logger.debug(f"API调用耗时: {query_time:.2f}秒")
            
            if df.type != 1 or df.resultdata is None or len(df.resultdata) == 0:
                error_msg = f'未找到{region_name}在{start_time}至{end_time}期间的数据,请检查是否有相关数据权限'
                self.logger.warning(error_msg)
                return {'code': 400, 'message': error_msg}
            
            self.logger.debug(f"查询结果: {df.resultdata}")
            markdown = self.to_markdown(df.resultdata)
            
            data = {
                'region': region_name,
                'region_code': code,
                'rate_data': df.resultdata,
                'markdown': markdown,
                'date_range': {
                    'start': start_time,
                    'end': end_time
                }
            }
            
            total_time = time.time() - agent_start
            self.logger.info(f"查询完成,总耗时: {total_time:.2f}秒")
            return data
            
        except Exception as e:
            self.logger.error(f"查询失败: {str(e)}", exc_info=True)
            raise

    def to_markdown(self, data: List[Dict[str, Any]]) -> str:
        """将数据转换为 markdown 表格"""
        self.logger.debug("开始生成 markdown 表格")
        markdown = """
| 序号 | 日期 | 在线率 |
| --- | --- | --- | 
"""
        for index, row in enumerate(data):
            markdown += f"| {index+1} | {row['name']} | {row['rate']} | \n"
        
        self.logger.debug("markdown 表格生成完成")
        return markdown
        

class RankingRateArgs(BaseModel):
    """排名查询参数"""
    rate_type: int = Field(..., description="排序类型,用于指定查询的排名类别。1表示省份排名,2表示厂商排名")

class RankingRateTool(BaseRateTool):
    """查询在线率排名的工具"""
    name:str = "online_rate_ranking"
    description:str = "查询设备在线率的排名数据,可查询省份排名或厂商排名"
    args_schema: Type[BaseModel] = RankingRateArgs
    client: Any = Field(None, exclude=True)
    
    def __init__(self, base_url: str = const_base_url, **data):
        super().__init__(**data)
        self.client = RateClient(base_url=base_url)
        self.logger.info(f"初始化 RankingRateTool,base_url: {base_url}")
    
    def _run(self, rate_type: int) -> Dict[str, Any]:
        return self.get_ranking_data(rate_type)
        
    def get_ranking_data(self, rate_type: int) -> Dict[str, Any]:
        if rate_type == 1:
            return self._get_province_ranking()
        else:
            return self._get_manufacturer_ranking()
    
    def _get_province_ranking(self) -> Dict[str, Any]:
        """获取省份在线率排名"""
        self.logger.info("开始查询省份在线率排名")
        try:
            df = self.client.query_rates_ranking_sync(rank_type=1)
            
            if df.type != 1 or df.resultdata is None or len(df.resultdata) == 0:
                error_msg = '未找到省份在线率排名数据,请检查是否有相关数据权限'
                self.logger.warning(error_msg)
                return {'code': 400, 'message': error_msg}
            
            self.logger.debug(f"省份排名数据: {df.resultdata}")
            markdown = self.to_markdown(df.resultdata)
            
            data = {
                'rankings': df.resultdata,
                'total_provinces': len(df.resultdata),
                'best_province': {
                    'name': df.resultdata[0]['name'],
                    'rate': df.resultdata[0]['onlineRate']
                },
                'markdown': markdown
            }
            
            self.logger.info(f"查询完成,共 {len(df.resultdata)} 个省份")
            return data
            
        except Exception as e:
            self.logger.error(f"查询省份排名失败: {str(e)}", exc_info=True)
            raise
        
    def _get_manufacturer_ranking(self) -> Dict[str, Any]:
        """获取厂商在线率排名"""
        self.logger.info("开始查询厂商在线率排名")
        try:
            df = self.client.query_rates_ranking_sync(rank_type=2)
            
            if df.type != 1 or df.resultdata is None or len(df.resultdata) == 0:
                error_msg = '未找到厂商在线率排名数据,请检查是否有相关数据权限'
                self.logger.warning(error_msg)
                return {'code': 400, 'message': error_msg}
            
            self.logger.debug(f"厂商排名数据: {df.resultdata}")
            markdown = self.to_markdown(df.resultdata)
            
            data = {
                'rankings': df.resultdata,
                'total_manufacturers': len(df.resultdata),
                'best_manufacturer': {
                    'name': df.resultdata[0]['name'],
                    'rate': df.resultdata[0]['onlineRate']
                },
                'markdown': markdown
            }
            
            self.logger.info(f"查询完成,共 {len(df.resultdata)} 个厂商")
            return data
            
        except Exception as e:
            self.logger.error(f"查询厂商排名失败: {str(e)}", exc_info=True)
            raise

    def to_markdown(self, data: List[Dict[str, Any]]) -> str:
        """将数据转换为 markdown 表格"""
        self.logger.debug("开始生成 markdown 表格")
        markdown = """
| 序号 | 名称 | 全称 | 在线率 |
| --- | --- | --- | --- | 
"""
        for index, row in enumerate(data):
            markdown += f"| {index+1} | {row['name']} | {row['fullname']} | {row['onlineRate']} | \n"
        
        self.logger.debug("markdown 表格生成完成")
        return markdown