"""
表单基础信息处理节点

接收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 FormBasicInfoNode(BaseNode):
    """
    表单基础信息处理节点

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

    node_type = 'form_basic_info'
    node_name = '表单基础信息'
    node_category = 'form'
    node_icon = 'file-text'
    node_description = '处理表单基础信息，验证和补充表单名称、编码等'

    inputs = [
        {
            'name': 'name',
            'type': 'string',
            'description': '表单名称',
            'required': True,
        },
        {
            'name': 'code',
            'type': 'string',
            'description': '表单编码',
            'required': False,
        },
        {
            'name': 'form_type',
            'type': 'string',
            'description': '表单类型（normal/workflow）',
            'required': False,
        },
        {
            'name': 'description',
            'type': 'string',
            'description': '表单描述',
            'required': False,
        },
        {
            'name': 'sort',
            'type': 'number',
            'description': '排序',
            'required': False,
        },
    ]

    outputs = [
        {
            'name': 'form_basic_info',
            'type': 'object',
            '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'FormBasicInfoNode - 使用用户编辑的数据: {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', ''))
            form_type = context.resolve_template(self.config.get('form_type', 'normal'))
            description = context.resolve_template(self.config.get('description', ''))

            # 处理sort（可能是字符串或数字）
            sort_value = self.config.get('sort', 0)
            # 先转换为字符串，再调用resolve_template
            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'FormBasicInfoNode - 输入参数: name={name}, code={code}, form_type={form_type}')

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

            name = name.strip()

            # 自动生成编码（如果未提供或配置了自动生成）
            auto_generate = self.config.get('auto_generate_code', False)
            if not code or not code.strip() or auto_generate:
                code = self._generate_code(name)
                logger.info(f'自动生成编码: {code}')
            else:
                code = code.strip()

            # 验证编码格式
            if not re.match(r'^[a-z][a-z0-9_]*$', code):
                return NodeResult(
                    success=False,
                    error=f'表单编码格式不正确：{code}，必须以字母开头，只能包含小写字母、数字和下划线',
                )

            # 验证表单类型
            if form_type not in ['normal', 'workflow']:
                logger.warning(f'表单类型 {form_type} 不合法，使用默认值 normal')
                form_type = 'normal'

            # 构建输出
            basic_info = {
                'name': name,
                'code': code,
                'form_type': form_type,
                'description': description.strip() if description else name,
                'sort': sort,
            }

            logger.info(f'FormBasicInfoNode - 输出: {basic_info}')

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

            return self._build_result(basic_info, require_confirmation)

        except Exception as e:
            logger.exception(f'表单基础信息节点执行失败: {e}')
            return NodeResult(
                success=False,
                error=f'节点执行失败: {str(e)}',
            )

    async def execute_async(self, context: NodeContext) -> NodeResult:
        """异步执行节点（直接调用同步方法）"""
        return self.execute(context)

    def _parse_user_edit(self, user_input: Any) -> Optional[Dict[str, Any]]:
        """解析用户编辑的数据"""
        import json

        if isinstance(user_input, dict):
            # 检查是否包含表单基础信息字段
            if 'name' in user_input:
                return user_input
            return None

        if isinstance(user_input, str):
            try:
                data = json.loads(user_input)
                if isinstance(data, dict) and 'name' in data:
                    return data
            except (json.JSONDecodeError, TypeError):
                pass

        return None

    def _build_result(self, basic_info: Dict[str, Any], require_confirmation: bool = False) -> NodeResult:
        """构建节点结果"""
        name = basic_info.get('name', '')
        code = basic_info.get('code', '')
        form_type = basic_info.get('form_type', 'normal')
        description = basic_info.get('description', name)
        sort = basic_info.get('sort', 0)

        # 构建预览数据
        preview_data = {
            'type': 'form_basic_info',
            'title': '表单基础信息',
            'data': basic_info,
            'editable': True,
        } if require_confirmation else None

        return NodeResult(
            success=True,
            output=basic_info,
            output_variables={
                'form_basic_info': basic_info,
                'form_name': name,
                'form_code': code,
                'form_type': form_type,
                'form_description': description,
                'form_sort': sort,
            },
            preview=preview_data,
            waiting_for_input=require_confirmation,
            waiting_config={
                'type': 'design_preview',
                'preview_type': 'form_basic_info',
                'title': '表单基础信息',
                'message': '请确认或编辑表单基础信息',
                'data': basic_info,
            } if require_confirmation else {},
        )

    def _generate_code(self, name: str) -> str:
        """
        根据表单名称自动生成编码

        Args:
            name: 表单名称

        Returns:
            生成的编码
        """
        try:
            from pypinyin import lazy_pinyin

            # 将中文转拼音
            pinyin_list = lazy_pinyin(name)
            code = '_'.join(pinyin_list)
        except ImportError:
            logger.warning('pypinyin 未安装，使用简单的编码生成策略')
            # 如果没有安装 pypinyin，使用简单策略
            code = name.lower()

        # 只保留字母、数字和下划线
        code = re.sub(r'[^a-z0-9_]', '', code.lower())

        # 确保以字母开头
        if code and not code[0].isalpha():
            code = 'form_' + code

        # 如果为空，使用默认值
        if not code:
            code = 'form_default'

        return code

    @classmethod
    def get_config_schema(cls) -> Dict[str, Any]:
        """
        获取节点配置 Schema（供前端表单渲染）

        Returns:
            配置 Schema
        """
        return {
            'type': 'object',
            'properties': {
                'name': {
                    'type': 'string',
                    'title': '表单名称',
                    'description': '表单的显示名称，支持变量引用如 {{llm_basic_name}}',
                    'required': True,
                    'x-component': 'Input',
                    'x-component-props': {
                        'placeholder': '请输入表单名称或使用变量 {{llm_basic_name}}',
                    },
                },
                'code': {
                    'type': 'string',
                    'title': '表单编码',
                    'description': '表单的唯一编码，支持变量引用如 {{llm_basic_code}}',
                    'required': False,
                    'x-component': 'Input',
                    'x-component-props': {
                        'placeholder': '留空则自动生成，或使用变量 {{llm_basic_code}}',
                    },
                },
                'form_type': {
                    'type': 'string',
                    'title': '表单类型',
                    'description': '表单类型：normal（普通表单）或 workflow（工作流表单）',
                    'default': 'normal',
                    'enum': ['normal', 'workflow'],
                    'x-component': 'Select',
                    'x-component-props': {
                        'placeholder': '请选择表单类型',
                        'options': [
                            {'label': '普通表单', 'value': 'normal'},
                            {'label': '工作流表单', 'value': 'workflow'},
                        ],
                    },
                },
                'description': {
                    'type': 'string',
                    'title': '表单描述',
                    'description': '表单的详细描述，支持变量引用',
                    'required': False,
                    'x-component': 'Textarea',
                    'x-component-props': {
                        'placeholder': '请输入表单描述',
                        'rows': 3,
                    },
                },
                'sort': {
                    'type': 'number',
                    'title': '排序',
                    'description': '表单的排序值，数字越小越靠前',
                    'default': 0,
                    'x-component': 'InputNumber',
                    'x-component-props': {
                        'placeholder': '请输入排序值',
                        'min': 0,
                    },
                },
                'auto_generate_code': {
                    'type': 'boolean',
                    'title': '自动生成编码',
                    'description': '是否自动根据表单名称生成编码（拼音转换）',
                    'default': False,
                    'x-component': 'Switch',
                },
                'require_confirmation': {
                    'type': 'boolean',
                    'title': '需要确认',
                    'description': '设计完成后是否暂停等待用户确认或编辑',
                    'default': True,
                    'x-component': 'Switch',
                },
            },
            'required': ['name'],
        }
