import { nextTick, type Reactive, type Ref } from 'vue'
import { ElMessage } from 'element-plus'
import type {
  ExternalDataSource,
  ProcessType,
  StepId,
  StructuredProcessOptions,
  UnstructuredProcessOptions,
} from './types'

export const DATA_PROCESS_DRAFT_STORAGE_KEY = 'yg-data-process-create-draft'
export const DATA_PROCESS_DRAFT_SCHEMA_VERSION = 6

interface DraftSnapshot {
  schemaVersion?: number
  currentStepId?: StepId
  task?: { name?: string; description?: string }
  processType?: ProcessType
  structuredOptions?: Partial<StructuredProcessOptions>
  unstructuredOptions?: Partial<UnstructuredProcessOptions>
  externalSource?: Partial<ExternalDataSource>
}

interface DraftBindings {
  currentStepId: Readonly<Ref<StepId>>
  task: Reactive<{ name: string; description: string }>
  processType: Ref<ProcessType>
  structuredOptions: Ref<StructuredProcessOptions>
  unstructuredOptions: Ref<UnstructuredProcessOptions>
  externalSource: Reactive<ExternalDataSource>
  restoringDraft: Ref<boolean>
  dirty: Ref<boolean>
  goToStep: (stepId: StepId) => void
}

function sanitizeExternalSource(source: Partial<ExternalDataSource>) {
  return {
    type: typeof source.type === 'string' ? source.type : 'mysql',
    url: typeof source.url === 'string' ? source.url : '',
    authMode: typeof source.authMode === 'string' ? source.authMode : 'none',
    username: typeof source.username === 'string' ? source.username : '',
    limit: Number.isFinite(source.limit) ? Number(source.limit) : 1000,
  }
}

function isDraftSnapshot(value: unknown): value is DraftSnapshot {
  return Boolean(value && typeof value === 'object')
}

/**
 * 只持久化可重建的配置。密码、令牌、文件正文、预览与结果都不进入 localStorage。
 */
export function useDataProcessDraft(bindings: DraftBindings) {
  function draftSnapshot(): DraftSnapshot {
    return {
      schemaVersion: DATA_PROCESS_DRAFT_SCHEMA_VERSION,
      currentStepId: bindings.currentStepId.value,
      task: { ...bindings.task },
      processType: bindings.processType.value,
      structuredOptions: {
        ...bindings.structuredOptions.value,
        preprocessOptions: [...bindings.structuredOptions.value.preprocessOptions],
        datasetSplit: { ...bindings.structuredOptions.value.datasetSplit },
      },
      unstructuredOptions: {
        ...bindings.unstructuredOptions.value,
        preprocessOptions: [...bindings.unstructuredOptions.value.preprocessOptions],
        datasetSplit: { ...bindings.unstructuredOptions.value.datasetSplit },
      },
      externalSource: sanitizeExternalSource(bindings.externalSource),
    }
  }

  function writeDraft(showWarning: boolean) {
    try {
      localStorage.setItem(DATA_PROCESS_DRAFT_STORAGE_KEY, JSON.stringify(draftSnapshot()))
    } catch {
      if (showWarning) ElMessage.warning('草稿保存失败，请检查浏览器存储空间')
    }
  }

  function persistDraft() {
    if (!bindings.restoringDraft.value) writeDraft(true)
  }

  function restoreDraft() {
    try {
      const raw = localStorage.getItem(DATA_PROCESS_DRAFT_STORAGE_KEY)
      if (!raw) return
      const snapshot: unknown = JSON.parse(raw)
      if (!isDraftSnapshot(snapshot)) return

      bindings.restoringDraft.value = true
      bindings.goToStep('create')
      bindings.task.name = snapshot.task?.name || ''
      bindings.task.description = snapshot.task?.description || ''
      bindings.processType.value = snapshot.processType === 'unstructured' || snapshot.processType === 'external'
        ? snapshot.processType
        : 'structured'

      if (snapshot.structuredOptions) {
        bindings.structuredOptions.value = {
          ...bindings.structuredOptions.value,
          ...snapshot.structuredOptions,
          preprocessOptions: Array.isArray(snapshot.structuredOptions.preprocessOptions)
            ? snapshot.structuredOptions.preprocessOptions
            : bindings.structuredOptions.value.preprocessOptions,
          datasetSplit: {
            ...bindings.structuredOptions.value.datasetSplit,
            ...snapshot.structuredOptions.datasetSplit,
          },
        }
      }

      if (snapshot.unstructuredOptions) {
        bindings.unstructuredOptions.value = {
          ...bindings.unstructuredOptions.value,
          ...snapshot.unstructuredOptions,
          preprocessOptions: Array.isArray(snapshot.unstructuredOptions.preprocessOptions)
            ? snapshot.unstructuredOptions.preprocessOptions
            : bindings.unstructuredOptions.value.preprocessOptions,
          datasetSplit: {
            ...bindings.unstructuredOptions.value.datasetSplit,
            ...snapshot.unstructuredOptions.datasetSplit,
          },
        }
      }

      Object.assign(bindings.externalSource, sanitizeExternalSource(snapshot.externalSource || {}), {
        password: '',
        token: '',
      })
      bindings.dirty.value = false

      nextTick(() => {
        bindings.restoringDraft.value = false
        // 立即覆盖 v5 及更早草稿，清除其中可能存在的敏感值和大段正文。
        writeDraft(false)
      })
      ElMessage.info('已恢复上次的任务配置，请重新上传或拉取源数据')
    } catch {
      localStorage.removeItem(DATA_PROCESS_DRAFT_STORAGE_KEY)
    }
  }

  return { draftSnapshot, persistDraft, restoreDraft }
}
