#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
路线管理器

整合了 route_config.py 和 auto_route.py 的功能，提供统一的路线配置和管理接口。
"""

import os
import sys
import pandas as pd
import json

from myffe.tools.color_printer import ColorPrinter

class RouteManager:
    """路线管理器类
    
    整合了 route_config.py 和 auto_route.py 的功能，提供统一的路线配置和管理接口。
    支持手动配置和自动推荐两种模式。
    """
    
    def __init__(self, tools=None, label_columns=None):
        """初始化路线管理器
        
        Args:
            tools (list, optional): 要配置的工具列表，默认None（执行所有工具）
            label_columns (list, optional): 标签列，默认None
        """
        self.tools = tools
        self.label_columns = label_columns
        self.route = {}
    
    def __call__(self, data, label_columns=None):
        """主调用函数
        
        Args:
            data (DataFrame): 输入数据，pandas DataFrame格式
            label_columns (list, optional): 标签列，默认N  one
        
        Returns:
            dict: 推荐的特征工程路线
        """
        # 如果没有提供label_columns，使用初始化时的参数
        if label_columns is None:
            label_columns = self.label_columns
        
        self.data = data
        self.route = self.get_route(label_columns)
        return self.route
    
    def get_route(self, label_columns=None):
        """获取路线配置
        
        Args:
            label_columns (list, optional): 标签列，默认None
        
        Returns:
            dict: 特征工程路线配置
        """
        # 初始化路线结构
        self.route = {}
        
        # 定义工具配置，包含路由名称、工具函数名称和参数
        tool_configs = {
            'nan_preprocessing': ('nan', 'nan_py', ()),
            'sample_preprocessing': ('sample', 'sample_py', (label_columns,)),
            'outlier_preprocessing': ('outlier', 'outlier_py', ()),
            'str_preprocessing': ('str', 'str_py', ()),
            'relative_preprocessing': ('relative', 'relative_py', ()),
            'time_preprocessing': ('time', 'time_py', ()),
            'specify_preprocessing': ('specify', 'specify_py', ()),
            'standard_preprocessing': ('standard', 'standard_py', ()),
            'normalized_preprocessing': ('normalized', 'normalized_py', ())
        }
        
        # 按照顺序执行工具
        # 如果没有指定工具列表，则执行所有工具
        if self.tools is None:
            # 按顺序执行所有工具
            tools_order = [
                'nan_preprocessing',
                'sample_preprocessing',
                'outlier_preprocessing',
                'str_preprocessing',
                'relative_preprocessing',
                'time_preprocessing',
                'specify_preprocessing',
                'standard_preprocessing',
                'normalized_preprocessing'
            ]
            for tool in tools_order:
                route_name, tool_name, args = tool_configs[tool]
                # 对于sample_preprocessing，需要传递原始数据（包含标签列）
                if tool == 'sample_preprocessing':
                    self._process_route(route_name, tool_name, *args, use_original_data=True, label_columns=label_columns)
                else:
                    self._process_route(route_name, tool_name, *args, label_columns=label_columns)
        else:
            # 只执行指定的工具
            for tool in self.tools:
                if tool in tool_configs:
                    route_name, tool_name, args = tool_configs[tool]
                    # 对于sample_preprocessing，需要传递原始数据（包含标签列）
                    if tool == 'sample_preprocessing':
                        self._process_route(route_name, tool_name, *args, use_original_data=True, label_columns=label_columns)
                    else:
                        self._process_route(route_name, tool_name, *args, label_columns=label_columns)
        
        # 可视化路由数据
        try:
            # 导入visualize_route模块（从tools目录）
            from myffe.tools import visualize_route
            ColorPrinter.print_info("\n" + "=" * 80)
            ColorPrinter.print_info("参数配置可视化")
            ColorPrinter.print_info("=" * 80)
            visualize_route(self.route)
        except ImportError as e:
            ColorPrinter.print_error(f"\n可视化模块未找到: {e}")
            ColorPrinter.print_error("请确保 visualize_route.py 在 tools 目录中")
        
        return self.route
    
    def _process_route(self, route_name, tool_name, *args, use_original_data=False, label_columns=None, **kwargs):
        """通用处理方法，简化重复的路由处理逻辑
        
        Args:
            route_name (str): 路由名称
            tool_name (str): 工具函数名称
            *args: 传递给工具函数的参数
            use_original_data (bool): 是否使用原始数据（包含标签列）
            label_columns (list): 标签列
            **kwargs: 传递给工具函数的关键字参数
        """
        # 动态导入工具模块
        module = __import__(f'myffe.route.py_tools.{tool_name}', fromlist=[tool_name])
        tool_func = getattr(module, tool_name)
        
        # 选择要传递的数据
        if use_original_data:
            # 传递原始数据（包含标签列）
            data_to_pass = self.data
        else:
            # 分离标签列和特征数据
            if label_columns:
                # 确保label_columns是列表
                if isinstance(label_columns, str):
                    label_columns = [label_columns]
                # 分离特征数据（排除标签列）
                data_to_pass = self.data[[col for col in self.data.columns if col not in label_columns]]
            else:
                data_to_pass = self.data.copy()
        
        # 调用工具函数获取处理参数，传递auto_test=True
        result = tool_func(data_to_pass, *args, auto_test=True, **kwargs)
        
        # 处理返回结果，确保结构正确
        if isinstance(result, dict):
            # 检查是否已经包含_preprocessing键
            preprocessing_key = f'{route_name}_preprocessing'
            if preprocessing_key in result:
                # 如果已经包含，则直接使用内部的内容
                self.route[preprocessing_key] = result[preprocessing_key]
            else:
                # 否则直接使用结果
                self.route[preprocessing_key] = result
        elif result == 'skip':
            # 如果返回的是'skip'字符串，创建包含'skip'值的默认参数字典
            preprocessing_key = f'{route_name}_preprocessing'
            # 根据工具类型创建对应的默认参数字典
            if route_name == 'nan':
                self.route[preprocessing_key] = {'nan_missing_process_choice': ['skip'], 'nan_processing_col': []}
            elif route_name == 'sample':
                self.route[preprocessing_key] = {'choice1_normal': ['skip'], 'choice1_advance': ['skip']}
            elif route_name == 'time':
                self.route[preprocessing_key] = {'time_col': None}
            elif route_name == 'str':
                self.route[preprocessing_key] = {'str_choice': 'skip', 'str_cols': []}
            elif route_name == 'outlier':
                self.route[preprocessing_key] = {'outlier_choice': 'skip'}
            elif route_name == 'relative':
                self.route[preprocessing_key] = {'choice3_normal': ['skip'], 'choice3_advance': ['skip']}
            elif route_name == 'specify':
                self.route[preprocessing_key] = {'drop_col': [], 'drop_row': []}
            elif route_name == 'standard':
                self.route[preprocessing_key] = {'scaler_method_choice': [], 'standard_col': []}
            elif route_name == 'normalized':
                self.route[preprocessing_key] = {'normalizer_method_choice': [], 'normalized_col': []}
            else:
                # 其他工具类型的默认处理
                self.route[preprocessing_key] = {'choice': 'skip'}
        else:
            # 如果返回的不是字典也不是'skip'，直接存储
            self.route[f'{route_name}_preprocessing'] = result
    
    def read(self, path):
        """读取数据集
        
        Args:
            path (str): 数据集路径
        
        Returns:
            DataFrame: 读取的数据集
        """
        # 统一使用pandas读取文件
        ColorPrinter.print_info("使用pandas读取CSV文件")
        return pd.read_csv(path)
    
    def get_cleaning_info(self):
        """获取清理信息（只返回路线信息，不执行清理）
        
        Returns:
            str: 格式化的路线信息JSON字符串
        """
        # 返回格式化的JSON字符串，便于阅读
        return json.dumps(self.route, indent=2, ensure_ascii=False)


# 使用示例
if __name__ == "__main__":
    # 创建测试数据
    import csv
    
    test_data = [
        ["name", "age", "city", "salary", "score", "label"],
        ["Alice", "25", "New York", "50000", "85", "A"],
        ["Bob", "", "Los Angeles", "60000", "90", "B"],  # 空值
        ["", "30", "Chicago", "70000", "75", "A"],        # 空值
        ["David", "35", "", "80000", "80", "C"],          # 空值
        ["Eve", "40", "Boston", "90000", "95", "A"]
    ]
    
    # 写入测试文件
    with open('test.csv', 'w', newline='') as f:
        writer = csv.writer(f)
        writer.writerows(test_data)
    
    # 创建RouteManager实例
    route_manager = RouteManager()
    
    # 读取数据
    data = route_manager.read('test.csv')
    
    # 获取路线配置
    route = route_manager(data, label_columns=['label'])
    
    ColorPrinter.print_info("清理路线:")
    if 'specify_preprocessing' in route:
        if 'drop_row' in route['specify_preprocessing']:
            ColorPrinter.print_info(f"要删除的行: {route['specify_preprocessing']['drop_row']}")
        if 'drop_col' in route['specify_preprocessing']:
            ColorPrinter.print_info(f"要删除的列: {route['specify_preprocessing']['drop_col']}")
    if 'nan_preprocessing' in route:
        ColorPrinter.print_info(f"缺失值处理方法: {route['nan_preprocessing'].get('nan_missing_process_choice', 'None')}")
    
    if 'standard_preprocessing' in route:
        ColorPrinter.print_info("\n标准化路线:")
        standard_col = route['standard_preprocessing']['standard_col']
        ColorPrinter.print_info(f"标准化列: {standard_col}")
        ColorPrinter.print_info("标准化方法:")
        methods = route['standard_preprocessing']['scaler_method_choice']
        for col, method in zip(standard_col, methods):
            ColorPrinter.print_info(f"  {col}: {method}")
    
    if 'normalized_preprocessing' in route:
        ColorPrinter.print_info("\n归一化路线:")
        normalized_col = route['normalized_preprocessing']['normalized_col']
        ColorPrinter.print_info(f"归一化列: {normalized_col}")
        ColorPrinter.print_info("归一化方法:")
        methods = route['normalized_preprocessing']['normalizer_method_choice']
        for col, method in zip(normalized_col, methods):
            ColorPrinter.print_info(f"  {col}: {method}")
    
    if 'sample_preprocessing' in route:
        ColorPrinter.print_info("\n采样处理路线:")
        sample_info = route['sample_preprocessing']
        ColorPrinter.print_info("采样参数配置:")
        for key, value in sample_info.items():
            ColorPrinter.print_info(f"    {key}: {value}")
    
    # 获取清理信息（不执行清理）
    cleaning_info = route_manager.get_cleaning_info()
    ColorPrinter.print_info("\n清理信息:")
    ColorPrinter.print_info(cleaning_info)
