"""
仪表盘基础信息处理节点

接收LLM提取的基础信息，进行验证和补充
"""
import logging
import re
from typing import Any, Dict, Optional

from ..base import BaseNode, NodeContext, NodeResult
from ..registry import NodeRegistry

logger = logging.getLogger(__name__)


@NodeRegistry.register
class DashboardBasicInfoNode(BaseNode):
    """
    仪表盘基础信息处理节点

    接收LLM提取的基础信息，进行验证和补充
    """

    node_type = 'dashboard_basic_info'
    node_name = '仪表盘基础信息'
    node_category = 'dashboard'
    node_icon = 'layout-dashboard'
    node_description = '处理仪表盘基础信息，验证和补充名称、编码等'

    inputs = [
        {
            'name': 'name',
            'type': 'string',
            'description': '仪表盘名称',
            'required': True,
        },
        {
            'name': 'code',
            'type': 'string',
            'description': '仪表盘编码',
            'required': False,
        },
        {
            'name': 'category',
            'type': 'string',
            'description': '分类（dashboard/portal/databoard/other）',
            'required': False,
        },
        {
            'name': 'description',
            'type': 'string',
            'description': '仪表盘描述',
            'required': False,
        },
        {
            'name': 'sort',
            'type': 'number',
            'description': '排序',
            'required': False,
        },
    ]

    outputs = [
        {
            'name': 'dashboard_basic_info',
            'type': 'object',
            'description': '处理后的仪表盘基础信息',
        },
        {
            'name': 'dashboard_name',
            'type': 'string',
            'description': '仪表盘名称',
        },
        {
            'name': 'dashboard_code',
            'type': 'string',
            'description': '仪表盘编码',
        },
    ]

    def execute(self, context: NodeContext) -> NodeResult:
        """执行节点"""
        try:
            # 检查是否有用户编辑的数据（从设计预览面板提交）
            user_input = context.variables.get('__user_input__')
            if user_input:
                edited_data = self._parse_user_edit(user_input)
                if edited_data:
                    logger.info(f'DashboardBasicInfoNode - 使用用户编辑的数据: {edited_data}')
                    # 使用编辑后的数据，清除用户输入
                    context.variables.pop('__user_input__', None)
                    return self._build_result(edited_data, require_confirmation=False)

            # 获取输入参数
            name = context.resolve_template(self.config.get('name', ''))
            code = context.resolve_template(self.config.get('code', ''))
            category = context.resolve_template(self.config.get('category', 'dashboard'))
            description = context.resolve_template(self.config.get('description', ''))

            # 处理sort（可能是字符串或数字）
            sort_value = self.config.get('sort', 0)
            sort_str = context.resolve_template(str(sort_value))
            try:
                sort = int(sort_str) if sort_str else 0
            except (ValueError, TypeError):
                sort = 0

            logger.info(f'DashboardBasicInfoNode - 输入参数: name={name}, code={code}, category={category}')

            # 验证必填字段
            if not name:
                return NodeResult(
                    success=False,
                    error='仪表盘名称不能为空',
                )

            # 自动生成编码（如果未提供）
            if not code:
                code = self._generate_code(name)

            # 验证编码格式
            if not self._validate_code(code):
                return NodeResult(
                    success=False,
                    error=f'仪表盘编码格式不正确: {code}，只能包含字母、数字、下划线和连字符',
                )

            # 验证分类
            valid_categories = ['dashboard', 'portal', 'databoard', 'other']
            if category and category not in valid_categories:
                category = 'dashboard'

            # 构建基础信息
            basic_info = {
                'name': name,
                'code': code,
                'category': category or 'dashboard',
                'description': description or '',
                'sort': sort,
            }

            # 检查是否需要确认（支持布尔值、字符串模式和变量引用）
            require_confirmation = self.resolve_require_confirmation(context, default=True)

            return self._build_result(basic_info, require_confirmation)

        except Exception as e:
            logger.error(f'DashboardBasicInfoNode - 执行失败: {str(e)}')
            return NodeResult(
                success=False,
                error=f'处理仪表盘基础信息失败: {str(e)}',
            )

    def _parse_user_edit(self, user_input: str) -> Optional[Dict[str, Any]]:
        """解析用户编辑的数据"""
        try:
            import json
            if isinstance(user_input, str):
                data = json.loads(user_input)
            else:
                data = user_input

            # 验证必要字段
            if isinstance(data, dict) and data.get('name'):
                return data
            return None
        except Exception:
            return None

    def _build_result(self, basic_info: Dict[str, Any], require_confirmation: bool) -> NodeResult:
        """构建节点结果"""
        output_data = {
            'dashboard_basic_info': basic_info,
            'dashboard_name': basic_info.get('name', ''),
            'dashboard_code': basic_info.get('code', ''),
        }

        if require_confirmation:
            return NodeResult(
                success=True,
                output=output_data,
                output_variables=output_data,  # 添加 output_variables
                waiting_for_input=True,
                waiting_config={
                    'type': 'design_preview',
                    'preview_type': 'dashboard_basic_info',
                    'title': '仪表盘基础信息确认',
                    'data': basic_info,
                    'editable': True,
                    'fields': [
                        {'key': 'name', 'label': '仪表盘名称', 'type': 'text', 'required': True},
                        {'key': 'code', 'label': '仪表盘编码', 'type': 'text', 'required': True},
                        {'key': 'category', 'label': '分类', 'type': 'select', 'options': [
                            {'label': '仪表盘', 'value': 'dashboard'},
                            {'label': '门户', 'value': 'portal'},
                            {'label': '数据看板', 'value': 'databoard'},
                            {'label': '其他', 'value': 'other'},
                        ]},
                        {'key': 'description', 'label': '描述', 'type': 'textarea'},
                        {'key': 'sort', 'label': '排序', 'type': 'number'},
                    ],
                },
            )

        return NodeResult(
            success=True,
            output=output_data,
            output_variables=output_data,  # 添加 output_variables
        )

    def _generate_code(self, name: str) -> str:
        """根据名称生成编码"""
        try:
            from pypinyin import lazy_pinyin
            # 使用拼音生成编码
            pinyin_list = lazy_pinyin(name)
            code = '_'.join(pinyin_list)
            # 清理非法字符
            code = re.sub(r'[^a-zA-Z0-9_]', '', code)
            return f'page_{code}'
        except ImportError:
            # 如果没有pypinyin，使用简单的处理
            code = re.sub(r'[^a-zA-Z0-9_]', '', name)
            return f'page_{code}' if code else f'page_{id(name)}'

    def _validate_code(self, code: str) -> bool:
        """验证编码格式"""
        if not code:
            return False
        # 只允许字母、数字、下划线和连字符
        pattern = r'^[a-zA-Z][a-zA-Z0-9_-]*$'
        return bool(re.match(pattern, code))
