import type { MemoryGraphLink, MemoryGraphNode, MemoryVisualization, Word } from '../api/request'
import { buildFocusNodes } from '../composables/useGraphFilter'
import type { LinkKind } from '../composables/useGraphFilter'

const DEFAULT_LINK_FILTERS: Record<LinkKind, boolean> = {
  co_review: true,
  status: true,
  similar: true,
}

function enText(w: Word) {
  return w.source_lang === 'en' ? w.source_text : w.target_text
}

function zhText(w: Word) {
  return w.source_lang === 'zh' ? w.source_text : w.target_text
}

/** 单词练习时展开为聚焦子图；多词练习则展示全部待练词 */
export function resolvePracticeDisplayIds(
  practiceIds: string[],
  storedDisplayIds: string[],
  viz: MemoryVisualization
): string[] {
  if (practiceIds.length > 1) {
    const coversAll =
      storedDisplayIds.length >= practiceIds.length &&
      practiceIds.every((id) => storedDisplayIds.includes(id))
    return coversAll ? storedDisplayIds : practiceIds
  }

  if (practiceIds.length !== 1) return practiceIds

  const center = practiceIds[0]
  if (storedDisplayIds.length > 1) return storedDisplayIds

  return buildFocusNodes(viz, center, '', '', DEFAULT_LINK_FILTERS).map((n) => n.id)
}

export function buildPracticeGraphNodes(
  displayIds: string[],
  vizNodes: MemoryGraphNode[],
  words: Word[]
): MemoryGraphNode[] {
  const byId = new Map(vizNodes.map((n) => [n.id, n]))
  const out: MemoryGraphNode[] = []

  for (const id of displayIds) {
    const existing = byId.get(id)
    if (existing) {
      out.push(existing)
      continue
    }
    const w = words.find((x) => String(x.id) === id)
    if (!w) continue
    out.push({
      id,
      label: enText(w).slice(0, 16),
      zh: zhText(w).slice(0, 8),
      status: w.status,
      mastery: w.mastery_score,
      entered_at: w.entered_at || w.created_at,
      size: 8 + Math.min(w.correct_count + w.wrong_count, 20),
    })
  }
  return out
}

export function buildPracticeGraphLinks(
  displayIds: string[],
  vizLinks: MemoryGraphLink[]
): MemoryGraphLink[] {
  const ids = new Set(displayIds)
  return vizLinks.filter((l) => ids.has(l.source) && ids.has(l.target))
}
