import fs from 'node:fs'
import path from 'node:path'

import { APP_CONFIG_KEYS } from '../../config/app-config-keys.js'
import { PROJECT_ROOT } from '../../config/runtime.js'
import { upsertAppConfigEntry } from '../../repositories/app-config-repo.js'
import { logInfo, logWarn } from '../../utils/logger.js'
import { normalizeFulfillmentRoutingConfig } from '../fulfillment/routing-config-service.js'
import { normalizeNotificationConfig } from '../notification/config-service.js'
import { normalizeCloudtentaclesOverrideRuleConfig } from '../order/cloudtentacles-override-rule-service.js'
import { normalizeCloudtentaclesSourcesConfig } from '../platforms/cloudtentacles/source-config-service.js'
import { normalizeSessionStatesFile } from '../platforms/cloudtentacles/session-state-service.js'
import { normalizeKuaishouFeifeiSourceConfig } from '../platforms/kuaishou-feifei/source-config-service.js'
import { normalizeKuaishouIndustrySourceConfig } from '../platforms/kuaishou-industry/source-config-service.js'
import { normalizeScheduledJobsConfig } from '../scheduler/config-service.js'
import { loadAppConfigCacheFromDatabase } from './app-config-store.js'

type JsonConfigMigrationItem = {
  configKey: string
  fileName: string
  normalize: (value: unknown) => unknown
}

const DATA_DIR = path.join(PROJECT_ROOT, 'data')

const JSON_CONFIG_MIGRATION_ITEMS: JsonConfigMigrationItem[] = [
  {
    configKey: APP_CONFIG_KEYS.notification,
    fileName: 'notification-config.json',
    normalize: normalizeNotificationConfig,
  },
  {
    configKey: APP_CONFIG_KEYS.scheduledJobs,
    fileName: 'scheduled-jobs.json',
    normalize: normalizeScheduledJobsConfig,
  },
  {
    configKey: APP_CONFIG_KEYS.fulfillmentRouting,
    fileName: 'fulfillment-routing-config.json',
    normalize: normalizeFulfillmentRoutingConfig,
  },
  {
    configKey: APP_CONFIG_KEYS.cloudtentaclesSources,
    fileName: 'cloudtentacles-sources.json',
    normalize: normalizeCloudtentaclesSourcesConfig,
  },
  {
    configKey: APP_CONFIG_KEYS.cloudtentaclesSession,
    fileName: 'cloudtentacles-session.json',
    normalize: normalizeSessionStatesFile,
  },
  {
    configKey: APP_CONFIG_KEYS.cloudtentaclesOverrideRules,
    fileName: 'cloudtentacles-override-rules.json',
    normalize: normalizeCloudtentaclesOverrideRuleConfig,
  },
  {
    configKey: APP_CONFIG_KEYS.kuaishouFeifei,
    fileName: 'kuaishou-feifei-config.json',
    normalize: normalizeKuaishouFeifeiSourceConfig,
  },
  {
    configKey: APP_CONFIG_KEYS.kuaishouIndustrySource,
    fileName: 'kuaishou-industry-source.json',
    normalize: normalizeKuaishouIndustrySourceConfig,
  },
]

export async function migrateJsonConfigFilesToDatabase() {
  const migrated: Array<{ configKey: string; filePath: string }> = []
  const skipped: Array<{ configKey: string; filePath: string; reason: string }> = []

  for (const item of JSON_CONFIG_MIGRATION_ITEMS) {
    const filePath = path.join(DATA_DIR, item.fileName)
    if (!fs.existsSync(filePath)) {
      continue
    }

    let normalized: unknown
    try {
      const rawText = fs.readFileSync(filePath, 'utf8')
      normalized = item.normalize(JSON.parse(rawText))
    } catch (error) {
      skipped.push({
        configKey: item.configKey,
        filePath,
        reason: error instanceof Error ? error.message : String(error),
      })
      logWarn('[config/migration]', 'JSON 配置解析失败，已保留原文件', {
        configKey: item.configKey,
        filePath,
        error,
      })
      continue
    }

    await upsertAppConfigEntry({
      configKey: item.configKey,
      configJson: normalized,
      sourceFilePath: filePath,
      migratedFromFile: true,
      timestamp: new Date().toISOString(),
    })

    try {
      fs.unlinkSync(filePath)
      migrated.push({
        configKey: item.configKey,
        filePath,
      })
    } catch (error) {
      skipped.push({
        configKey: item.configKey,
        filePath,
        reason: error instanceof Error ? error.message : String(error),
      })
      logWarn('[config/migration]', 'JSON 配置已入库，但删除原文件失败', {
        configKey: item.configKey,
        filePath,
        error,
      })
    }
  }

  await loadAppConfigCacheFromDatabase()

  if (migrated.length > 0 || skipped.length > 0) {
    logInfo('[config/migration]', 'JSON 配置文件迁移完成', {
      migratedCount: migrated.length,
      skippedCount: skipped.length,
      migrated,
      skipped,
    })
  }

  return {
    migrated,
    skipped,
  }
}
