'use client';

import React, { useState, useEffect, useRef, useCallback, useMemo, ComponentType } from 'react';
import { LucideIcon } from 'lucide-react';
import { useNodeData } from '../hooks/useNodeData';
import { useNodeExecution } from '../hooks/useNodeExecution';
import { useNodeDimensions } from '../hooks/useNodeDimensions';
import { useNodeDataSync } from '../hooks/useNodeDataSync';
import { useNodeActions } from '../hooks/useNodeActions';
import { NodeToolbar } from './components/NodeToolbar';
import { NodeHandles } from './components/NodeHandles';
import { NodeFrame } from './components/NodeFrame';
import { AppNodeData } from '../types/node';

interface BaseNodeProps {
    id: string;
    data: AppNodeData;
    selected?: boolean;
    dragging?: boolean;
    icon: LucideIcon;
    color: string;
    border: string;
    ring: string;
    shadow: string;
    renderer: ComponentType<any>;
}

export const BaseNode: React.FC<BaseNodeProps> = ({
    id,
    data,
    selected,
    dragging,
    icon: NodeIcon,
    ring: ringColor,
    shadow: shadowColor,
    renderer: Renderer
}) => {
    const { update } = useNodeData(id);
    const { executeNode } = useNodeExecution();
    const {
        type,
        status = 'IDLE',
        title,
        prompt,
        userPrompt,
        model,
        inputPrompt,
        targetType,
        aspectRatio,
        resolution,
        duration,
        voice,
        stylePrompt,
        styleId,
        imageCount,
        videoCount,
        template,
        image,
        videoUri,
        audioUri,
        content: nodeContent,
        autoExecute,
        images,
        videoUris,
        error,
        generationMode,
        negativePrompt,
        shotType,
        enableAudio,
        cameraControl,
        croppedFrame
    } = data;

    const [isResizing, setIsResizing] = useState(false);
    const autoExecuteProcessedRef = useRef(false);

    // Auto-execute logic
    useEffect(() => {
        const isGeneratorNode = ['IMAGE_GENERATOR', 'VIDEO_GENERATOR', 'AUDIO_GENERATOR', 'IMAGE_EDITOR', 'PROMPT_GENERATOR', 'VIDEO_ANALYZER', 'LYRICS_GENERATOR'].includes(type);
        
        if (autoExecute && status !== 'WORKING' && isGeneratorNode && !autoExecuteProcessedRef.current) {
            autoExecuteProcessedRef.current = true;
            update({ autoExecute: false });
            
            const timer = setTimeout(() => {
                executeNode(id);
            }, 150);
            
            return () => clearTimeout(timer);
        }
        
        if (!autoExecute) {
            autoExecuteProcessedRef.current = false;
        }
    }, [autoExecute, status, type, id, update, executeNode]);

    // 节点 dimensions
    const { 
        nodeWidth, 
        nodeHeight, 
        minHeight, 
        shouldKeepRatio
    } = useNodeDimensions(data);

    // Data synchronization
    const { 
        inputAssets, 
        handleInputReorder 
    } = useNodeDataSync(id, data, update);

    // 节点 actions
    const {
        handleDownload,
        handleExpand,
        handleMediaContextMenu,
        handleCropRequest,
        handleSmartSave,
        handleHandleClick
    } = useNodeActions(id, data, update);

    const [isHovered, setIsHovered] = useState(false);
    const isWorking = status === 'WORKING';

    const handleMouseEnter = useCallback(() => setIsHovered(true), []);
    const handleMouseLeave = useCallback(() => setIsHovered(false), []);
    const handleResizeStart = useCallback(() => setIsResizing(true), []);
    const handleResizeEnd = useCallback(() => setIsResizing(false), []);
    const handleResize = useCallback((width: number) => update({ width }), [update]);
    const handleExecute = useCallback(() => executeNode(id), [executeNode, id]);

    const content = useMemo(() => {
        return <Renderer 
            data={data}
            update={update}
            isWorking={isWorking}
            onExpand={handleExpand}
            icon={NodeIcon}
            onCropRequest={handleCropRequest}
            onContextMenu={handleMediaContextMenu}
            type={type}
            image={image}
            videoUri={videoUri}
            images={images}
            videoUris={videoUris}
            content={nodeContent}
            title={title}
            error={error}
            generationMode={generationMode}
            croppedFrame={croppedFrame}
            inputAssets={inputAssets}
        />;
    }, [
        Renderer,
        data,
        update,
        isWorking,
        handleExpand,
        NodeIcon,
        handleCropRequest,
        handleMediaContextMenu,
        type,
        image,
        videoUri,
        images,
        videoUris,
        nodeContent,
        title,
        error,
        generationMode,
        croppedFrame,
        inputAssets,
    ]);

    const handleUpdateTitle = useCallback((newTitle: string) => update({ title: newTitle }), [update]);

    return (
        <NodeFrame
            selected={selected}
            dragging={dragging}
            isResizing={isResizing}
            isHovered={isHovered}
            width={nodeWidth}
            height={nodeHeight}
            minHeight={minHeight}
            shouldKeepRatio={shouldKeepRatio}
            ringColor={ringColor}
            shadowColor={shadowColor}
            onMouseEnter={handleMouseEnter}
            onMouseLeave={handleMouseLeave}
            onResizeStart={handleResizeStart}
            onResizeEnd={handleResizeEnd}
            onResize={handleResize}
            toolbar={
                <NodeToolbar 
                    title={title}
                    type={type}
                    hasMedia={!!(image || videoUri || audioUri || nodeContent)}
                    updateTitle={handleUpdateTitle}
                    selected={!!selected} 
                    isHovered={isHovered} 
                    isWorking={isWorking}
                    onSave={handleSmartSave}
                    onDownload={handleDownload}
                    onExpand={handleExpand}
                />
            }
            handles={<NodeHandles onHandleClick={handleHandleClick} />}
        >
            {content}
        </NodeFrame>
    );
};
