'use client'

import type { Node } from '../types'
import { toast } from '@langgenius/dify-ui/toast'
import { useEffect, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { useSearchParams } from '@/next/navigation'
import { scrollToWorkflowNode } from '../utils/node-navigation'
import { useNodesInteractions } from './use-nodes-interactions'

/**
 * Hook to locate a node by ID from URL query parameter `node_id`.
 *
 * Usage scenario: operators find a failing node ID from server logs,
 * construct a URL like `/workflow?node_id=xxx`, and the editor will
 * automatically select and scroll to that node on load.
 *
 * The hook reads `node_id` from the URL search params, waits for nodes
 * to be available, then selects and scrolls to the target node.
 * A toast message is shown to indicate success or failure.
 */
export const useLocateNode = (nodes: Node[]) => {
  const { t } = useTranslation('workflow')
  const searchParams = useSearchParams()
  const nodeIdFromUrl = searchParams.get('node_id')
  const { handleNodeSelect } = useNodesInteractions()
  const hasLocateRef = useRef(false)

  useEffect(() => {
    if (!nodeIdFromUrl || hasLocateRef.current) return

    // Wait for nodes to be loaded
    if (!nodes.length) return

    const targetNode = nodes.find((n) => n.id === nodeIdFromUrl)

    if (!targetNode) {
      // Don't mark as located yet — nodes may still be loading asynchronously.
      // Retry on the next nodes update before reporting "not found".
      return
    }

    // Select the node (opens its panel) and scroll to it
    handleNodeSelect(nodeIdFromUrl)

    // Delay scroll to ensure node selection state has been applied
    const scrollTimer = setTimeout(() => {
      scrollToWorkflowNode(nodeIdFromUrl)
    }, 200)

    toast.success(
      t(($) => $['panel.locateNodeSuccess'], {
        title: targetNode.data?.title || nodeIdFromUrl,
      }),
    )
    hasLocateRef.current = true

    return () => clearTimeout(scrollTimer)
  }, [nodeIdFromUrl, nodes, handleNodeSelect, t])

  // Report "not found" after nodes have settled (no longer changing)
  useEffect(() => {
    if (!nodeIdFromUrl || hasLocateRef.current || !nodes.length) return

    const targetNode = nodes.find((n) => n.id === nodeIdFromUrl)
    if (targetNode) return

    // Debounce: wait to see if nodes continue loading before reporting not found
    const notFoundTimer = setTimeout(() => {
      if (hasLocateRef.current) return
      const stillMissing = !nodes.find((n) => n.id === nodeIdFromUrl)
      if (stillMissing) {
        toast.error(t(($) => $['panel.locateNodeNotFound'], { nodeId: nodeIdFromUrl }))
        hasLocateRef.current = true
      }
    }, 500)

    return () => clearTimeout(notFoundTimer)
  }, [nodeIdFromUrl, nodes, t])
}
