import {
  getFulfillmentProfileByKey,
  listFulfillmentProfileRequirements,
  replaceFulfillmentProfileRequirements,
  upsertFulfillmentProfile,
  upsertSkuFulfillmentBinding,
} from '../../repositories/fulfillment-profile-repo.js'
import { upsertProductMatchRule } from '../../repositories/product-match-rule-repo.js'
import { normalizeProductName } from '../order/product-match-service.js'
import { query } from '../../db/client.js'
import { getLegacyOrderFulfillmentBindingConfigs } from '../order/fulfillment-binding-config-service.js'
import {
  getKuaishouCloudFulfillmentConfig,
  mapKuaishouCloudFulfillmentItemsToBindings,
} from '../order/kuaishou-cloud-fulfillment-config-service.js'
import { nowIso } from '../../utils/time.js'

const CORE_PROFILES = [
  {
    profileKey: 'manual_review',
    name: '人工发货',
    executorKey: 'manual_dispatch',
    requiresClaim: false,
    autoDispatch: false,
    inventoryStrategy: 'static_pool',
    requirements: [],
  },
  {
    profileKey: 'tencent_claim_redeem',
    name: '腾讯领取兑换',
    executorKey: 'tencent_claim_redeem',
    requiresClaim: true,
    autoDispatch: false,
    inventoryStrategy: 'static_pool',
    requirements: [
      {
        roleKey: 'primary_code',
        credentialType: 'tencent_code',
        quantityPerUnit: 1,
        isRequired: true,
      },
    ],
  },
  {
    profileKey: 'tencent_claim_assisted',
    name: '腾讯领取兑换（半自动+人工）',
    executorKey: 'tencent_claim_assisted',
    requiresClaim: true,
    autoDispatch: false,
    inventoryStrategy: 'static_pool',
    requirements: [
      {
        roleKey: 'primary_code',
        credentialType: 'tencent_code',
        quantityPerUnit: 1,
        isRequired: true,
      },
    ],
  },
  {
    profileKey: 'kuaishou_ct_assisted',
    name: '快手 cloud 履约',
    executorKey: 'kuaishou_ct_assisted',
    requiresClaim: false,
    autoDispatch: false,
    inventoryStrategy: 'external_platform',
    requirements: [],
  },
]

type JsonObject = Record<string, any>

export async function ensureFulfillmentCatalogBootstrapped() {
  const profileMap = await ensureCoreProfiles()
  await syncConfiguredFulfillmentBindings(profileMap)
}

async function ensureCoreProfiles() {
  const timestamp = nowIso()
  const profileMap = {}

  for (const profile of CORE_PROFILES) {
    const saved = await upsertFulfillmentProfile({
      profileKey: profile.profileKey,
      name: profile.name,
      executorKey: profile.executorKey,
      requiresClaim: profile.requiresClaim,
      autoDispatch: profile.autoDispatch,
      inventoryStrategy: profile.inventoryStrategy,
      configJson: '{}',
      createdAt: timestamp,
      updatedAt: timestamp,
    })

    if (!saved) {
      continue
    }

    profileMap[profile.profileKey] = saved
    const currentRequirements = await listFulfillmentProfileRequirements(saved.id)
    if (currentRequirements.length !== profile.requirements.length) {
      await replaceFulfillmentProfileRequirements(saved.id, profile.requirements, timestamp)
    }
  }

  return profileMap
}

export async function syncConfiguredFulfillmentBindings(profileMap: JsonObject = {}) {
  const timestamp = nowIso()
  const bindingsToApply = [
    ...getLegacyOrderFulfillmentBindingConfigs(),
    ...mapKuaishouCloudFulfillmentItemsToBindings(getKuaishouCloudFulfillmentConfig()),
  ]

  await query('DELETE FROM product_match_rules')
  await query('DELETE FROM sku_fulfillment_bindings')

  for (const binding of bindingsToApply) {
    const profile = profileMap[binding.profileKey] || await getFulfillmentProfileByKey(binding.profileKey)
    if (!profile) {
      continue
    }

    const bindingConfig = resolveBindingRuntimeConfig(binding)
    const matchShopIds = resolveBindingMatchShopIds(binding)
    const match = binding.match || {}
    const externalSkuName = String(match.externalSkuName || '').trim()
    const externalItemId = String(match.externalItemId || '').trim()
    const externalSkuCode = String(match.externalSkuCode || '').trim()

    for (const matchShopId of matchShopIds) {
      await upsertSkuFulfillmentBinding({
        skuCode: binding.skuCode,
        provider: binding.provider,
        platform: binding.platform,
        shopId: matchShopId,
        profileId: profile.id,
        enabled: binding.enabled,
        priority: binding.priority,
        configJson: JSON.stringify(bindingConfig),
        createdAt: timestamp,
        updatedAt: timestamp,
      })

      if (!externalSkuName && !externalItemId && !externalSkuCode) {
        continue
      }

      await upsertProductMatchRule({
        provider: binding.provider,
        platform: binding.platform,
        shopId: matchShopId,
        externalItemId,
        externalSkuCode,
        externalSkuName,
        externalSkuNameNormalized: normalizeProductName(externalSkuName),
        resolvedSkuCode: binding.skuCode,
        enabled: binding.enabled,
        priority: binding.priority,
        configJson: JSON.stringify(match.config || {}),
        createdAt: timestamp,
        updatedAt: timestamp,
      })
    }
  }
}

export function resolveBindingMatchShopIds(binding: JsonObject = {}) {
  return [String(binding.shopId || '').trim()]
}

function resolveBindingRuntimeConfig(binding: JsonObject = {}) {
  const baseConfig = isPlainObject(binding.config) ? { ...binding.config } : {}

  if (String(binding.provider || '').trim() === '91kaquan' && String(binding.platform || '').trim() === 'kuaishou') {
    baseConfig.kuaishouShop = {
      ...(isPlainObject(baseConfig.kuaishouShop) ? baseConfig.kuaishouShop : {}),
      shopId: String(binding.shopId || '').trim(),
      shopName: String(binding.shopName || '').trim(),
    }
  }

  return baseConfig
}

function isPlainObject(value) {
  return Object.prototype.toString.call(value) === '[object Object]'
}
