"""
数据库表结构设计节点

接收LLM提取的表结构，进行验证、标准化和补充系统字段
"""
import asyncio
import json
import logging
import uuid
from typing import Any, Dict, List, Optional

from core.database_connection.resolver import ConnectionResolver
from core.database_manager.ddl_builder import (
    SYSTEM_FIELDS,
    normalize_db_type,
    process_canonical_field,
)

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

logger = logging.getLogger(__name__)


@NodeRegistry.register
class FormDatabaseDesignNode(BaseNode):
    """
    数据库表结构设计节点

    接收LLM提取的表结构，验证、标准化并补充系统字段
    """

    node_type = 'form_database_design'
    node_name = '数据库表结构设计'
    node_category = 'form'
    node_icon = 'database'
    node_description = '验证和标准化数据库表结构，自动补充系统字段'

    inputs = [
        {
            'name': 'design_mode',
            'type': 'string',
            'description': '设计模式：main（主表）或 sub（从表）',
            'required': True,
        },
        {
            'name': 'table_name',
            'type': 'string',
            'description': '主表名（主表模式）',
            'required': False,
        },
        {
            'name': 'fields',
            'type': 'array',
            'description': '主表字段列表（主表模式）',
            'required': False,
        },
        {
            'name': 'sub_table_name',
            'type': 'string',
            'description': '从表名（从表模式）',
            'required': False,
        },
        {
            'name': 'sub_fields',
            'type': 'array',
            'description': '从表字段列表（从表模式）',
            'required': False,
        },
        {
            'name': 'parent_table',
            'type': 'string',
            'description': '关联主表名（从表模式）',
            'required': False,
        },
        {
            'name': 'foreign_key',
            'type': 'string',
            'description': '外键字段名（从表模式）',
            'required': False,
        },
        {
            'name': 'db_config',
            'type': 'string',
            'description': '数据库配置名',
            'required': False,
        },
        {
            'name': 'auto_add_system_fields',
            'type': 'boolean',
            'description': '是否自动添加系统字段',
            'required': False,
        },
    ]

    outputs = [
        {
            'name': 'database_design',
            'type': 'object',
            'description': '标准化的数据库设计配置',
        },
        {
            'name': 'table_name',
            'type': 'string',
            'description': '表名',
        },
        {
            'name': 'field_count',
            'type': 'number',
            'description': '字段数量',
        },
    ]

    def execute(self, context: NodeContext) -> NodeResult:
        """执行节点"""
        loop = asyncio.get_event_loop()
        if loop.is_running():
            import concurrent.futures
            with concurrent.futures.ThreadPoolExecutor() as executor:
                future = executor.submit(asyncio.run, self.execute_async(context))
                return future.result()
        return loop.run_until_complete(self.execute_async(context))

    async def execute_async(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('FormDatabaseDesignNode - 使用用户编辑的数据')
                    context.variables.pop('__user_input__', None)
                    return self._build_result_from_edit(edited_data)

            design_mode = self.config.get('design_mode', 'main')
            db_config = context.resolve_template(self.config.get('db_config', 'default'))

            db_schema_raw = self.config.get('db_schema', '')
            db_schema = context.resolve_template(db_schema_raw)

            db_database_raw = self.config.get('db_database', '')
            db_database = context.resolve_template(db_database_raw)

            config_db_type = self.config.get('db_type', 'postgresql')
            db_type, db_type_resolved = await self._resolve_db_type(
                db_config, config_db_type, context,
            )
            auto_add_system = self.config.get('auto_add_system_fields', True)

            logger.info(
                'FormDatabaseDesignNode - mode=%s database=%s schema=%s db_config=%s db_type=%s resolved=%s',
                design_mode,
                db_database,
                db_schema,
                db_config,
                db_type,
                db_type_resolved,
            )

            if design_mode == 'main':
                table_name_str = context.resolve_template(self.config.get('table_name', ''))
                fields = resolve_list_config(context, self.config.get('fields', '[]'))

                if not table_name_str:
                    return NodeResult(success=False, error='主表名不能为空')
                if fields is None:
                    return NodeResult(success=False, error='字段列表解析失败')
                if not fields:
                    return NodeResult(success=False, error='字段列表不能为空')

                table_config = {'tableName': table_name_str, 'fields': fields}
                processed_table = self._process_table(
                    table_config,
                    'main',
                    auto_add_system,
                    db_config,
                    db_database,
                    db_database_raw,
                    db_schema,
                    db_schema_raw,
                    db_type,
                    db_type_resolved,
                )

                database_design = {
                    'type': 'main',
                    'table': processed_table,
                    'dbConfig': db_config,
                }
                field_count = len(processed_table['fields'])

                require_confirmation = self.resolve_require_confirmation(context, default=True)
                preview_data = {
                    'type': 'database_design',
                    'title': '数据库表结构设计',
                    'data': database_design,
                    'editable': True,
                } if require_confirmation else None

                return NodeResult(
                    success=True,
                    output=database_design,
                    output_variables={
                        'database_design': database_design,
                        'table_name': table_name_str,
                        'field_count': field_count,
                    },
                    preview=preview_data,
                    waiting_for_input=require_confirmation,
                    waiting_config={
                        'type': 'design_preview',
                        'preview_type': 'database_design',
                        'title': '数据库表结构设计',
                        'message': '请确认或编辑数据库表结构',
                        'data': database_design,
                    } if require_confirmation else {},
                )

            sub_table_name_str = context.resolve_template(self.config.get('sub_table_name', ''))
            sub_fields = resolve_list_config(context, self.config.get('sub_fields', '[]'))
            parent_table = context.resolve_template(self.config.get('parent_table', ''))
            foreign_key = context.resolve_template(self.config.get('foreign_key', ''))

            if not sub_table_name_str:
                return NodeResult(success=False, error='从表名不能为空')
            if not parent_table:
                return NodeResult(success=False, error='关联主表不能为空')
            if sub_fields is None:
                return NodeResult(success=False, error='从表字段列表解析失败')
            if not sub_fields:
                return NodeResult(success=False, error='从表字段列表不能为空')

            if not foreign_key:
                foreign_key = f'{parent_table}_id'

            table_config = {
                'tableName': sub_table_name_str,
                'fields': sub_fields,
                'foreignKey': foreign_key,
                'parentTable': parent_table,
            }
            processed_table = self._process_table(
                table_config,
                'sub',
                auto_add_system,
                db_config,
                db_database,
                db_database_raw,
                db_schema,
                db_schema_raw,
                db_type,
                db_type_resolved,
            )

            database_design = {
                'type': 'sub',
                'table': processed_table,
                'parentTable': parent_table,
                'foreignKey': foreign_key,
                'dbConfig': db_config,
            }
            field_count = len(processed_table['fields'])

            return NodeResult(
                success=True,
                output=database_design,
                output_variables={
                    'database_design': database_design,
                    'table_name': sub_table_name_str,
                    'field_count': field_count,
                },
            )

        except Exception as exc:
            logger.exception('数据库表结构设计节点执行失败: %s', exc)
            return NodeResult(success=False, error=f'节点执行失败: {str(exc)}')

    async def _resolve_db_type(
        self,
        db_config: str,
        config_db_type: str,
        context: NodeContext,
    ) -> tuple[str, bool]:
        configured = normalize_db_type(config_db_type or 'postgresql')
        try:
            conn_info = await ConnectionResolver.resolve(db_config, context.db_session)
            resolved = normalize_db_type(conn_info.db_type)
            if configured != resolved:
                logger.warning(
                    'FormDatabaseDesignNode - db_type 配置=%s 与连接 %s 解析=%s 不一致，以连接为准',
                    configured,
                    db_config,
                    resolved,
                )
            return resolved, True
        except Exception as exc:
            logger.warning(
                'FormDatabaseDesignNode - 无法解析连接 %s: %s，使用配置 db_type=%s',
                db_config,
                exc,
                configured,
            )
            return configured, False

    def _parse_user_edit(self, user_input: Any) -> Optional[Dict[str, Any]]:
        if isinstance(user_input, dict):
            if 'table' in user_input or 'type' in user_input:
                return user_input
            return None

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

        return None

    def _build_result_from_edit(self, edited_data: Dict[str, Any]) -> NodeResult:
        table_info = edited_data.get('table', {})
        table_name = table_info.get('tableName', '')
        field_count = len(table_info.get('fields', []))

        return NodeResult(
            success=True,
            output=edited_data,
            output_variables={
                'database_design': edited_data,
                'table_name': table_name,
                'field_count': field_count,
            },
        )

    def _process_table(
        self,
        table: dict,
        table_type: str,
        auto_add_system: bool,
        db_config: str,
        db_database: str = '',
        db_database_raw: str = '',
        db_schema: str = '',
        db_schema_raw: str = '',
        db_type: str = 'postgresql',
        db_type_resolved: bool = False,
    ) -> dict:
        table_name = table.get('tableName', '')
        if not table_name:
            raise ValueError(f'{table_type} 表必须包含 tableName 字段')

        alias = table.get('alias', table_name)
        fields = table.get('fields', [])

        if not isinstance(fields, list):
            raise ValueError(f'表 {table_name} 的 fields 必须是数组')

        processed_fields = []
        existing_field_names = set()

        for fld in fields:
            if not isinstance(fld, dict):
                logger.warning('跳过无效的字段配置: %s', fld)
                continue

            field_name = fld.get('name', '')
            if not field_name:
                logger.warning('跳过没有名称的字段: %s', fld)
                continue

            if field_name in existing_field_names:
                logger.warning('跳过重复字段: %s', field_name)
                continue

            existing_field_names.add(field_name)
            processed_fields.append(process_canonical_field(fld))

        if auto_add_system:
            for sys_field in SYSTEM_FIELDS:
                if sys_field['name'] not in existing_field_names:
                    processed_fields.append(sys_field.copy())

        final_schema = db_schema or table.get('schema', '')
        final_database = db_database or table.get('database', '')

        result = {
            'id': str(uuid.uuid4()).replace('-', ''),
            'type': table_type,
            'tableName': table_name,
            'alias': alias,
            'fields': processed_fields,
            'meta': {
                'dbName': db_config,
                'database': final_database,
                'databaseRaw': db_database_raw,
                'schema': final_schema,
                'schemaRaw': db_schema_raw,
                'dbType': normalize_db_type(db_type),
                'dbTypeResolved': db_type_resolved,
            },
        }

        if table_type == 'sub':
            result['foreignKey'] = table.get('foreignKey', '')
            result['parentTable'] = table.get('parentTable', '')
            result['relatedField'] = table.get('relatedField', 'id')
            result['relationType'] = table.get('relationType', 'one-to-many')

        return result

    @classmethod
    def get_config_schema(cls) -> Dict[str, Any]:
        return {
            'type': 'object',
            'properties': {
                'design_mode': {
                    'type': 'string',
                    'title': '设计模式',
                    'description': '选择设计主表或从表',
                    'default': 'main',
                    'enum': ['main', 'sub'],
                    'x-component': 'RadioGroup',
                },
                'table_name': {
                    'type': 'string',
                    'title': '表名',
                    'description': '主表名（string类型）',
                    'x-component': 'SmartInput',
                },
                'fields': {
                    'type': 'string',
                    'title': '字段列表',
                    'description': '主表字段配置（array类型）',
                    'x-component': 'Textarea',
                },
                'sub_table_name': {
                    'type': 'string',
                    'title': '从表名',
                    'description': '从表名（string类型）',
                    'x-component': 'SmartInput',
                },
                'sub_fields': {
                    'type': 'string',
                    'title': '从表字段列表',
                    'description': '从表字段配置（array类型）',
                    'x-component': 'Textarea',
                },
                'parent_table': {
                    'type': 'string',
                    'title': '关联主表',
                    'description': '从表关联的主表名（string类型）',
                    'x-component': 'SmartInput',
                },
                'foreign_key': {
                    'type': 'string',
                    'title': '外键字段',
                    'description': '外键字段名（string类型），不填则自动生成',
                    'x-component': 'SmartInput',
                },
                'db_config': {
                    'type': 'string',
                    'title': '数据库配置',
                    'description': '数据库配置名称',
                    'default': 'default',
                    'x-component': 'Input',
                },
                'db_database': {
                    'type': 'string',
                    'title': '目标数据库',
                    'description': 'PostgreSQL/MySQL/SQL Server 的目标库名，为空则使用连接默认库',
                    'default': '',
                    'x-component': 'SmartInput',
                },
                'db_schema': {
                    'type': 'string',
                    'title': '数据库 Schema',
                    'description': 'PostgreSQL schema 名称（如 public、app），为空则使用默认',
                    'default': '',
                    'x-component': 'SmartInput',
                },
                'db_type': {
                    'type': 'string',
                    'title': '数据库类型',
                    'description': '由数据库连接自动解析，一般无需手动修改',
                    'default': 'postgresql',
                    'enum': ['postgresql', 'mysql', 'oracle', 'sqlserver'],
                    'x-component': 'Select',
                },
                'auto_add_system_fields': {
                    'type': 'boolean',
                    'title': '自动添加系统字段',
                    'description': '是否自动添加系统字段（id, sys_create_datetime等）',
                    'default': True,
                    'x-component': 'Switch',
                },
                'require_confirmation': {
                    'type': 'boolean',
                    'title': '需要确认',
                    'description': '设计完成后是否暂停等待用户确认或编辑',
                    'default': True,
                    'x-component': 'Switch',
                },
            },
            'required': ['design_mode'],
        }
