"""
可复用的单元格查看器组件
封装了单元格内容的弹窗展示功能，支持JSON友好的展示控件
"""

import json
import pandas as pd
import streamlit as st


class CellViewer:
    """单元格内容查看器"""
    
    def __init__(self):
        """初始化单元格查看器"""
        pass
    
    def display_modal(self, value, column_name):
        """
        在模态框中显示单元格的完整值，支持JSON友好的展示控件
        
        Args:
            value: 单元格的值
            column_name (str): 列名
        
        Returns:
            function: 模态框显示函数
        """
        @st.dialog(f"📋 {column_name} - 单元格内容查看器", width="large")
        def show_cell_content():
            # 创建标签页
            tab1, tab2, tab3 = st.tabs(["🎯 格式化视图", "📝 原始内容", "📊 数据统计"])
            
            with tab1:
                self._render_formatted_view(value)
            
            with tab2:
                self._render_raw_content(value)
            
            with tab3:
                self._render_statistics(value)
        
        return show_cell_content
    
    def _render_formatted_view(self, value):
        """渲染格式化视图"""
        st.markdown("### 💫 格式化展示")
        
        # 尝试解析JSON并提供多种展示方式
        try:
            if isinstance(value, str) and (value.strip().startswith('{') or value.strip().startswith('[')):
                parsed_value = json.loads(value)
                
                # 默认使用交互式JSON树展示，避免使用会触发重渲染的st.radio
                st.json(parsed_value)
                
                # 同时提供代码格式展示
                with st.expander("📄 查看格式化代码", expanded=False):
                    formatted_json = json.dumps(parsed_value, ensure_ascii=False, indent=2)
                    st.code(formatted_json, language='json', line_numbers=True)
                
                # 如果是聊天消息列表，提供特殊展示
                if isinstance(parsed_value, list) and len(parsed_value) > 0:
                    if isinstance(parsed_value[0], dict) and any(key in parsed_value[0] for key in ['role', 'content', 'message']):
                        with st.expander("💬 聊天消息视图", expanded=True):
                            self._render_chat_messages(parsed_value)
            
            else:
                # 非JSON数据的智能展示
                self._render_non_json_content(value)
                
        except json.JSONDecodeError as e:
            st.error(f"❌ JSON解析失败: {str(e)}")
            st.code(str(value), language='text', line_numbers=True)
        except Exception as e:
            st.error(f"❌ 显示内容时出错: {str(e)}")
            st.text(str(value))
    
    def _render_chat_messages(self, parsed_value):
        """渲染聊天消息列表"""
        st.markdown("---")
        st.markdown("### 💬 聊天消息视图")
        
        for i, msg in enumerate(parsed_value):
            role = msg.get('role', 'unknown')
            content = msg.get('content', msg.get('message', ''))
            
            # 根据角色使用不同的样式
            if role == 'user':
                st.markdown(f"**👤 用户** (消息 {i+1})")
                st.info(str(content))
            elif role == 'assistant':
                st.markdown(f"**🤖 助手** (消息 {i+1})")
                st.success(str(content))
            else:
                st.markdown(f"**🔹 {role}** (消息 {i+1})")
                st.write(str(content))
            
            if i < len(parsed_value) - 1:
                st.markdown("---")
    
    def _render_non_json_content(self, value):
        """渲染非JSON内容"""
        value_str = str(value)
        
        if len(value_str) > 1000:
            st.warning(f"⚠️ 内容较长 ({len(value_str)} 字符)，已截断显示前1000字符")
            st.code(value_str[:1000] + "\n...[内容被截断]...", language='text', line_numbers=True)
        else:
            st.code(value_str, language='text', line_numbers=True)
    
    def _render_raw_content(self, value):
        """渲染原始内容"""
        st.markdown("### 📝 原始内容")
        
        # 显示原始内容
        raw_content = str(value)
        st.text_area(
            "原始数据：", 
            raw_content, 
            height=400,
            help="这是未经任何处理的原始数据内容",
            key=f"raw_content_{id(value)}_{hash(raw_content)}"  # 使用唯一key避免冲突
        )
        
        # 显示提示信息而不是可点击按钮，避免触发重渲染
        st.info("💡 可以直接从上方文本框中选择和复制内容")
    
    def _render_statistics(self, value):
        """渲染数据统计信息"""
        st.markdown("### 📊 数据统计信息")
        
        # 基础统计
        raw_str = str(value)
        
        col1, col2, col3, col4 = st.columns(4)
        with col1:
            st.metric("字符数", len(raw_str))
        with col2:
            st.metric("行数", raw_str.count('\n') + 1)
        with col3:
            st.metric("数据类型", type(value).__name__)
        with col4:
            st.metric("大小 (bytes)", len(raw_str.encode('utf-8')))
        
        # JSON特定统计
        try:
            if isinstance(value, str) and (value.strip().startswith('{') or value.strip().startswith('[')):
                parsed_value = json.loads(value)
                self._render_json_statistics(parsed_value)
        except:
            st.info("💡 非JSON格式数据")
        
        # 内容预览
        st.markdown("#### 📄 内容预览")
        preview_length = min(200, len(raw_str))
        st.code(raw_str[:preview_length] + ("..." if len(raw_str) > preview_length else ""), language='text')
    
    def _render_json_statistics(self, parsed_value):
        """渲染JSON统计信息"""
        st.markdown("#### 🔍 JSON结构分析")
        
        if isinstance(parsed_value, dict):
            st.write(f"**对象类型**: 字典 (包含 {len(parsed_value)} 个键)")
            
            # 显示键列表
            if len(parsed_value) > 0:
                keys_df = pd.DataFrame({
                    '键名': list(parsed_value.keys()),
                    '值类型': [type(v).__name__ for v in parsed_value.values()],
                    '值长度': [len(str(v)) for v in parsed_value.values()]
                })
                st.dataframe(keys_df, width='stretch')
            
        elif isinstance(parsed_value, list):
            st.write(f"**数组类型**: 列表 (包含 {len(parsed_value)} 个元素)")
            
            if len(parsed_value) > 0:
                element_types = {}
                for item in parsed_value:
                    item_type = type(item).__name__
                    element_types[item_type] = element_types.get(item_type, 0) + 1
                
                types_df = pd.DataFrame({
                    '元素类型': list(element_types.keys()),
                    '数量': list(element_types.values())
                })
                st.dataframe(types_df, width='stretch')


def create_cell_viewer():
    """
    创建单元格查看器的便捷函数
    
    Returns:
        CellViewer: 单元格查看器实例
    """
    return CellViewer()