import { api } from '../api/client'
import type { KnowledgeGraphData, ExpandKnowledgeGraphData, KnowledgeGraphNode } from './knowledgeGraph'
import type { SourcePreviewItem } from './sourcePreview'
import type { CopyMissionResearchMapData } from '../types/copyMission'

export function copyMissionGraphPath(personaId: string, missionId: string) {
  return `/api/v1/personas/${encodeURIComponent(personaId)}/copy-missions/${encodeURIComponent(missionId)}/knowledge-graph`
}

export async function fetchCopyMissionGraph(personaId: string, missionId: string) {
  return api.get<KnowledgeGraphData>(copyMissionGraphPath(personaId, missionId), { auth: true })
}

export async function expandCopyMissionGraph(
  personaId: string,
  missionId: string,
  body: { seed_query: string; supplemental?: boolean },
) {
  return api.post<ExpandKnowledgeGraphData>(
    `${copyMissionGraphPath(personaId, missionId)}/expand`,
    body,
    { auth: true },
  )
}

export async function patchCopyMissionGraphNodes(
  personaId: string,
  missionId: string,
  updates: { node_id: string; selected_for_scan: boolean }[],
) {
  return api.patch<KnowledgeGraphData>(
    `${copyMissionGraphPath(personaId, missionId)}/nodes`,
    { updates },
    { auth: true },
  )
}

export function countSelectedGraphNodes(nodes: KnowledgeGraphNode[] | null | undefined): number {
  return (nodes ?? []).filter((node) => node.selected_for_scan).length
}

export function graphSelectionDirty(
  draft: KnowledgeGraphNode[],
  saved: KnowledgeGraphNode[] | null | undefined,
): boolean {
  if (!draft.length) return false
  const savedMap = new Map((saved ?? []).map((node) => [node.id, !!node.selected_for_scan]))
  for (const node of draft) {
    if (savedMap.get(node.id) !== !!node.selected_for_scan) return true
  }
  return false
}

/** 背景重載時保留使用者尚未儲存的勾選狀態。 */
export function mergeGraphDraftWithServer(
  draft: KnowledgeGraphNode[],
  server: KnowledgeGraphNode[] | null | undefined,
): KnowledgeGraphNode[] {
  const serverNodes = server ?? []
  if (!draft.length) return serverNodes
  const draftById = new Map(draft.map((node) => [node.id, node]))
  const merged: KnowledgeGraphNode[] = serverNodes.map((serverNode) => {
    const local = draftById.get(serverNode.id)
    return local ? { ...serverNode, selected_for_scan: local.selected_for_scan } : serverNode
  })
  const serverIds = new Set(serverNodes.map((node) => node.id))
  for (const localNode of draft) {
    if (!serverIds.has(localNode.id)) merged.push(localNode)
  }
  return merged
}

export function mergeCopyMissionSources(
  map: CopyMissionResearchMapData | null | undefined,
  graph: KnowledgeGraphData | null | undefined,
): SourcePreviewItem[] {
  const seen = new Set<string>()
  const merged: SourcePreviewItem[] = []
  for (const src of [...(graph?.brave_sources ?? []), ...(map?.research_items ?? [])]) {
    const key = src.url?.trim() || `${src.query}-${src.snippet}`
    if (!key || seen.has(key)) continue
    seen.add(key)
    merged.push(src)
  }
  return merged
}