/**
 * Auto Workflow Generator Hook
 * 
 * Automatically generates workflow nodes from assets and storyboards
 * when switching canvases in the right sidebar.
 */

import { useCallback } from 'react';
import { useReactFlow, Node, Edge } from '@xyflow/react';
import { Asset, Storyboard } from '@/types';
import { NodeType, NodeStatus, AppNodeData, AppNodeType } from '@/components/canvas/types/node';
import { findNonOverlappingPosition, LAYOUT_CONFIG } from '@/components/canvas/utils/layoutUtils';

interface WorkflowResult {
  nodes: AppNodeType[];
  edges: Edge[];
}

export function useAutoWorkflow() {
  const { getNodes, setNodes, setEdges, screenToFlowPosition } = useReactFlow();

  /**
   * Generate unique node ID
   */
  const generateNodeId = useCallback((prefix: string, id: string) => {
    return `auto-${prefix}-${id}-${Date.now()}`;
  }, []);

  /**
   * Create nodes from a single asset
   * Workflow: INFO_DISPLAY → IMAGE_GENERATOR (simplified, no prompt optimization)
   * Asset info already contains image_prompt, so we skip the prompt generator node
   * All nodes aligned horizontally (same Y position)
   */
  const createNodesFromAsset = useCallback((
    asset: Asset,
    startPosition: { x: number; y: number }
  ): WorkflowResult => {
    const nodes: AppNodeType[] = [];
    const edges: Edge[] = [];

    // Fixed grid layout - same as storyboard canvas
    const columnWidth = 500; // Match storyboard canvas spacing
    const baseY = startPosition.y; // All nodes at same Y (top-aligned)

    const assetTypeLabel = 
      asset.type === 'character' ? '角色' :
      asset.type === 'scene' ? '场景' :
      asset.type === 'prop' ? '道具' :
      asset.type === 'audio' ? '音频' : '资产';

    // 1. Create INFO_DISPLAY node (Asset description) - Column 0
    const infoNodeId = generateNodeId('asset-info', asset.id);

    nodes.push({
      id: infoNodeId,
      type: 'appNode',
      position: { x: startPosition.x, y: baseY },
      data: {
        title: `${assetTypeLabel}信息: ${asset.name}`,
        type: NodeType.INFO_DISPLAY,
        status: NodeStatus.SUCCESS,
        content: asset.desc || asset.name,
        assetInfo: {
          name: asset.name,
          type: asset.type,
          desc: asset.desc,
          tags: asset.tags,
          imageUrl: asset.imageUrl,
          imageUrls: asset.imageUrls,
          videoUrls: asset.videoUrls,
          imagePrompt: (asset as any).imagePrompt, // Include AI image prompt
          // Spread any additional asset fields
          ...(asset as any),
        },
      } as AppNodeData,
    });

    // 2. Create IMAGE_GENERATOR node - Column 1 (directly after info, no prompt optimization)
    const imageNodeId = generateNodeId('asset-image', asset.id);
    
    // Use imagePrompt from asset if available, otherwise fall back to desc
    const imagePrompt = (asset as any).imagePrompt || asset.desc || asset.name;

    nodes.push({
      id: imageNodeId,
      type: 'appNode',
      position: { x: startPosition.x + columnWidth, y: baseY },
      data: {
        title: `${asset.name} 图片`,
        type: NodeType.IMAGE_GENERATOR,
        status: (asset.imageUrl || (asset.imageUrls && asset.imageUrls.length > 0)) 
          ? NodeStatus.SUCCESS 
          : NodeStatus.IDLE,
        image: asset.imageUrl || asset.imageUrls?.[0],
        images: asset.imageUrls,
        prompt: imagePrompt, // Use AI-generated image prompt
      } as AppNodeData,
    });

    // Connect info → image (direct connection, skip prompt optimization)
    edges.push({
      id: `e-${infoNodeId}-${imageNodeId}`,
      source: infoNodeId,
      target: imageNodeId,
      type: 'gradient',
    });

    // 3. Create VIDEO_GENERATOR node if asset has videos - Below image node
    if (asset.videoUrls && asset.videoUrls.length > 0) {
      const videoNodeId = generateNodeId('asset-video', asset.id);

      nodes.push({
        id: videoNodeId,
        type: 'appNode',
        position: { x: startPosition.x + columnWidth, y: baseY + 300 },
        data: {
          title: `${asset.name} 视频`,
          type: NodeType.VIDEO_GENERATOR,
          status: NodeStatus.SUCCESS,
          videoUri: asset.videoUrls[0],
          videoUris: asset.videoUrls,
          prompt: imagePrompt, // Use same prompt as image
        } as AppNodeData,
      });

      // Connect image → video
      edges.push({
        id: `e-${imageNodeId}-${videoNodeId}`,
        source: imageNodeId,
        target: videoNodeId,
        type: 'gradient',
      });
    }

    return { nodes, edges };
  }, [generateNodeId]);

  /**
   * Create simplified workflow from storyboard
   * Layout: Storyboard Info (left) → Asset Images (middle, from library) → Storyboard Image (right) → Storyboard Video (far right)
   * Uses fixed grid layout for clean alignment
   */
  const createWorkflowFromStoryboard = useCallback((
    storyboard: Storyboard,
    assets: Asset[],
    startPosition: { x: number; y: number }
  ): WorkflowResult => {
    const nodes: AppNodeType[] = [];
    const edges: Edge[] = [];

    // Fixed grid layout parameters
    const startX = startPosition.x;
    const startY = startPosition.y;
    const columnWidth = 500;  // Fixed width between columns
    const rowHeight = 250;    // Fixed height between rows

    // 1. Collect all related assets from library
    const relatedAssets: Asset[] = [];
    
    // Add scene if exists
    if (storyboard.sceneId) {
      const scene = assets.find(a => a.id === storyboard.sceneId);
      if (scene) relatedAssets.push(scene);
    }
    
    // Add characters
    if (storyboard.characterIds && storyboard.characterIds.length > 0) {
      storyboard.characterIds.forEach(charId => {
        const character = assets.find(a => a.id === charId);
        if (character) relatedAssets.push(character);
      });
    }
    
    // Add props
    if (storyboard.propIds && storyboard.propIds.length > 0) {
      storyboard.propIds.forEach(propId => {
        const prop = assets.find(a => a.id === propId);
        if (prop) relatedAssets.push(prop);
      });
    }

    // Calculate layout positions
    const totalRows = Math.max(relatedAssets.length, 1);
    
    // 2. Create Storyboard INFO_DISPLAY node (column 0, aligned with first asset row)
    const storyboardInfoId = generateNodeId('storyboard-info', storyboard.id);
    
    nodes.push({
      id: storyboardInfoId,
      type: 'appNode',
      position: { x: startX, y: startY }, // Align with first row
      data: {
        title: `分镜信息: ${storyboard.shot}`,
        type: NodeType.INFO_DISPLAY,
        status: NodeStatus.SUCCESS,
        content: storyboard.desc,
        assetInfo: {
          name: `分镜${storyboard.order}: ${storyboard.shot}`,
          type: 'storyboard',
          desc: storyboard.desc,
          shot: storyboard.shot,
          duration: storyboard.duration,
          order: storyboard.order,
          imageUrls: storyboard.imageUrls,
          videoUrls: storyboard.videoUrls,
          // Spread any additional storyboard fields
          ...(storyboard as any),
        },
      } as AppNodeData,
    });

    // 3. Create simple IMAGE nodes for each asset (column 1, vertically distributed)
    const assetImageNodeIds: string[] = [];
    relatedAssets.forEach((asset, index) => {
      const assetY = startY + (index * rowHeight);
      const imageUrl = asset.imageUrl || (asset.imageUrls && asset.imageUrls[0]);
      
      const assetImageId = generateNodeId('asset-image', `${asset.id}-${index}`);

      const assetTypeLabel = 
        asset.type === 'character' ? '角色' :
        asset.type === 'scene' ? '场景' :
        asset.type === 'prop' ? '道具' : '素材';

      // Use imagePrompt if available, otherwise fall back to desc
      const assetImagePrompt = (asset as any).imagePrompt || asset.desc || '';

      nodes.push({
        id: assetImageId,
        type: 'appNode',
        position: { x: startX + columnWidth, y: assetY },
        data: {
          title: `${assetTypeLabel}: ${asset.name}`,
          type: NodeType.IMAGE_GENERATOR,
          status: imageUrl ? NodeStatus.SUCCESS : NodeStatus.IDLE,
          image: imageUrl,
          images: asset.imageUrls,
          prompt: assetImagePrompt, // Use AI-generated imagePrompt
          assetInfo: asset, // Keep reference to asset
        } as AppNodeData,
      });

      // Connect storyboard info to asset image
      edges.push({
        id: `e-${storyboardInfoId}-${assetImageId}`,
        source: storyboardInfoId,
        target: assetImageId,
        type: 'gradient',
      });

      assetImageNodeIds.push(assetImageId);
    });

    // Calculate center Y for output nodes (image and video)
    const totalHeight = (totalRows - 1) * rowHeight;
    const centerY = startY + (totalHeight / 2);

    // 4. Create storyboard IMAGE_GENERATOR node (column 2, centered vertically)
    // Use mergeImagePrompt if available, otherwise fall back to desc
    const storyboardImageId = generateNodeId('storyboard-image', storyboard.id);
    const hasStoryboardImages = storyboard.imageUrls && storyboard.imageUrls.length > 0;
    const mergeImagePrompt = (storyboard as any).mergeImagePrompt || storyboard.desc || '';
    
    nodes.push({
      id: storyboardImageId,
      type: 'appNode',
      position: { x: startX + columnWidth * 2, y: centerY },
      data: {
        title: '分镜图片生成',
        type: NodeType.IMAGE_GENERATOR,
        status: hasStoryboardImages ? NodeStatus.SUCCESS : NodeStatus.IDLE,
        image: storyboard.imageUrls?.[0],
        images: storyboard.imageUrls,
        prompt: mergeImagePrompt, // Use merge_image_prompt from storyboard
      } as AppNodeData,
    });

    // Connect all asset images to storyboard image node
    assetImageNodeIds.forEach(assetImageId => {
      edges.push({
        id: `e-${assetImageId}-${storyboardImageId}`,
        source: assetImageId,
        target: storyboardImageId,
        type: 'gradient',
      });
    });

    // 5. Create storyboard VIDEO_GENERATOR node (column 3, centered vertically)
    // Always create video node, use videoPrompt if available
    const storyboardVideoId = generateNodeId('storyboard-video', storyboard.id);
    const hasStoryboardVideos = storyboard.videoUrls && storyboard.videoUrls.length > 0;
    const videoPrompt = (storyboard as any).videoPrompt || storyboard.desc || '';
    
    nodes.push({
      id: storyboardVideoId,
      type: 'appNode',
      position: { x: startX + columnWidth * 3, y: centerY },
      data: {
        title: '分镜视频生成',
        type: NodeType.VIDEO_GENERATOR,
        status: hasStoryboardVideos ? NodeStatus.SUCCESS : NodeStatus.IDLE,
        videoUri: storyboard.videoUrls?.[0],
        videoUris: storyboard.videoUrls,
        prompt: videoPrompt, // Use video_prompt from storyboard
      } as AppNodeData,
    });

    // Connect image to video
    edges.push({
      id: `e-${storyboardImageId}-${storyboardVideoId}`,
      source: storyboardImageId,
      target: storyboardVideoId,
      type: 'gradient',
    });

    return { nodes, edges };
  }, [generateNodeId]);

  /**
   * Apply workflow to canvas (replace existing nodes)
   */
  const applyWorkflow = useCallback((nodes: AppNodeType[], edges: Edge[]) => {
    console.log('[AutoWorkflow] Applying workflow:', { nodeCount: nodes.length, edgeCount: edges.length });
    setNodes(nodes);
    setEdges(edges);
  }, [setNodes, setEdges]);

  /**
   * Append workflow to canvas (add to existing nodes)
   */
  const appendWorkflow = useCallback((nodes: AppNodeType[], edges: Edge[]) => {
    console.log('[AutoWorkflow] Appending workflow:', { nodeCount: nodes.length, edgeCount: edges.length });
    setNodes(prev => [...prev, ...nodes]);
    setEdges(prev => [...prev, ...edges]);
  }, [setNodes, setEdges]);

  return {
    createNodesFromAsset,
    createWorkflowFromStoryboard,
    applyWorkflow,
    appendWorkflow,
  };
}

export default useAutoWorkflow;
