import pandas as pd
import numpy as np
from scipy import stats
from myffe.tools.interactive import interactive

def analyze_relative_distribution(data, selected_cols=None):
    """分析数据的相关性分布，推荐适合的特征工程方法
    
    Args:
        data: pandas DataFrame，输入数据
        selected_cols: list，用户选择的列，默认为 None（使用所有数值列）
    
    Returns:
        dict: 包含特征工程参数的字典
    """
    # 初始化处理路线
    relative_route = {}
    
    # 找出数值列
    numeric_columns = data.select_dtypes(include=['number']).columns.tolist()
    
    # 使用用户选择的列或所有数值列
    if selected_cols is None:
        selected_cols = numeric_columns
    
    # 构建参数配置
    relative_params = {
        'clean_type': 'normal',
        'choice3_normal': ['skip'],
        'choice3_advance': ['skip'],
        'linear_cols': selected_cols,
        'linear_threshold': 0.75,
        'feature_cols': selected_cols,
        'feature_threshold': 0.75,
        'relation_func': 'func1',
        'pca_cols': selected_cols,
        'n_components': 10,
        'kernel_selection': 'pca',
        'n_features': 10
    }
    
    if len(selected_cols) >= 2:
        # 计算相关性矩阵
        try:
            corr_matrix = data[selected_cols].corr()
            
            # 分析相关性特征
            max_corr = corr_matrix.abs().max().max()
            mean_corr = corr_matrix.abs().mean().mean()
            
            # 分析数据特征
            data_size = len(data)
            num_features = len(selected_cols)
            
            # 确定模式和推荐方法
            if data_size > 1000 or num_features > 10:
                # 大数据集或多特征使用高级模式
                relative_params['clean_type'] = 'advance'
                choice3 = []
                
                # 高相关性处理
                if max_corr > 0.7:
                    choice3.append('linear_plus')
                
                # 非线性特征构建
                if mean_corr > 0.3:
                    choice3.append('feature_plus')
                
                # 降维处理
                if num_features > 15:
                    choice3.append('pca_lda_kernel')
                
                # 特征重要性评估
                if num_features > 5:
                    choice3.append('feature_importance')
                
                if not choice3:
                    choice3.append('skip')
                
                relative_params['choice3_advance'] = choice3
            else:
                # 小数据集使用普通模式
                relative_params['clean_type'] = 'normal'
                choice3 = []
                
                # 高相关性处理
                if max_corr > 0.7:
                    choice3.append('linear_plus')
                
                # 非线性特征构建
                if mean_corr > 0.3:
                    choice3.append('feature_plus')
                
                # 特征重要性评估
                if num_features > 5:
                    choice3.append('feature_importance')
                
                if not choice3:
                    choice3.append('skip')
                
                relative_params['choice3_normal'] = choice3
        except Exception:
            pass
    
    relative_route['relative_preprocessing'] = relative_params
    
    return relative_route

def relative_py(data, auto_test=False):
    """Python实现的相关性分析和特征工程
    
    Args:
        data: pandas DataFrame，输入数据
        auto_test: bool，是否自动测试模式，默认为 False
    
    Returns:
        dict: 包含特征工程参数的字典
    """
    # 找出数值列
    numeric_columns = data.select_dtypes(include=['number']).columns.tolist()
    
    # 如果不是自动测试模式，先分析所有列生成推荐，再让用户选择
    if not auto_test and numeric_columns:
        print("\n" + "=" * 80)
        print("相关性分析和特征工程")
        print("=" * 80)
        
        # 先分析所有数值列，生成初始推荐
        initial_analysis = analyze_relative_distribution(data)
        relative_params = initial_analysis['relative_preprocessing']
        
        # 显示初始推荐结果
        print("\n初始推荐结果（基于所有数值列）:")
        print(f"- 推荐模式: {'高级' if relative_params['clean_type'] == 'advance' else '普通'}")
        
        # 显示推荐的方法
        if relative_params['clean_type'] == 'advance':
            methods = relative_params['choice3_advance']
        else:
            methods = relative_params['choice3_normal']
        
        if methods and methods[0] != 'skip':
            print(f"- 推荐的特征工程方法: {', '.join(methods)}")
        else:
            print("- 推荐的特征工程方法: 无需处理")
        
        # 显示数据特征
        print(f"- 数值列数量: {len(numeric_columns)}")
        print(f"- 数据行数: {len(data)}")
        
        # 使用交互式选择器让用户选择列
        print("\n" + "=" * 80)

        
        selector = interactive(
            options=numeric_columns,
            title="请选择要进行相关性分析的列",
            description="基于上面的推荐结果，选择您需要处理的列。使用上下箭头键移动，按 'm' 选择/取消选择，按 Enter 确认",
            min_select=2,  # 至少选择2列进行相关性分析
            max_select=len(numeric_columns)
        )
        
        # 运行选择器
        selected_cols = selector.run()
        
        print(f"\n已选择列: {selected_cols}")
        
        # 根据用户选择的列重新生成推荐
        final_result = analyze_relative_distribution(data, selected_cols)
        
        # 显示最终推荐结果
        final_params = final_result['relative_preprocessing']
        print("\n最终推荐结果（基于选择的列）:")
        print(f"- 推荐模式: {'高级' if final_params['clean_type'] == 'advance' else '普通'}")
        
        if final_params['clean_type'] == 'advance':
            final_methods = final_params['choice3_advance']
        else:
            final_methods = final_params['choice3_normal']
        
        if final_methods and final_methods[0] != 'skip':
            print(f"- 推荐的特征工程方法: {', '.join(final_methods)}")
        else:
            print("- 推荐的特征工程方法: 无需处理")
        
        return final_result
    else:
        # 自动测试模式或没有数值列，使用所有数值列
        return analyze_relative_distribution(data)
