import streamlit as st
import pandas as pd
from typing import List, Optional, Union


class DataAnalysisSqlGenerator:
    """数据分析SQL语句生成器
    
    用于根据分析结果生成对应的SQL查询语句，支持DuckDB语法
    """
    
    def __init__(self, table_name: str = "data", use_json_contains: bool = False):
        """初始化SQL生成器
        
        Args:
            table_name: 表名，默认为"data"
            use_json_contains: 是否使用json_contains方式（False则使用list_contains + CAST方式）
        """
        self.table_name = table_name
        self.use_json_contains = use_json_contains
    
    def _convert_custom_json_path_to_duckdb(self, json_path: str) -> str:
        """将自定义JSON路径格式转换为DuckDB标准JSONPath格式
        
        Args:
            json_path: 自定义路径格式，如 "*.messageType" 或 "key1.*.key2"
            
        Returns:
            DuckDB兼容的JSONPath格式，如 "$[*].messageType" 或 "$.key1[*].key2"
        """
        if not json_path:
            return "$"
        
        # 确保以$开头
        if not json_path.startswith('$'):
            if json_path.startswith('*.'):
                # 处理开头的通配符：*.xxx -> $[*].xxx
                json_path = '$[*].' + json_path[2:]
            else:
                json_path = '$.' + json_path
        
        # 处理中间的通配符：.* -> [*]
        # 但要避免重复处理已经转换过的 $[*]
        parts = json_path.split('.')
        result_parts = []
        
        for i, part in enumerate(parts):
            if part == '*':
                # 将 * 转换为 [*] 并合并到前一个部分
                if result_parts:
                    result_parts[-1] += '[*]'
                else:
                    result_parts.append('$[*]')
            elif part.startswith('$[*]'):
                # 已经是正确格式的开头
                result_parts.append(part)
            else:
                result_parts.append(part)
        
        # 重新组合，但要注意[*]不需要额外的点号
        result = ""
        for i, part in enumerate(result_parts):
            if i == 0:
                result = part
            elif part == "" or result.endswith('[*]'):
                # 如果前一个部分以[*]结尾，或者当前部分是空，则直接连接
                result += '.' + part if part else ''
            else:
                result += '.' + part
        
        return result
    
    def _is_regex_pattern(self, json_path: str) -> bool:
        """检查路径是否包含正则表达式模式
        
        Args:
            json_path: JSON路径
            
        Returns:
            是否包含正则表达式
        """
        return 'r"' in json_path or "r'" in json_path
    
    def generate_regex_workaround_sql(self, 
                                    column_name: str, 
                                    json_path: str,
                                    selected_values: List[str] = None,
                                    is_aggregation: bool = False) -> str:
        """生成正则表达式匹配的变通实现SQL
        
        Args:
            column_name: 列名
            json_path: 包含正则表达式的JSON路径
            selected_values: 筛选值（可选）
            is_aggregation: 是否为聚合查询
            
        Returns:
            变通实现的SQL语句
        """
        # 解析路径中的正则表达式
        import re
        regex_match = re.search(r'r["\'](.+?)["\']', json_path)
        if not regex_match:
            return "-- 未找到有效的正则表达式模式"
        
        regex_pattern = regex_match.group(1)
        
        # 构建基础的key提取查询
        # 这里需要先获取所有可能的key，然后用正则表达式过滤
        
        if is_aggregation:
            sql = f"""-- 正则表达式路径的聚合查询变通实现
WITH extracted_keys AS (
    SELECT 
        json_keys(json_extract({column_name}, '$')) as keys_array,
        {column_name}
    FROM {self.table_name}
    WHERE {column_name} IS NOT NULL
),
matched_keys AS (
    SELECT 
        unnest(keys_array) as key_name,
        {column_name}
    FROM extracted_keys
    WHERE regexp_matches(unnest(keys_array), '{regex_pattern}')
),
final_values AS (
    SELECT 
        json_value({column_name}, '$.' || key_name) as value
    FROM matched_keys
    WHERE json_value({column_name}, '$.' || key_name) IS NOT NULL
)
SELECT 
    value,
    COUNT(*) as count,
    ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 2) as percentage
FROM final_values
GROUP BY value
ORDER BY count DESC
LIMIT 100;"""
        else:
            # 筛选查询
            filter_condition = ""
            if selected_values:
                escaped_values = [f'"\"{v.replace(chr(34), chr(92)+chr(34))}\""' for v in selected_values]
                values_str = ", ".join(escaped_values)
                filter_condition = f"AND final_value IN ({values_str})"
            
            sql = f"""-- 正则表达式路径的筛选查询变通实现
WITH extracted_keys AS (
    SELECT 
        json_keys(json_extract({column_name}, '$')) as keys_array,
        {column_name},
        *
    FROM {self.table_name}
    WHERE {column_name} IS NOT NULL
),
matched_data AS (
    SELECT 
        *,
        json_value({column_name}, '$.' || unnest(keys_array)) as final_value
    FROM extracted_keys
    WHERE regexp_matches(unnest(keys_array), '{regex_pattern}')
        {filter_condition}
)
SELECT * 
FROM matched_data
WHERE final_value IS NOT NULL
LIMIT 1000;"""
        
        return sql
    
    def generate_value_filter_sql(self, 
                                  column_name: str, 
                                  selected_values: List[str], 
                                  json_path: Optional[str] = None, 
                                  is_list_expanded: bool = False) -> str:
        """生成按值筛选的SQL语句
        
        Args:
            column_name: 列名
            selected_values: 选中的值列表
            json_path: JSON路径，如果是从JSON字段提取的数据
            is_list_expanded: 是否为列表展开的数据
            
        Returns:
            生成的SQL查询语句
        """
        if not selected_values:
            return ""
        
        # 构建WHERE条件
        if json_path and is_list_expanded:
            # 检查是否包含正则表达式，如果是，则使用变通实现
            if self._is_regex_pattern(json_path):
                return self.generate_regex_workaround_sql(column_name, json_path, selected_values, False)
            
            # 转换自定义路径格式为DuckDB格式
            duckdb_path = self._convert_custom_json_path_to_duckdb(json_path)
            
            # 列表展开场景：使用json_value函数和正确的引号处理
            condition_parts = []
            for value in selected_values:
                # DuckDB的json_value需要值带引号
                escaped_value = value.replace('"', '\\"')
                condition_parts.append(f"list_contains(json_value({column_name}, '{duckdb_path}'), '\"{escaped_value}\"')")
            where_condition = " OR ".join(condition_parts)
            
        elif is_list_expanded:
            # 列表展开但没有JSON路径的场景：直接对列使用list_contains
            condition_parts = []
            for value in selected_values:
                escaped_value = value.replace('"', '\\"')
                condition_parts.append(f"list_contains({column_name}, '{escaped_value}')")
            where_condition = " OR ".join(condition_parts)
            
        elif json_path:
            # 检查正则表达式
            if self._is_regex_pattern(json_path):
                return self.generate_regex_workaround_sql(column_name, json_path, selected_values, False)
            
            # 转换路径格式
            duckdb_path = self._convert_custom_json_path_to_duckdb(json_path)
            
            # 普通JSON路径提取场景：使用json_value
            if len(selected_values) == 1:
                escaped_value = selected_values[0].replace(chr(39), chr(39)+chr(39))
                where_condition = f"json_value({column_name}, '{duckdb_path}') = '\"{escaped_value}\"'"
            else:
                escaped_values = [f'"\"{v.replace(chr(34), chr(92)+chr(34))}\""' for v in selected_values]
                values_str = ", ".join(escaped_values)
                where_condition = f"json_value({column_name}, '{duckdb_path}') IN ({values_str})"
                
        else:
            # 普通列场景
            if len(selected_values) == 1:
                escaped_value = selected_values[0].replace(chr(39), chr(39)+chr(39))
                where_condition = f"{column_name} = '{escaped_value}'"
            else:
                escaped_values = [f"'{v.replace(chr(39), chr(39)+chr(39))}'" for v in selected_values]
                values_str = ", ".join(escaped_values)
                where_condition = f"{column_name} IN ({values_str})"
        
        # 生成完整SQL
        sql = f"""SELECT * 
FROM {self.table_name} 
WHERE {where_condition}
LIMIT 1000;"""
        
        return sql
    
    def generate_aggregation_sql(self, 
                                column_name: str, 
                                selected_values: List[str],
                                json_path: Optional[str] = None, 
                                is_list_expanded: bool = False) -> str:
        """生成聚合统计的SQL语句
        
        Args:
            column_name: 列名
            selected_values: 选中的值列表（用于筛选）
            json_path: JSON路径
            is_list_expanded: 是否为列表展开的数据
            
        Returns:
            生成的SQL聚合查询语句
        """
        if json_path and is_list_expanded:
            # 检查正则表达式
            if self._is_regex_pattern(json_path):
                return self.generate_regex_workaround_sql(column_name, json_path, selected_values, True)
            
            # 转换路径格式
            duckdb_path = self._convert_custom_json_path_to_duckdb(json_path)
            
            # 列表展开的聚合查询，使用json_value
            filter_condition = ""
            if selected_values:
                condition_parts = []
                for value in selected_values:
                    escaped_value = value.replace('"', '\\"')
                    condition_parts.append(f"unnested_value = '\"{escaped_value}\"'")
                filter_condition = f"WHERE {' OR '.join(condition_parts)}"
            
            sql = f"""SELECT 
    unnested_value as value,
    COUNT(*) as count,
    ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 2) as percentage
FROM (
    SELECT unnest(json_value({column_name}, '{duckdb_path}')) AS unnested_value
    FROM {self.table_name}
    WHERE json_value({column_name}, '{duckdb_path}') IS NOT NULL
) subquery
{filter_condition}
GROUP BY unnested_value
ORDER BY count DESC
LIMIT 100;"""
            
        elif is_list_expanded:
            # 列表展开但没有JSON路径的场景：直接对列使用unnest
            filter_condition = ""
            if selected_values:
                condition_parts = []
                for value in selected_values:
                    escaped_value = value.replace('"', '\\"')
                    condition_parts.append(f"unnested_value = '\"{escaped_value}\"'")
                filter_condition = f"WHERE {' OR '.join(condition_parts)}"
            
            sql = f"""SELECT 
    unnested_value as value,
    COUNT(*) as count,
    ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 2) as percentage
FROM (
    SELECT unnest({column_name}) AS unnested_value
    FROM {self.table_name}
    WHERE {column_name} IS NOT NULL
) subquery
{filter_condition}
GROUP BY unnested_value
ORDER BY count DESC
LIMIT 100;"""
            
        elif json_path:
            # 检查正则表达式
            if self._is_regex_pattern(json_path):
                return self.generate_regex_workaround_sql(column_name, json_path, selected_values, True)
            
            # 转换路径格式
            duckdb_path = self._convert_custom_json_path_to_duckdb(json_path)
            
            # 普通JSON路径聚合，使用json_value
            filter_condition = ""
            if selected_values:
                escaped_values = [f'"\"{v.replace(chr(34), chr(92)+chr(34))}\""' for v in selected_values]
                values_str = ", ".join(escaped_values)
                filter_condition = f"AND json_value({column_name}, '{duckdb_path}') IN ({values_str})"
            
            sql = f"""SELECT 
    json_value({column_name}, '{duckdb_path}') as value,
    COUNT(*) as count,
    ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM {self.table_name} WHERE json_value({column_name}, '{duckdb_path}') IS NOT NULL), 2) as percentage
FROM {self.table_name}
WHERE json_value({column_name}, '{duckdb_path}') IS NOT NULL {filter_condition}
GROUP BY json_value({column_name}, '{duckdb_path}')
ORDER BY count DESC
LIMIT 100;"""
            
        else:
            # 普通列聚合
            filter_condition = ""
            if selected_values:
                escaped_values = [f"'{v.replace(chr(39), chr(39)+chr(39))}'" for v in selected_values]
                values_str = ", ".join(escaped_values)
                filter_condition = f"AND {column_name} IN ({values_str})"
            
            sql = f"""SELECT 
    {column_name} as value,
    COUNT(*) as count,
    ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM {self.table_name} WHERE {column_name} IS NOT NULL), 2) as percentage
FROM {self.table_name}
WHERE {column_name} IS NOT NULL {filter_condition}
GROUP BY {column_name}
ORDER BY count DESC
LIMIT 100;"""
        
        return sql
    
    def render_sql_display(self, sql: str, title: str = "生成的SQL查询"):
        """渲染SQL显示区域
        
        Args:
            sql: SQL语句
            title: 显示标题
        """
        if not sql.strip():
            return
            
        st.subheader(title)
        
        # 显示SQL代码
        st.code(sql, language="sql")
        
        # 提供复制按钮功能（通过text_area实现）
        col1, col2 = st.columns([3, 1])
        
        with col1:
            st.text_area(
                "SQL语句（可复制）",
                value=sql,
                height=100,
                key=f"sql_copy_{hash(sql)}",
                help="您可以复制此SQL语句到SQL查询页面执行"
            )
        
        with col2:
            st.write("")
            st.write("")
            if st.button("📋 复制到剪贴板", key=f"copy_btn_{hash(sql)}"):
                # 使用streamlit的方式提示用户复制
                st.success("请从上方文本框中复制SQL语句")


class InteractiveDataFilter:
    """交互式数据筛选器
    
    提供分页展示和多选功能的数据筛选界面（已废弃，请使用data_paginator.InteractiveDataSelector）
    """
    
    def __init__(self, key_prefix: str):
        """初始化筛选器
        
        Args:
            key_prefix: streamlit组件的key前缀，确保唯一性
        """
        self.key_prefix = key_prefix
        # 导入新的组件
        from super_datascope.components.data_paginator import InteractiveDataSelector
        self.new_selector = InteractiveDataSelector(key_prefix)
    
    def render_paginated_selection(self, 
                                  data_series: pd.Series, 
                                  title: str = "数据选择",
                                  page_size: int = 20,
                                  show_stats: bool = True) -> List[str]:
        """渲染分页的多选界面（兼容性方法）
        
        Args:
            data_series: 要展示的数据Series
            title: 标题
            page_size: 每页显示的数量
            show_stats: 是否显示统计信息（已集成到新界面中）
            
        Returns:
            用户选中的值列表
        """
        # 使用新的选择器
        selected_values = self.new_selector.render_data_selector(
            data_series, title, page_size
        )
        
        # 显示选择总结
        if selected_values:
            self.new_selector.render_selection_summary(selected_values, data_series)
        
        return selected_values