# 趋势分析模块
import pandas as pd
from typing import Dict, Tuple, Optional
from qihuo_analyzer.utils.technical_analysis import (
    calculate_adx,
    calculate_moving_average,
    calculate_price_quantile,
    calculate_volume_price_strength
)
from qihuo_analyzer.core.models import StrategyConfig


class TrendFilter:
    """趋势分析过滤器"""
    
    def __init__(self, config: Optional[StrategyConfig] = None):
        self.config = config or StrategyConfig()
    
    def analyze_trend(self, data: pd.DataFrame) -> Dict:
        """分析趋势"""
        result = {}
        
        # 计算ADX指标
        adx_data = calculate_adx(data, self.config.adx_period)
        adx = adx_data['adx'].iloc[-1]
        plus_di = adx_data['plus_di'].iloc[-1]
        minus_di = adx_data['minus_di'].iloc[-1]
        
        # 趋势强度判断
        trend_strength = self._judge_trend_strength(adx)
        trend_direction = self._judge_trend_direction(plus_di, minus_di)
        
        # 计算移动平均线
        ma_data = calculate_moving_average(data, [self.config.short_ma, self.config.long_ma])
        short_ma = ma_data[f'ma{self.config.short_ma}'].iloc[-1]
        long_ma = ma_data[f'ma{self.config.long_ma}'].iloc[-1]
        
        # 双均线排列判断
        ma_relationship = self._judge_ma_relationship(short_ma, long_ma)
        
        # 多周期共振分析
        multi_period_analysis = self._analyze_multi_period(data)
        
        # 综合趋势判断
        overall_trend = self._judge_overall_trend(trend_strength, trend_direction, ma_relationship)
        
        result.update({
            'adx': adx,
            'plus_di': plus_di,
            'minus_di': minus_di,
            'trend_strength': trend_strength,
            'trend_direction': trend_direction,
            'short_ma': short_ma,
            'long_ma': long_ma,
            'ma_relationship': ma_relationship,
            'multi_period_analysis': multi_period_analysis,
            'overall_trend': overall_trend
        })
        
        return result
    
    def _judge_trend_strength(self, adx: float) -> str:
        """判断趋势强度"""
        if adx > 40:
            return 'strong'
        elif adx >= 25:
            return 'medium'
        elif adx >= 20:
            return 'weak'
        else:
            return 'none'
    
    def _judge_trend_direction(self, plus_di: float, minus_di: float) -> str:
        """判断趋势方向"""
        if plus_di > minus_di:
            return 'up'
        elif plus_di < minus_di:
            return 'down'
        else:
            return 'neutral'
    
    def _judge_ma_relationship(self, short_ma: float, long_ma: float) -> str:
        """判断均线关系"""
        if short_ma > long_ma:
            return 'bullish'
        elif short_ma < long_ma:
            return 'bearish'
        else:
            return 'neutral'
    
    def _analyze_multi_period(self, data: pd.DataFrame) -> Dict:
        """多周期共振分析"""
        periods = [15, 60, 240]  # 15分钟、1小时、4小时
        analysis = {}
        
        for period in periods:
            # 简化处理，使用不同周期的收盘价
            if len(data) >= period:
                period_data = data.tail(period)
                ma_short = period_data['close'].rolling(window=5).mean().iloc[-1]
                ma_long = period_data['close'].rolling(window=20).mean().iloc[-1]
                
                if ma_short > ma_long:
                    analysis[f'{period}min'] = 'bullish'
                elif ma_short < ma_long:
                    analysis[f'{period}min'] = 'bearish'
                else:
                    analysis[f'{period}min'] = 'neutral'
            else:
                analysis[f'{period}min'] = 'insufficient_data'
        
        # 计算共振程度
        bullish_count = sum(1 for v in analysis.values() if v == 'bullish')
        bearish_count = sum(1 for v in analysis.values() if v == 'bearish')
        
        resonance = 'none'
        if bullish_count >= 2:
            resonance = 'bullish_resonance'
        elif bearish_count >= 2:
            resonance = 'bearish_resonance'
        
        analysis['resonance'] = resonance
        
        return analysis
    
    def _judge_overall_trend(self, trend_strength: str, trend_direction: str, ma_relationship: str) -> str:
        """综合判断趋势"""
        if trend_strength == 'none':
            return 'neutral'
        
        if trend_direction == 'up' and ma_relationship == 'bullish':
            return 'strong_bullish'
        elif trend_direction == 'down' and ma_relationship == 'bearish':
            return 'strong_bearish'
        elif trend_direction == 'up' and ma_relationship == 'bearish':
            return 'weak_bullish'
        elif trend_direction == 'down' and ma_relationship == 'bullish':
            return 'weak_bearish'
        else:
            return 'neutral'
    
    def calculate_win_rate(self, data: pd.DataFrame) -> float:
        """计算胜率"""
        # 获取ADX值
        adx_data = calculate_adx(data, self.config.adx_period)
        adx = adx_data['adx'].iloc[-1]
        
        # 计算价格分位
        price_quantile = calculate_price_quantile(data)
        price_score = self._calculate_price_score(price_quantile)
        
        # 计算量价强度
        volume_price_strength = calculate_volume_price_strength(data)
        
        # 计算趋势强度评分
        trend_strength_score = self._calculate_trend_strength_score(adx)
        
        # 根据市场状态计算加权胜率
        if adx < 20:  # 震荡市
            win_rate = (
                price_score * 0.25 +
                volume_price_strength * 0.6 +
                trend_strength_score * 0.15
            )
        else:  # 趋势市
            # 价格分位权重随ADX递减
            price_weight = max(0.3, 0.6 - (adx - 20) * 0.0075)
            trend_adjustment = ((adx - 20) * 0.5) / 100 if adx_data['plus_di'].iloc[-1] > adx_data['minus_di'].iloc[-1] else -((adx - 20) * 0.5) / 100
            
            win_rate = (
                price_score * price_weight +
                volume_price_strength * 0.4 +
                trend_strength_score * (0.6 - price_weight)
            ) + trend_adjustment
        
        # 确保胜率在合理范围内
        win_rate = max(0, min(100, win_rate))
        
        return win_rate
    
    def _calculate_price_score(self, quantile: float) -> float:
        """计算价格分位评分"""
        if quantile < 0.2:
            return 90
        elif quantile < 0.4:
            return 75
        elif quantile < 0.6:
            return 55
        elif quantile < 0.8:
            return 40
        else:
            return 25
    
    def _calculate_trend_strength_score(self, adx: float) -> float:
        """计算趋势强度评分"""
        if adx > 40:
            return 85
        elif adx >= 25:
            return 70
        elif adx >= 20:
            return 50
        else:
            return 30
    
    def judge_cycle(self, data: pd.DataFrame) -> str:
        """判断周期"""
        multi_period_analysis = self._analyze_multi_period(data)
        adx_data = calculate_adx(data, self.config.adx_period)
        adx = adx_data['adx'].iloc[-1]
        
        # 检查各周期方向一致性
        directions = [v for k, v in multi_period_analysis.items() if k.endswith('min')]
        valid_directions = [d for d in directions if d != 'insufficient_data']
        
        if not valid_directions:
            return 'medium'
        
        # 检查是否所有周期方向一致且不为中性
        if len(set(valid_directions)) == 1 and valid_directions[0] != 'neutral':
            # 检查是否为极强趋势
            if adx > 40:
                return 'long'
            else:
                return 'short'
        else:
            return 'medium'
