"""
JSON路径提取组件
用于提供JSON路径输入界面和提取功能
"""

import streamlit as st
import pandas as pd
import json
import numpy as np
from super_datascope.common.lang_util import is_not_empty
from super_datascope.common.json_util import extract_json_by_path
from super_datascope import logger


class JsonPathExtractor:
    """JSON路径提取器组件"""
    
    def __init__(self, key_prefix: str = "json_path"):
        self.key_prefix = key_prefix
    
    def render(self, json_data, expanded: bool = False) -> dict:
        """
        渲染JSON路径提取界面
        
        Args:
            json_data: 要提取的JSON数据
            expanded: 是否默认展开
            
        Returns:
            dict: 包含提取结果和相关信息
        """
        result = {
            'extracted_data': json_data,
            'path_used': None,
            'success': False,
            'error': None
        }
        
        with st.expander("🔍 JSON路径提取设置", expanded=expanded):
            # 解析JSON数据
            try:
                if isinstance(json_data, str):
                    original_data = json.loads(json_data)
                elif isinstance(json_data, np.ndarray):
                    original_data = json_data.tolist()
                else:
                    original_data = json_data
            except json.JSONDecodeError:
                original_data = json_data
                st.warning("⚠️ 输入数据不是有效的JSON格式")
            
            # 键路径输入框
            col1, col2 = st.columns([3, 1])
            
            with col1:
                key_path = st.text_input(
                    "键路径 (支持点号分割、通配符*、正则r\"pattern\"、区间[start:end])",
                    placeholder="例如: key1.key2.key3 或 data.*.name 或 items.[0:5]",
                    key=f"{self.key_prefix}_path_input",
                    help="输入JSON路径来提取特定数据"
                )
            
            with col2:
                extract_btn = st.button(
                    "提取", 
                    key=f"{self.key_prefix}_extract_btn",
                    type="primary"
                )
            
            # 如果有键路径输入，进行提取
            if key_path and (extract_btn or key_path):
                try:
                    extracted_data = extract_json_by_path(original_data, key_path)
                    if extracted_data is not None:
                        st.success(f"✅ 成功提取路径: {key_path}")
                        result['extracted_data'] = extracted_data
                        result['path_used'] = key_path
                        result['success'] = True
                        
                        # 显示提取结果预览
                        if isinstance(extracted_data, (list, dict)):
                            st.write("**提取结果预览:**")
                            if isinstance(extracted_data, list) and len(extracted_data) > 5:
                                st.json(extracted_data[:5])
                                st.caption(f"显示前5项，共{len(extracted_data)}项")
                            else:
                                st.json(extracted_data)
                    else:
                        st.warning(f"⚠️ 路径未找到数据: {key_path}")
                        result['extracted_data'] = original_data
                        result['error'] = f"路径未找到数据: {key_path}"
                        
                except Exception as e:
                    st.error(f"❌ 路径提取失败: {e}")
                    result['extracted_data'] = original_data
                    result['error'] = str(e)
            else:
                result['extracted_data'] = original_data
            
            # 显示路径格式示例
            self._render_path_examples()
        
        return result
    
    def _render_path_examples(self):
        """渲染路径格式示例"""
        with st.expander("💡 路径格式示例", expanded=False):
            st.markdown("""
            **支持的路径格式：**
            
            - **普通路径**: `key1.key2.key3`
            - **带引号的键**: `key1."key with space".key3`  
            - **通配符**: `key1.*.key3` (返回数组)
            - **正则表达式**: `key1.r"^[0-3]$".key3` (返回数组)
            - **区间匹配**: `key1.[0:10].key3` (返回数组，适用于list/tuple)
            
            **示例数据结构参考：**
            ```json
            {
              "data": {
                "users": [
                  {"id": 0, "name": "Alice"},  
                  {"id": 1, "name": "Bob"}
                ],
                "0": {"value": "zero"},
                "1": {"value": "one"}
              }
            }
            ```
            
            **对应路径示例：**
            - `data.users.0.name` → `"Alice"`
            - `data.users.*.name` → `["Alice", "Bob"]`
            - `data.r"^[0-1]$".value` → `["zero", "one"]`
            - `data.users.[0:2].name` → `["Alice", "Bob"]`
            """)


def render_json_path_extractor(json_data, key_prefix: str = "json_path", expanded: bool = False) -> dict:
    """
    渲染JSON路径提取器的便捷函数
    
    Args:
        json_data: JSON数据
        key_prefix: 组件key前缀
        expanded: 是否默认展开
        
    Returns:
        dict: 提取结果
    """
    extractor = JsonPathExtractor(key_prefix)
    return extractor.render(json_data, expanded)


class JsonColumnAnalyzer:
    """JSON列分析器 - 集成路径提取和数据分析"""
    
    def __init__(self, df, json_column: str, key_prefix: str = "json_analyzer"):
        self.df = df
        self.json_column = json_column
        self.key_prefix = key_prefix
    
    def render(self):
        """渲染JSON列分析界面"""
        if self.json_column not in self.df.columns:
            st.error(f"列 '{self.json_column}' 不存在")
            return None
        
        st.subheader(f"🔬 JSON列分析: {self.json_column}")
        
        # 获取第一个非空的JSON数据作为示例
        sample_data = None
        for idx, row in self.df.iterrows():
            value = row[self.json_column]
            # if pd.notna(value) and str(value).strip():
            if is_not_empty(value):
                sample_data = value
                break
        
        if sample_data is None:
            st.warning("该JSON列没有可用的数据进行分析")
            return None
        
        st.info(f"📋 基于第{self.df.index[0]}行数据进行路径提取配置")
        
        # JSON路径提取器
        extractor_result = render_json_path_extractor(
            sample_data, 
            key_prefix=f"{self.key_prefix}_extractor",
            expanded=True
        )
        
        # 如果用户配置了路径提取，对整个列应用提取
        if extractor_result['success'] and extractor_result['path_used']:
            st.subheader("📊 批量提取结果")
            
            with st.spinner("正在对所有行应用路径提取..."):
                extracted_values = []
                success_count = 0
                
                for idx, row in self.df.iterrows():
                    try:
                        json_value = row[self.json_column]
                        if pd.notna(json_value):
                            # 解析JSON
                            if isinstance(json_value, str):
                                parsed_data = json.loads(json_value)
                            else:
                                parsed_data = json_value
                            
                            # 应用路径提取
                            extracted = extract_json_by_path(parsed_data, extractor_result['path_used'])
                            extracted_values.append(extracted)
                            if extracted is not None:
                                success_count += 1
                        else:
                            extracted_values.append(None)
                    except Exception as e:
                        logger.debug(f"第{idx}行提取失败: {e}")
                        extracted_values.append(None)
                
                # 显示提取统计
                st.metric("提取成功率", f"{success_count}/{len(self.df)} ({success_count/len(self.df)*100:.1f}%)")
                
                # 创建包含提取结果的DataFrame用于分析
                analysis_df = self.df.copy()
                analysis_df[f'{self.json_column}_extracted'] = extracted_values
                
                # 显示提取结果预览
                if success_count > 0:
                    st.subheader("🔍 提取结果预览")
                    
                    # 过滤掉None值进行预览
                    valid_extracts = [(i, v) for i, v in enumerate(extracted_values) if v is not None]
                    if valid_extracts:
                        # 只取前10条，确保两个数组长度一致
                        preview_extracts = valid_extracts[:10]
                        preview_data = pd.DataFrame({
                            '原始行索引': [item[0] for item in preview_extracts],
                            '提取结果': [item[1] for item in preview_extracts]
                        })
                        st.dataframe(preview_data, width='stretch')
                        
                        if len(valid_extracts) > 10:
                            st.caption(f"显示前10条，共{len(valid_extracts)}条有效提取结果")
                
                return {
                    'analysis_df': analysis_df,
                    'extracted_column': f'{self.json_column}_extracted',
                    'success_count': success_count,
                    'path_used': extractor_result['path_used']
                }
        
        return None