"""
列表UI设计节点

根据表单UI设计配置自动生成列表配置
"""
import json
import logging
import re
import uuid
from typing import Any, Dict, List, Optional, Tuple

from ..base import BaseNode, NodeContext, NodeResult
from ..registry import NodeRegistry
from ..utils.config_utils import resolve_object_config

logger = logging.getLogger(__name__)


@NodeRegistry.register
class FormListDesignNode(BaseNode):
    """
    列表UI设计节点

    根据表单UI设计配置自动生成列表配置，包括：
    - 查询字段配置
    - 列表列配置
    - 表格属性配置
    - 按钮配置
    """

    node_type = 'form_list_design'
    node_name = '列表UI设计'
    node_category = 'form'
    node_icon = 'table'
    node_description = '根据表单UI设计自动生成列表配置'

    # ========== 查询字段推断规则 ==========
    # 默认添加为查询字段的字段模式
    QUERY_INCLUDE_PATTERNS = [
        r'^(name|title|code|no|status|type|category)$',
        r'(creator|modifier)_id$',
    ]

    # name 相关字段模式（优先级最高，作为第一个查询字段）
    NAME_FIELD_PATTERNS = [
        r'^name$',
        r'_name$',
        r'^title$',
    ]

    # 排除的查询字段模式
    QUERY_EXCLUDE_PATTERNS = [
        r'^id$',
        r'^is_deleted$',
        r'^sort$',
        r'(remark|note|description|content|address)$',
        r'(password|pwd|secret)$',
    ]

    # ========== 列表列推断规则 ==========
    # 默认显示的列模式
    COLUMN_INCLUDE_PATTERNS = [
        r'^(name|title|code|no|status|type|category)$',
        r'(amount|price|count|quantity|total)$',
        r'sys_create_datetime$',
    ]

    # 排除的列模式
    COLUMN_EXCLUDE_PATTERNS = [
        r'^id$',
        r'^is_deleted$',
        r'^sort$',
        r'(password|pwd|secret)$',
        r'^sys_(creator|modifier|dept)_id$',
    ]

    # 固定在左侧的列模式
    FIXED_LEFT_PATTERNS = [
        r'^(name|title|code)$',
    ]

    inputs = [
        {
            'name': 'form_ui_design',
            'type': 'object',
            'description': '表单UI设计配置（来自表单UI设计节点）',
            'required': True,
        },
        {
            'name': 'database_design',
            'type': 'object',
            'description': '数据库设计配置（可选，用于补充字段信息）',
            'required': False,
        },
    ]

    outputs = [
        {
            'name': 'list_config',
            'type': 'object',
            'description': '完整的列表配置',
        },
        {
            'name': 'query_field_count',
            'type': 'number',
            'description': '查询字段数量',
        },
        {
            'name': 'column_count',
            'type': 'number',
            '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'FormListDesignNode - 使用用户编辑的数据')
                    context.variables.pop('__user_input__', None)
                    return self._build_result_from_edit(edited_data)

            # 获取配置
            form_ui_design = resolve_object_config(
                context, self.config.get('form_ui_design', '{}')
            )
            database_design = resolve_object_config(
                context, self.config.get('database_design', '{}')
            )

            # 列表配置选项
            auto_query_fields = self.config.get('auto_query_fields', True)
            auto_columns = self.config.get('auto_columns', True)
            container_type = self.config.get('container_type', 'drawer')
            page_size = self.config.get('page_size', 20)
            show_index = self.config.get('show_index', True)
            show_selection = self.config.get('show_selection', True)
            enable_export = self.config.get('enable_export', True)
            enable_import = self.config.get('enable_import', False)

            logger.info(f'FormListDesignNode - 开始生成列表配置')

            # 解析表单UI设计
            if not form_ui_design:
                return NodeResult(
                    success=False,
                    error='表单UI设计配置解析失败或为空',
                )

            # 解析数据库设计（可选）

            # 获取表单项
            form_items = form_ui_design.get('items', [])
            if not form_items:
                return NodeResult(
                    success=False,
                    error='表单项列表为空',
                )

            # 提取表单字段列表（用于前端列表设计组件）
            form_fields = self._extract_form_fields(form_items, database_design)

            # 生成查询字段
            query_fields = []
            if auto_query_fields:
                query_fields = self._generate_query_fields(form_items)

            # 生成列表列
            columns = []
            if auto_columns:
                columns = self._generate_columns(form_items, database_design)

            # 构建列表配置
            list_config = {
                'queryFields': query_fields,
                'columns': columns,
                'containerType': container_type,
                'table': {
                    'showPagination': True,
                    'pageSize': page_size,
                    'showIndex': show_index,
                    'showSelection': show_selection,
                    'stripe': True,
                    'border': True,
                    'size': 'default',
                    'height': 'auto',
                    'defaultSort': [],
                    'showSummary': False,
                    'summaryType': 'sum',
                    'summaryPrecision': 2,
                },
                'dialog': {
                    'width': '800px',
                    'fullscreen': False,
                    'draggable': True,
                    'closeOnClickModal': False,
                    'closeOnPressEscape': True,
                },
                'drawer': {
                    'size': '800px',
                    'direction': 'rtl',
                    'withHeader': True,
                    'closeOnClickModal': False,
                    'closeOnPressEscape': True,
                },
                'page': {
                    'showBackButton': True,
                    'openInNewTab': True,
                },
                'buttons': {
                    'showAdd': True,
                    'showEdit': True,
                    'showDelete': True,
                    'showView': True,
                    'showExport': enable_export,
                    'showImport': enable_import,
                    'showBatchDelete': True,
                },
            }

            query_field_count = len(query_fields)
            column_count = len(columns)

            logger.info(f'FormListDesignNode - 列表配置生成完成: 查询字段数: {query_field_count}, 列数: {column_count}')

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

            # 构建预览数据（包含 form_fields 供前端列表设计组件使用）
            preview_data = {
                'type': 'list_config',
                'title': '列表UI设计',
                'data': list_config,
                'form_fields': form_fields,
                'editable': True,
            } if require_confirmation else None

            return NodeResult(
                success=True,
                output=list_config,
                output_variables={
                    'list_config': list_config,
                    'form_fields': form_fields,
                    'query_field_count': query_field_count,
                    'column_count': column_count,
                },
                preview=preview_data,
                waiting_for_input=require_confirmation,
                waiting_config={
                    'type': 'design_preview',
                    'preview_type': 'list_config',
                    'title': '列表UI设计',
                    'message': '请确认或编辑列表UI设计',
                    'data': list_config,
                    'form_fields': form_fields,
                } if require_confirmation else {},
            )

        except Exception as e:
            logger.exception(f'列表UI设计节点执行失败: {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]]:
        """解析用户编辑的数据"""
        if isinstance(user_input, dict):
            if 'columns' in user_input or 'queryFields' in user_input:
                return user_input
            return None

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

        return None

    def _build_result_from_edit(self, edited_data: Dict[str, Any]) -> NodeResult:
        """从用户编辑的数据构建节点结果"""
        query_fields = edited_data.get('queryFields', [])
        columns = edited_data.get('columns', [])

        return NodeResult(
            success=True,
            output=edited_data,
            output_variables={
                'list_config': edited_data,
                'query_field_count': len(query_fields),
                'column_count': len(columns),
            },
        )

    def _parse_config(self, config_str: Any) -> Optional[Dict]:
        """解析配置"""
        if isinstance(config_str, dict):
            return config_str

        if isinstance(config_str, str):
            config_str = config_str.strip()
            if not config_str or config_str == '{}':
                return None

            try:
                return json.loads(config_str)
            except json.JSONDecodeError:
                import ast
                try:
                    return ast.literal_eval(config_str)
                except (ValueError, SyntaxError):
                    return None

        return None

    def _extract_form_fields(self, form_items: List[Dict], database_design: Optional[Dict] = None) -> List[Dict]:
        """
        从表单项中提取字段列表，供前端列表设计组件使用

        Args:
            form_items: 表单项列表
            database_design: 数据库设计配置（可选，用于获取字段类型）

        Returns:
            字段列表，每个字段包含 label, field, component, options, props, dbType 等
        """
        fields = []

        # 获取数据库字段类型映射
        db_field_types = {}
        if database_design:
            table_data = database_design.get('table', database_design)
            db_fields = table_data.get('fields', [])
            for db_field in db_fields:
                db_field_types[db_field.get('name', '')] = db_field.get('type', '')

        def extract_from_items(items: List[Dict]):
            """递归提取字段"""
            for item in items:
                item_type = item.get('type', '')

                # 跳过布局组件，递归处理其子元素
                if item_type in ['grid', 'row', 'card', 'tabs', 'collapse', 'divider', 'alert', 'timeline', 'text', 'html', 'spacer', 'title', 'steps']:
                    if item.get('children'):
                        extract_from_items(item.get('children', []))
                    if item.get('columns'):
                        for col in item.get('columns', []):
                            if col.get('children'):
                                extract_from_items(col.get('children', []))
                    if item.get('items'):
                        for sub_item in item.get('items', []):
                            if sub_item.get('children'):
                                extract_from_items(sub_item.get('children', []))
                    continue

                # 提取有字段名的组件
                field_name = item.get('field', '')
                if field_name:
                    db_type = db_field_types.get(field_name, '')
                    fields.append({
                        'label': item.get('label', field_name),
                        'field': field_name,
                        'component': item_type,
                        'options': item.get('options', []),
                        'props': item.get('props', {}),
                        'dbType': db_type,
                        'isNumeric': db_type.lower() in ['int', 'integer', 'bigint', 'smallint', 'decimal', 'numeric', 'float', 'double', 'real'],
                    })

        extract_from_items(form_items)

        # 添加系统字段
        system_fields = [
            {'name': 'sys_create_datetime', 'label': '创建时间', 'component': 'date-picker', 'dbType': 'timestamp'},
            {'name': 'sys_update_datetime', 'label': '更新时间', 'component': 'date-picker', 'dbType': 'timestamp'},
            {'name': 'sys_creator_id', 'label': '创建人', 'component': 'user-select', 'dbType': 'varchar'},
            {'name': 'sys_modifier_id', 'label': '修改人', 'component': 'user-select', 'dbType': 'varchar'},
            {'name': 'sys_dept_id', 'label': '所属部门', 'component': 'dept-select', 'dbType': 'varchar'},
        ]

        existing_field_names = [f['field'] for f in fields]
        for sys_field in system_fields:
            if sys_field['name'] not in existing_field_names:
                fields.append({
                    'label': sys_field['label'],
                    'field': sys_field['name'],
                    'component': sys_field['component'],
                    'options': [],
                    'props': {},
                    'dbType': sys_field['dbType'],
                    'isNumeric': False,
                    'isSystemField': True,
                })

        return fields

    def _generate_query_fields(self, form_items: List[Dict]) -> List[Dict]:
        """生成查询字段配置"""
        name_fields = []  # name 相关字段（优先级最高）
        other_fields = []  # 其他查询字段

        for item in form_items:
            field_name = item.get('field', '')
            if not field_name:
                continue

            # 检查是否应该排除
            if self._matches_patterns(field_name, self.QUERY_EXCLUDE_PATTERNS):
                continue

            # 检查是否为 name 相关字段
            is_name_field = self._matches_patterns(field_name, self.NAME_FIELD_PATTERNS)

            # 检查是否应该包含
            should_include = False
            if is_name_field:
                should_include = True
            elif self._matches_patterns(field_name, self.QUERY_INCLUDE_PATTERNS):
                should_include = True
            else:
                # 如果不在包含列表中，检查是否是常用查询字段
                component = item.get('type', 'input')
                # 选择类组件通常需要查询
                if component in ['select', 'radio', 'checkbox', 'user-selector', 'dept-selector', 'date']:
                    should_include = True

            if not should_include:
                continue

            # 生成查询字段配置
            query_field = self._build_query_field(item)
            if query_field:
                # name 字段放在前面，其他字段放在后面
                if is_name_field:
                    name_fields.append(query_field)
                else:
                    other_fields.append(query_field)

        # name 字段排在最前面
        return name_fields + other_fields

    def _build_query_field(self, item: Dict) -> Optional[Dict]:
        """构建单个查询字段配置"""
        field_name = item.get('field', '')
        label = item.get('label', field_name)
        component = item.get('type', 'input')
        props = item.get('props', {})
        options = item.get('options', [])

        # 推断查询组件类型
        query_component = self._infer_query_component(component)

        # 推断查询类型
        query_type = self._infer_query_type(component, field_name)

        # 判断是否为日期时间类型
        is_datetime = component in ['date', 'datetime'] or props.get('type') in ['datetime', 'datetimerange']

        return {
            'label': label,
            'field': field_name,
            'type': query_type,
            'component': query_component,
            'originalComponent': component,
            'options': options,
            'props': props,
            'dbType': '',
            'width': 6,
            'defaultValue': '',
            'hidden': False,
            'multiple': props.get('multiple', False),
            'showTime': is_datetime,
        }

    def _infer_query_component(self, component: str) -> str:
        """推断查询组件类型"""
        # 用户/部门/岗位选择器保持原组件
        if component in ['user-selector', 'dept-selector', 'role-selector', 'post-selector']:
            return component

        # 带选项的组件映射为 select
        if component in ['select', 'radio', 'checkbox', 'cascader', 'tree-select']:
            return 'select'

        # 日期类组件保持日期选择
        if component in ['date', 'datetime', 'date-picker', 'time']:
            return 'date'

        # 其他组件默认使用输入框
        return 'input'

    def _infer_query_type(self, component: str, field_name: str) -> str:
        """推断查询类型"""
        # 用户/部门/岗位选择器使用 in 查询
        if component in ['user-selector', 'dept-selector', 'role-selector', 'post-selector']:
            return 'in'

        # 选项组件默认精确匹配
        if component in ['select', 'radio', 'checkbox', 'cascader', 'tree-select']:
            return 'eq'

        # 日期类组件默认范围查询
        if component in ['date', 'datetime', 'date-picker', 'time']:
            return 'range'

        # 文本类默认模糊匹配
        return 'like'

    def _generate_columns(self, form_items: List[Dict], database_design: Optional[Dict]) -> List[Dict]:
        """生成列表列配置"""
        columns = []

        # 获取数据库字段信息（用于补充类型信息）
        db_fields = {}
        if database_design:
            table_info = database_design.get('table', {})
            for field in table_info.get('fields', []):
                db_fields[field.get('name', '')] = field

        for item in form_items:
            field_name = item.get('field', '')
            if not field_name:
                continue

            # 检查是否应该排除
            if self._matches_patterns(field_name, self.COLUMN_EXCLUDE_PATTERNS):
                continue

            # 生成列配置
            column = self._build_column(item, db_fields.get(field_name, {}))
            if column:
                columns.append(column)

        return columns

    def _build_column(self, item: Dict, db_field: Dict) -> Optional[Dict]:
        """构建单个列配置"""
        field_name = item.get('field', '')
        label = item.get('label', field_name)
        component = item.get('type', 'input')
        props = item.get('props', {})
        options = item.get('options', [])

        # 判断是否为数值类型
        db_type = db_field.get('type', '')
        is_numeric = self._is_numeric_type(db_type)

        # 判断是否为选项组件
        has_options = component in ['select', 'radio', 'checkbox', 'cascader', 'tree-select']

        # 判断是否为关联组件
        is_relation = component in ['user-selector', 'dept-selector', 'role-selector', 'post-selector']

        # 判断是否固定在左侧
        fixed = 'left' if self._matches_patterns(field_name, self.FIXED_LEFT_PATTERNS) else False

        # 推断对齐方式
        align = 'right' if is_numeric else ('center' if component in ['date', 'datetime', 'switch'] else 'left')

        # 判断是否为日期时间类型
        is_datetime = db_type.lower() in ['datetime', 'timestamp'] or component in ['datetime']

        # 推断过滤类型
        filter_type = self._infer_filter_type(component)

        # 深拷贝选项并添加 tagType
        cloned_options = None
        if options:
            cloned_options = [
                {**opt, 'tagType': opt.get('tagType', '')}
                for opt in options
            ]

        return {
            'label': label,
            'field': field_name,
            # 排序配置
            'sortable': not self._is_no_sort_component(component),
            'sortType': 'backend',
            # 过滤配置
            'filterable': False,
            'filterType': filter_type,
            'filterQueryType': 'range',
            'filterShowTime': is_datetime,
            'filterMultiple': True,
            # 列显示配置
            'fixed': fixed,
            'align': align,
            'width': '',
            'minWidth': '',
            'resizable': True,
            'showOverflowTooltip': True,
            'ellipsis': True,
            'formatter': 'none',
            'formatPattern': '',
            'prefix': '',
            'suffix': '',
            # 选项显示
            'originalComponent': component,
            'options': cloned_options,
            'showAsTag': has_options,
            # 关联字段
            'isRelation': is_relation,
            'showDisplayName': is_relation,
            'displayField': self._generate_display_field(field_name) if is_relation else '',
            # 统计
            'dbType': db_type,
            'isNumeric': is_numeric,
            'summaryEnabled': False,
        }

    def _infer_filter_type(self, component: str) -> str:
        """推断过滤类型"""
        if component in ['date', 'datetime', 'date-picker']:
            return 'date-range'
        elif component in ['user-selector', 'user-select']:
            return 'user-select'
        elif component in ['dept-selector', 'dept-select', 'department-selector']:
            return 'dept-select'
        elif component in ['select', 'radio', 'checkbox', 'cascader', 'tree-select']:
            return 'select'
        return 'input'

    def _is_numeric_type(self, db_type: str) -> bool:
        """判断是否为数值类型"""
        if not db_type:
            return False
        db_type_lower = db_type.lower()
        return any(t in db_type_lower for t in ['int', 'decimal', 'numeric', 'float', 'double', 'real', 'money'])

    def _is_no_sort_component(self, component: str) -> bool:
        """判断是否为不支持排序的组件类型"""
        return component in ['file-selector', 'image-selector', 'rich-text', 'textarea']

    def _generate_display_field(self, field_name: str) -> str:
        """生成显示字段名"""
        if field_name.endswith('_id'):
            return field_name.replace('_id', '_name')
        if field_name.endswith('Id'):
            return field_name.replace('Id', 'Name')
        return f'{field_name}_name'

    def _matches_patterns(self, field_name: str, patterns: List[str]) -> bool:
        """检查字段名是否匹配任一模式"""
        field_name_lower = field_name.lower()
        for pattern in patterns:
            if re.search(pattern, field_name_lower):
                return True
        return False

    @classmethod
    def get_config_schema(cls) -> Dict[str, Any]:
        """获取节点配置 Schema"""
        return {
            'type': 'object',
            'properties': {
                'form_ui_design': {
                    'type': 'string',
                    'title': '表单UI设计配置',
                    'description': '来自表单UI设计节点的输出',
                    'x-component': 'SmartInput',
                },
                'database_design': {
                    'type': 'string',
                    'title': '数据库设计配置',
                    'description': '来自数据库设计节点的输出（可选，用于补充字段类型信息）',
                    'x-component': 'SmartInput',
                },
                'auto_query_fields': {
                    'type': 'boolean',
                    'title': '自动生成查询字段',
                    'description': '根据表单字段自动生成查询条件',
                    'default': True,
                    'x-component': 'Switch',
                },
                'auto_columns': {
                    'type': 'boolean',
                    'title': '自动生成列配置',
                    'description': '根据表单字段自动生成列表列',
                    'default': True,
                    'x-component': 'Switch',
                },
                'container_type': {
                    'type': 'string',
                    'title': '容器类型',
                    'description': '表单编辑的容器类型',
                    'default': 'drawer',
                    'enum': ['drawer', 'dialog', 'page'],
                    'enumNames': ['抽屉', '弹窗', '页面'],
                    'x-component': 'Select',
                },
                'page_size': {
                    'type': 'number',
                    'title': '每页条数',
                    'description': '列表每页显示的数据条数',
                    'default': 20,
                    'enum': [10, 20, 50, 100],
                    'x-component': 'Select',
                },
                'show_index': {
                    'type': 'boolean',
                    'title': '显示序号列',
                    'description': '是否显示行序号',
                    'default': True,
                    'x-component': 'Switch',
                },
                'show_selection': {
                    'type': 'boolean',
                    'title': '显示选择列',
                    'description': '是否显示多选框列',
                    'default': True,
                    'x-component': 'Switch',
                },
                'enable_export': {
                    'type': 'boolean',
                    'title': '启用导出',
                    'description': '是否显示导出按钮',
                    'default': True,
                    'x-component': 'Switch',
                },
                'enable_import': {
                    'type': 'boolean',
                    'title': '启用导入',
                    'description': '是否显示导入按钮',
                    'default': False,
                    'x-component': 'Switch',
                },
                'require_confirmation': {
                    'type': 'boolean',
                    'title': '需要确认',
                    'description': '设计完成后是否暂停等待用户确认或编辑',
                    'default': True,
                    'x-component': 'Switch',
                },
            },
            'required': ['form_ui_design'],
        }
