"""
资产类型检测器

根据代码格式自动识别资产类型，支持：
- A股指数/ETF/股票
- 港股指数/股票
- 美股指数/股票
- 期货合约
- 加密货币

用法:
    from datasource.asset_type_detector import AssetTypeDetector, AssetType
    
    # 检测资产类型
    asset_type = AssetTypeDetector.detect("000300.SH")  # AssetType.CHINA_INDEX
    
    # 获取描述
    desc = AssetTypeDetector.get_description(asset_type)  # "A股指数"
    
    # 批量分组
    grouped = AssetTypeDetector.group_by_type(["000300.SH", "NDX", "AU.SHF"])
"""

from enum import Enum
from typing import Dict, List


class AssetType(Enum):
    """资产类型枚举"""
    CHINA_INDEX = "china_index"      # A股指数
    CHINA_ETF = "china_etf"           # A股ETF
    CHINA_STOCK = "china_stock"       # A股股票
    HK_INDEX = "hk_index"             # 港股指数
    HK_STOCK = "hk_stock"             # 港股股票
    US_INDEX = "us_index"             # 美股指数
    US_STOCK = "us_stock"             # 美股股票
    FUTURES = "futures"               # 期货合约
    CRYPTO = "crypto"                 # 加密货币
    UNKNOWN = "unknown"               # 未知类型


class AssetTypeDetector:
    """
    资产类型检测器
    
    根据代码格式自动识别资产类型
    """
    
    # A股后缀
    CHINA_SUFFIXES = ('.SH', '.SZ', '.SS', '.CSI')
    
    # 中国期货后缀
    CHINA_FUTURES_SUFFIXES = ('.SHF', '.DCE', '.CZC', '.INE', '.GFEX')
    
    # 境外期货后缀
    FOREIGN_FUTURES_SUFFIXES = ('.NYM', '.ICE', '.CME', '.CBT')
    
    # 港股后缀
    HK_SUFFIXES = ('.HK',)
    
    # 加密货币代码
    CRYPTO_CODES = {'BTC', 'ETH', 'SOL', 'BNB', 'XRP', 'ADA', 'DOGE'}
    
    # 特殊指数代码（无后缀）
    SPECIAL_INDEX_CODES = {
        'HSI': AssetType.HK_INDEX,      # 恒生指数
        'NDX': AssetType.US_INDEX,      # 纳斯达克100
        'SPX': AssetType.US_INDEX,      # 标普500
        'DJI': AssetType.US_INDEX,      # 道琼斯
        'N225': AssetType.US_INDEX,     # 日经225（日本）
        'GDAXI': AssetType.US_INDEX,    # 德国DAX（欧洲）
        'HSCCI': AssetType.HK_INDEX,    # 恒生国企指数
        'HSCEI': AssetType.HK_INDEX,    # 恒生中企指数
    }
    
    # YFinance映射（用于判断是否为指数）
    YFINANCE_INDEX_MAP = {
        "HSTECH.HK": "3033.HK",
        "HSI": "^HSI",
        "NDX": "^NDX",
        "SPX": "^GSPC",
        "DJI": "^DJI",
        "N225": "^N225",
        "GDAXI": "^GDAXI",
        "CL.NYM": "CL=F",
    }
    
    # 类型描述映射
    DESCRIPTIONS = {
        AssetType.CHINA_INDEX: "A股指数",
        AssetType.CHINA_ETF: "A股ETF",
        AssetType.CHINA_STOCK: "A股股票",
        AssetType.HK_INDEX: "港股指数",
        AssetType.HK_STOCK: "港股股票",
        AssetType.US_INDEX: "美股指数",
        AssetType.US_STOCK: "美股股票",
        AssetType.FUTURES: "期货合约",
        AssetType.CRYPTO: "加密货币",
        AssetType.UNKNOWN: "未知类型",
    }
    
    @classmethod
    def detect(cls, code: str) -> AssetType:
        """
        检测资产类型
        
        Args:
            code: 标的代码
        
        Returns:
            AssetType 枚举值
        """
        code = code.strip().upper()
        
        # 1. 加密货币（优先判断）
        if code in cls.CRYPTO_CODES:
            return AssetType.CRYPTO
        
        # 2. 特殊指数代码（无后缀）
        if code in cls.SPECIAL_INDEX_CODES:
            return cls.SPECIAL_INDEX_CODES[code]
        
        # 3. YFinance映射中的代码（指数）
        if code in cls.YFINANCE_INDEX_MAP:
            yf_code = cls.YFINANCE_INDEX_MAP[code]
            if yf_code.startswith('^'):
                return AssetType.US_INDEX
            elif yf_code.endswith('.HK'):
                return AssetType.HK_INDEX
        
        # 4. 期货后缀
        if any(code.endswith(suffix) for suffix in cls.CHINA_FUTURES_SUFFIXES):
            return AssetType.FUTURES
        if any(code.endswith(suffix) for suffix in cls.FOREIGN_FUTURES_SUFFIXES):
            return AssetType.FUTURES
        
        # 5. 港股后缀
        if code.endswith('.HK'):
            # 4位数字.HK通常是指数
            code_body = code.split('.')[0]
            if code_body.isdigit() and len(code_body) == 4:
                return AssetType.HK_INDEX
            return AssetType.HK_STOCK
        
        # 6. A股后缀
        if any(code.endswith(suffix) for suffix in cls.CHINA_SUFFIXES):
            return cls._classify_china_asset(code)
        
        # 7. 默认：美股股票
        return AssetType.US_STOCK
    
    @classmethod
    def _classify_china_asset(cls, code: str) -> AssetType:
        """
        细分A股资产类型
        
        规则:
        - .CSI 后缀：中证指数
        - 指数代码段: 000, 001, 002, 399, 930, 931, 932
        - ETF代码段: 51, 52, 56, 58, 15, 16
        - 股票: 其他
        
        Args:
            code: A股代码（含后缀）
        
        Returns:
            AssetType
        """
        # .CSI 后缀直接判定为指数
        if code.endswith('.CSI'):
            return AssetType.CHINA_INDEX
        
        # 提取代码主体
        code_body = code.split('.')[0]
        
        # 检查是否为6位数字
        if not code_body.isdigit() or len(code_body) != 6:
            return AssetType.CHINA_STOCK
        
        # 特殊情况：000001 是平安银行（股票）
        if code_body == '000001':
            return AssetType.CHINA_STOCK
        
        # ETF代码段
        etf_prefixes = ('51', '52', '56', '58', '15', '16')
        if code_body.startswith(etf_prefixes):
            return AssetType.CHINA_ETF
        
        # 指数代码段
        index_prefixes = ('000', '001', '002', '399', '930', '931', '932')
        if code_body.startswith(index_prefixes):
            return AssetType.CHINA_INDEX
        
        # 默认为股票
        return AssetType.CHINA_STOCK
    
    @classmethod
    def get_description(cls, asset_type: AssetType) -> str:
        """获取资产类型描述"""
        return cls.DESCRIPTIONS.get(asset_type, "未知类型")
    
    @classmethod
    def group_by_type(cls, codes: List[str]) -> Dict[AssetType, List[str]]:
        """
        按资产类型分组
        
        Args:
            codes: 代码列表
        
        Returns:
            {AssetType: [codes]}
        """
        grouped = {}
        for code in codes:
            asset_type = cls.detect(code)
            if asset_type not in grouped:
                grouped[asset_type] = []
            grouped[asset_type].append(code)
        return grouped