import React, { useState, useEffect, useMemo } from 'react';
import { FormItem, Input, NumberPicker, Select, FormLayout, Switch } from '@formily/antd-v5';
import { createForm } from '@formily/core';
import { createSchemaField, FormProvider, ISchema } from '@formily/react';
import { Save, RotateCcw } from 'lucide-react';
import { Sheet, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle } from '@/components/ui/sheet';
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion';
import { Button } from '@/components/ui/button';
import { useToast } from '@/components/ui/use-toast';
import type { FlowNode, FlowNodeData } from '../types';
import type { WorkflowNodeDefinition } from '../nodes/types';
import { isConfigurableNode } from '../nodes/types';

// 创建Schema组件
const SchemaField = createSchemaField({
    components: {
        FormItem,
        Input,
        NumberPicker,
        Select,
        FormLayout,
        Switch,
        'Input.TextArea': Input.TextArea,
    },
});

interface NodeConfigModalProps {
    visible: boolean;
    node: FlowNode | null;
    onCancel: () => void;
    onOk: (nodeId: string, updatedData: Partial<FlowNodeData>) => void;
}

const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
    visible,
    node,
    onCancel,
    onOk
}) => {
    const [loading, setLoading] = useState(false);
    const { toast } = useToast();

    // 获取节点定义
    const nodeDefinition: WorkflowNodeDefinition | null = node?.data?.nodeDefinition || null;

    // ✅ 根据节点 ID 重新创建表单实例（修复切换节点时数据不更新的问题）
    const configForm = useMemo(() => createForm(), [node?.id]);
    const inputForm = useMemo(() => createForm(), [node?.id]);

    // 初始化表单数据
    useEffect(() => {
        if (visible && node && nodeDefinition) {
            const nodeData = node.data || {};
            
            // 准备默认配置
            const defaultConfig = {
                nodeName: nodeDefinition.nodeName,
                nodeCode: nodeDefinition.nodeCode,
                description: nodeDefinition.description
            };
            
            // 设置表单初始值
            configForm.setInitialValues({ ...defaultConfig, ...(nodeData.configs || {}) });
            configForm.reset();
            
            if (isConfigurableNode(nodeDefinition)) {
                inputForm.setInitialValues(nodeData.inputMapping || {});
                inputForm.reset();
            }
        }
    }, [visible, node, nodeDefinition, configForm, inputForm]);

    // 递归处理表单值，将JSON字符串转换为对象
    const processFormValues = (values: Record<string, any>, schema: ISchema | undefined): Record<string, any> => {
        const result: Record<string, any> = {};
        
        if (!schema?.properties || typeof schema.properties !== 'object') return values;
        
        Object.entries(values).forEach(([key, value]) => {
            const propSchema = (schema.properties as Record<string, any>)?.[key];
            
            // 如果是object类型且值是字符串，尝试解析
            if (propSchema?.type === 'object' && typeof value === 'string') {
                try {
                    result[key] = JSON.parse(value);
                } catch {
                    result[key] = value; // 解析失败保持原值
                }
            } else {
                result[key] = value;
            }
        });
        
        return result;
    };

    const handleSubmit = async () => {
        if (!node || !nodeDefinition) return;
        
        try {
            setLoading(true);

            // 获取表单值并转换
            const configs = processFormValues(configForm.values, nodeDefinition.configSchema);
            const inputMapping = isConfigurableNode(nodeDefinition) 
                ? processFormValues(inputForm.values, nodeDefinition.inputMappingSchema)
                : {};

            const updatedData: Partial<FlowNodeData> = {
                label: configs.nodeName || node.data.label,
                configs,
                inputMapping,
                // outputs 保留原值（不修改，因为它是只读的输出能力定义）
                outputs: node.data.outputs || [],
            };

            onOk(node.id, updatedData);
            toast({
                title: "保存成功",
                description: "节点配置已成功保存",
            });
            onCancel();
        } catch (error) {
            if (error instanceof Error) {
                toast({
                    variant: "destructive",
                    title: "保存失败",
                    description: error.message,
                });
            }
        } finally {
            setLoading(false);
        }
    };

    const handleReset = () => {
        configForm.reset();
        inputForm.reset();
        toast({
            title: "已重置",
            description: "表单已重置为初始值",
        });
    };

    // 将JSON Schema转换为Formily Schema（扩展配置）
    const convertToFormilySchema = (jsonSchema: ISchema): ISchema => {
        const schema: ISchema = {
            type: 'object',
            properties: {}
        };

        if (!jsonSchema.properties || typeof jsonSchema.properties !== 'object') return schema;

        Object.entries(jsonSchema.properties as Record<string, any>).forEach(([key, prop]: [string, any]) => {
            const field: any = {
                title: prop.title || key,
                description: prop.description,
                'x-decorator': 'FormItem',
                'x-decorator-props': {
                    tooltip: prop.description,
                    // 垂直布局不需要 labelCol 和 wrapperCol
                },
            };

            // 根据类型设置组件
            switch (prop.type) {
                case 'string':
                    if (prop.enum) {
                        field['x-component'] = 'Select';
                        field['x-component-props'] = {
                            style: { width: '100%' }, // 统一宽度
                            options: prop.enum.map((v: any, i: number) => ({
                                label: prop.enumNames?.[i] || v,
                                value: v
                            }))
                        };
                    } else if (prop.format === 'password') {
                        field['x-component'] = 'Input';
                        field['x-component-props'] = { 
                            type: 'password',
                            style: { width: '100%' } // 统一宽度
                        };
                    } else {
                        field['x-component'] = 'Input';
                        field['x-component-props'] = {
                            style: { width: '100%' } // 统一宽度
                        };
                    }
                    break;
                case 'number':
                case 'integer':
                    field['x-component'] = 'NumberPicker';
                    field['x-component-props'] = {
                        min: prop.minimum,
                        max: prop.maximum,
                        style: { width: '100%' } // 统一宽度
                    };
                    break;
                case 'boolean':
                    field['x-component'] = 'Switch';
                    break;
                case 'object':
                    field['x-component'] = 'Input.TextArea';
                    field['x-component-props'] = {
                        rows: 4,
                        style: { width: '100%' }, // 统一宽度
                        placeholder: '请输入JSON格式，例如：{"key": "value"}'
                    };
                    // ✅ 关键修复：将object类型的default值转换为JSON字符串
                    if (prop.default !== undefined && typeof prop.default === 'object') {
                        field.default = JSON.stringify(prop.default, null, 2);
                    } else {
                        field.default = prop.default;
                    }
                    // Formily会自动处理object的序列化
                    field['x-validator'] = (value: any) => {
                        if (!value) return true;
                        if (typeof value === 'string') {
                            try {
                                JSON.parse(value);
                                return true;
                            } catch {
                                return '请输入有效的JSON格式';
                            }
                        }
                        return true;
                    };
                    break;
                default:
                    field['x-component'] = 'Input';
                    field['x-component-props'] = {
                        style: { width: '100%' } // 统一宽度
                    };
            }

            // 设置默认值（非object类型）
            if (prop.type !== 'object' && prop.default !== undefined) {
                field.default = prop.default;
            }

            // 设置必填
            if (Array.isArray(jsonSchema.required) && jsonSchema.required.includes(key)) {
                field.required = true;
            }

            (schema.properties as Record<string, any>)[key] = field;
        });

        return schema;
    };

    if (!nodeDefinition) {
        return null;
    }

        return (
            <Sheet open={visible} onOpenChange={(open) => !open && onCancel()}>
                <SheetContent className="w-[600px] sm:max-w-[600px] flex flex-col p-0">
                {/* Header - 固定在顶部 */}
                <div className="px-6 pt-6 pb-4 border-b">
                    <SheetHeader className="space-y-2">
                        <SheetTitle className="text-xl font-semibold">
                            编辑节点 - {nodeDefinition.nodeName}
                        </SheetTitle>
                        <SheetDescription className="text-sm text-muted-foreground">
                            配置节点的参数和映射关系
                        </SheetDescription>
                    </SheetHeader>
                </div>

                {/* Content - 可滚动区域 */}
                <div className="flex-1 overflow-y-auto px-6 py-4">
                    {/* 使用 Accordion 支持多个面板同时展开，默认展开基本配置 */}
                    <Accordion 
                        type="multiple" 
                        defaultValue={["config"]} 
                        className="w-full"
                    >
                        {/* 基本配置 - 始终显示 */}
                        <AccordionItem value="config" className="border-b">
                            <AccordionTrigger className="text-base font-semibold flex-row-reverse justify-end gap-2 hover:no-underline">
                                基本配置
                            </AccordionTrigger>
                            <AccordionContent className="px-1">
                                <FormProvider form={configForm}>
                                    <FormLayout layout="vertical" colon={false}>
                                        <SchemaField schema={convertToFormilySchema(nodeDefinition.configSchema)} />
                                    </FormLayout>
                                </FormProvider>
                            </AccordionContent>
                        </AccordionItem>

                        {/* 输入映射 - 条件显示 */}
                        {isConfigurableNode(nodeDefinition) && nodeDefinition.inputMappingSchema && (
                            <AccordionItem value="input" className="border-b">
                                <AccordionTrigger className="text-base font-semibold flex-row-reverse justify-end gap-2 hover:no-underline">
                                    输入映射
                                </AccordionTrigger>
                                <AccordionContent className="px-1">
                                    <FormProvider form={inputForm}>
                                        <FormLayout layout="vertical" colon={false}>
                                            <SchemaField schema={convertToFormilySchema(nodeDefinition.inputMappingSchema)} />
                                        </FormLayout>
                                    </FormProvider>
                                </AccordionContent>
                            </AccordionItem>
                        )}

                        {/* 输出能力 - 只读展示 */}
                        {isConfigurableNode(nodeDefinition) && nodeDefinition.outputs && nodeDefinition.outputs.length > 0 && (
                            <AccordionItem value="output" className="border-b">
                                <AccordionTrigger className="text-base font-semibold flex-row-reverse justify-end gap-2 hover:no-underline">
                                    输出能力
                                </AccordionTrigger>
                                <AccordionContent className="px-1">
                                    <div className="text-sm text-muted-foreground mb-4 p-3 bg-muted/50 rounded-md">
                                        💡 此节点执行后会产生以下数据，下游节点可以通过 <code className="px-1 py-0.5 bg-background rounded">{'${upstream.字段名}'}</code> 引用这些数据
                                    </div>
                                    <div className="space-y-3">
                                        {nodeDefinition.outputs.map((output) => (
                                            <div key={output.name} className="p-3 border rounded-md bg-background">
                                                <div className="flex items-start justify-between mb-2">
                                                    <div className="flex-1">
                                                        <div className="flex items-center gap-2">
                                                            <span className="font-medium text-foreground">{output.title}</span>
                                                            <code className="px-1.5 py-0.5 text-xs bg-muted rounded">{output.name}</code>
                                                            <span className="text-xs text-muted-foreground border border-border px-1.5 py-0.5 rounded">
                                                                {output.type}
                                                            </span>
                                                            {output.required && (
                                                                <span className="text-xs text-red-500">*</span>
                                                            )}
                                                        </div>
                                                        <p className="text-sm text-muted-foreground mt-1">
                                                            {output.description}
                                                        </p>
                                                    </div>
                                                </div>
                                                {output.enum && (
                                                    <div className="mt-2 text-xs">
                                                        <span className="text-muted-foreground">可选值：</span>
                                                        <span className="ml-1 text-foreground">{output.enum.join(', ')}</span>
                                                    </div>
                                                )}
                                                {output.example !== undefined && (
                                                    <div className="mt-2 text-xs">
                                                        <span className="text-muted-foreground">示例：</span>
                                                        <code className="ml-1 px-1.5 py-0.5 bg-muted rounded text-foreground">
                                                            {typeof output.example === 'object' 
                                                                ? JSON.stringify(output.example) 
                                                                : String(output.example)}
                                                        </code>
                                                    </div>
                                                )}
                                            </div>
                                        ))}
                                    </div>
                                </AccordionContent>
                            </AccordionItem>
                        )}
                    </Accordion>
                </div>

                {/* Footer - 固定在底部 */}
                <div className="px-6 py-4 border-t bg-background">
                    <SheetFooter className="flex-row justify-between gap-2">
                        <Button
                            type="button"
                            variant="outline"
                            onClick={handleReset}
                            className="gap-2"
                        >
                            <RotateCcw className="h-4 w-4" />
                            重置
                        </Button>
                        <div className="flex gap-2">
                            <Button
                                type="button"
                                variant="outline"
                                onClick={onCancel}
                            >
                                取消
                            </Button>
                            <Button
                                type="button"
                                onClick={handleSubmit}
                                disabled={loading}
                                className="gap-2"
                            >
                                <Save className="h-4 w-4" />
                                {loading ? '保存中...' : '保存配置'}
                            </Button>
                        </div>
                    </SheetFooter>
                </div>
            </SheetContent>
        </Sheet>
    );
};

export default NodeConfigModal;