import type { WorkflowCatalog, WorkflowDefinition } from '@/types/workflow'
import { DEMO_WORKFLOW } from '@/workflow/nodeCatalog'
import {
  cloneWorkflowDefinition,
  normalizeWorkflow,
  WORKFLOW_CATALOG_VERSION,
  WORKFLOW_EDITOR_STORAGE_KEY
} from '@/workflow/workflowUtils'

export const WORKFLOW_LIBRARY_STORAGE_KEY = 'workflowEditor.library'

export interface StoredWorkflowLibrary {
  catalogVersion: number
  workflows: WorkflowDefinition[]
  activeWorkflowId: string
}

export interface WorkflowCatalogExport {
  catalogVersion: number
  exportedAt: string
  workflows: WorkflowDefinition[]
}

let workflowSeq = 0

export function nextWorkflowId(): string {
  workflowSeq += 1
  return `wf-${Date.now()}-${workflowSeq}`
}

export function createEmptyWorkflow(name = '未命名流程'): WorkflowDefinition {
  return {
    id: nextWorkflowId(),
    name,
    version: 1,
    nodes: [],
    edges: [],
    viewport: { x: 0, y: 0, zoom: 0.85 }
  }
}

function seedLibrary(): StoredWorkflowLibrary {
  const demo = normalizeWorkflow(cloneWorkflowDefinition(DEMO_WORKFLOW))
  return {
    catalogVersion: WORKFLOW_CATALOG_VERSION,
    workflows: [demo],
    activeWorkflowId: demo.id
  }
}

/** 打开页面时的初始流程库（仅内存，不读 localStorage） */
export function createInitialWorkflowLibrary(): StoredWorkflowLibrary {
  return seedLibrary()
}

function migrateLegacyDraft(): WorkflowDefinition | null {
  try {
    const raw = localStorage.getItem(WORKFLOW_EDITOR_STORAGE_KEY)
    if (!raw) return null
    const parsed = JSON.parse(raw) as { catalogVersion?: number; workflow?: WorkflowDefinition }
    if (
      (parsed.catalogVersion === WORKFLOW_CATALOG_VERSION || parsed.catalogVersion === 2) &&
      parsed.workflow?.nodes
    ) {
      return normalizeWorkflow(parsed.workflow)
    }
    return null
  } catch {
    return null
  }
}

export function loadWorkflowLibrary(): StoredWorkflowLibrary {
  try {
    const raw = localStorage.getItem(WORKFLOW_LIBRARY_STORAGE_KEY)
    if (raw) {
      const parsed = JSON.parse(raw) as StoredWorkflowLibrary
      if (parsed.catalogVersion === WORKFLOW_CATALOG_VERSION && parsed.workflows?.length) {
        const activeId =
          parsed.activeWorkflowId && parsed.workflows.some((w) => w.id === parsed.activeWorkflowId)
            ? parsed.activeWorkflowId
            : parsed.workflows[0]!.id
        return {
          catalogVersion: WORKFLOW_CATALOG_VERSION,
          workflows: parsed.workflows.map((w) => normalizeWorkflow(w)),
          activeWorkflowId: activeId
        }
      }
    }
  } catch {
    /* ignore */
  }

  const legacy = migrateLegacyDraft()
  if (legacy) {
    return {
      catalogVersion: WORKFLOW_CATALOG_VERSION,
      workflows: [legacy],
      activeWorkflowId: legacy.id
    }
  }

  return seedLibrary()
}

export function saveWorkflowLibrary(lib: StoredWorkflowLibrary): void {
  try {
    localStorage.setItem(WORKFLOW_LIBRARY_STORAGE_KEY, JSON.stringify(lib))
  } catch {
    /* localStorage 可能被禁用 */
  }
}

export function toWorkflowCatalog(lib: StoredWorkflowLibrary): WorkflowCatalog {
  return {
    workflows: lib.workflows,
    activeWorkflowId: lib.activeWorkflowId
  }
}

export function getWorkflowById(lib: StoredWorkflowLibrary, id: string): WorkflowDefinition | undefined {
  return lib.workflows.find((w) => w.id === id)
}

export function getActiveWorkflow(lib: StoredWorkflowLibrary): WorkflowDefinition {
  return getWorkflowById(lib, lib.activeWorkflowId) ?? lib.workflows[0]!
}

/** 将当前编辑中的流程写回库（按 id 覆盖或追加） */
export function upsertWorkflow(
  lib: StoredWorkflowLibrary,
  workflow: WorkflowDefinition
): StoredWorkflowLibrary {
  const normalized = normalizeWorkflow(workflow)
  const idx = lib.workflows.findIndex((w) => w.id === normalized.id)
  const workflows =
    idx >= 0
      ? lib.workflows.map((w, i) => (i === idx ? normalized : w))
      : [...lib.workflows, normalized]
  return {
    catalogVersion: WORKFLOW_CATALOG_VERSION,
    workflows,
    activeWorkflowId: normalized.id
  }
}

export function setActiveWorkflowId(lib: StoredWorkflowLibrary, id: string): StoredWorkflowLibrary | null {
  if (!lib.workflows.some((w) => w.id === id)) return null
  return { ...lib, activeWorkflowId: id }
}

export function addWorkflow(lib: StoredWorkflowLibrary, workflow: WorkflowDefinition): StoredWorkflowLibrary {
  const normalized = normalizeWorkflow(workflow)
  if (lib.workflows.some((w) => w.id === normalized.id)) {
    return upsertWorkflow(lib, normalized)
  }
  return {
    catalogVersion: WORKFLOW_CATALOG_VERSION,
    workflows: [...lib.workflows, normalized],
    activeWorkflowId: normalized.id
  }
}

export function removeWorkflow(lib: StoredWorkflowLibrary, id: string): StoredWorkflowLibrary | null {
  if (lib.workflows.length <= 1) return null
  const workflows = lib.workflows.filter((w) => w.id !== id)
  let activeWorkflowId = lib.activeWorkflowId
  if (activeWorkflowId === id) {
    activeWorkflowId = workflows[0]!.id
  }
  return {
    catalogVersion: WORKFLOW_CATALOG_VERSION,
    workflows,
    activeWorkflowId
  }
}

export function duplicateWorkflow(lib: StoredWorkflowLibrary, id: string): StoredWorkflowLibrary | null {
  const source = getWorkflowById(lib, id)
  if (!source) return null
  const copy = normalizeWorkflow({
    ...cloneWorkflowDefinition(source),
    id: nextWorkflowId(),
    name: `${source.name}（副本）`
  })
  return addWorkflow(lib, copy)
}

/** 确保示例流程存在于库中，并返回更新后的库与示例 id */
export function ensureDemoInLibrary(lib: StoredWorkflowLibrary): {
  library: StoredWorkflowLibrary
  demoId: string
} {
  const demo = normalizeWorkflow(cloneWorkflowDefinition(DEMO_WORKFLOW))
  const exists = lib.workflows.some((w) => w.id === demo.id)
  const library = exists ? lib : addWorkflow(lib, demo)
  return { library, demoId: demo.id }
}

/** 将多个导入流程追加到库，返回新库与最后导入的流程 id（用于切换画布） */
export function mergeWorkflowsIntoLibrary(
  lib: StoredWorkflowLibrary,
  workflows: WorkflowDefinition[]
): { library: StoredWorkflowLibrary; lastImportedId: string } | null {
  if (workflows.length === 0) return null
  let result = lib
  for (const w of workflows) {
    result = addWorkflow(result, w)
  }
  return {
    library: result,
    lastImportedId: workflows[workflows.length - 1]!.id
  }
}
