import { useCanvasStore } from '@/stores/canvas-store'
import { useDocumentStore } from '@/stores/document-store'
import type { PenNode } from '@/types/pen'

/**
 * Pure utility module for depth-aware selection.
 * Determines which nodes are selectable at the current entered-frame depth.
 */

/** Returns the set of node IDs that are selectable at the current depth. */
export function getSelectableNodeIds(): Set<string> {
  const { enteredFrameId } = useCanvasStore.getState().selection
  const doc = useDocumentStore.getState().document

  if (!enteredFrameId) {
    // Root level: only top-level children are selectable
    return new Set(doc.children.map((n) => n.id))
  }

  const frame = useDocumentStore.getState().getNodeById(enteredFrameId)
  if (!frame || !('children' in frame) || !frame.children) {
    return new Set()
  }
  return new Set(frame.children.map((n) => n.id))
}

/**
 * Given a Fabric target's penNodeId, resolve it to the selectable node
 * at the current depth. Walks up the parent chain until it finds a node
 * in the selectable set.
 *
 * Returns null if the target is entirely outside the current context
 * (e.g. belongs to a different root frame when inside an entered frame).
 */
export function resolveTargetAtDepth(nodeId: string): string | null {
  const selectableIds = getSelectableNodeIds()

  // Direct match
  if (selectableIds.has(nodeId)) return nodeId

  // Handle virtual instance child IDs (refId__childId)
  if (nodeId.includes('__')) {
    const refId = nodeId.substring(0, nodeId.indexOf('__'))
    if (selectableIds.has(refId)) return refId
    // Walk up from the RefNode
    let cur: string | undefined = refId
    while (cur) {
      const parent = useDocumentStore.getState().getParentOf(cur)
      if (!parent) break
      if (selectableIds.has(parent.id)) return parent.id
      cur = parent.id
    }
  }

  // Walk up parent chain
  let currentId: string | undefined = nodeId
  while (currentId) {
    const parent = useDocumentStore.getState().getParentOf(currentId)
    if (!parent) break
    if (selectableIds.has(parent.id)) return parent.id
    currentId = parent.id
  }

  return null
}

/** Check whether a node is a container that can be "entered" via double-click. */
export function isEnterableContainer(nodeId: string): boolean {
  const node = useDocumentStore.getState().getNodeById(nodeId)
  if (!node) return false
  if (node.type !== 'frame' && node.type !== 'group') return false
  if (!('children' in node) || !node.children || node.children.length === 0) return false
  return true
}

/** Return the direct children IDs of a container node. */
export function getChildIds(nodeId: string): Set<string> {
  const node = useDocumentStore.getState().getNodeById(nodeId)
  if (!node || !('children' in node) || !node.children) return new Set()
  return new Set(node.children.map((n: PenNode) => n.id))
}
