import { createHttpError } from '../../../utils/http.js'
import { formatFenToAmount } from '../../../utils/money.js'
import { isPlainObject, pickFirstNonEmpty } from './context.js'
import { mapAdminObservedProductItem } from './domain.js'

type JsonObject = Record<string, any>

export function normalizeFulfillmentLookupPayload(payload: JsonObject = {}) {
  const provider = String(payload.provider || 'agiso').trim() || 'agiso'
  const platform = String(payload.platform || 'xianyu').trim() || 'xianyu'
  const shopId = String(payload.shopId || '').trim()
  const platformOrderId = String(payload.platformOrderId || '').trim()

  if (!shopId) {
    throw createHttpError('请先填写店铺 ID', {
      statusCode: 400,
      errorCode: 'admin_fulfillment_lookup_missing_shop_id',
    })
  }

  if (!platformOrderId) {
    throw createHttpError('请先填写平台订单号', {
      statusCode: 400,
      errorCode: 'admin_fulfillment_lookup_missing_platform_order_id',
    })
  }

  if (provider !== 'agiso' || platform !== 'xianyu') {
    throw createHttpError('目前仅支持 Agiso 咸鱼订单手动查询', {
      statusCode: 400,
      errorCode: 'admin_fulfillment_lookup_platform_not_supported',
    })
  }

  return { provider, platform, shopId, platformOrderId }
}

export function resolveFulfillmentLookupDetail(detailResult: JsonObject, platformOrderId: unknown) {
  const detail = isPlainObject(detailResult?.parsed) ? detailResult.parsed : {}
  const items = Array.isArray(detail.items) ? detail.items : []

  if (items.length > 0) {
    return { detail, items }
  }

  const detailReason = String(detailResult?.reason || '').trim()
  const detailMessage = String(detailResult?.errorMessage || '').trim()
  let message = detailMessage

  if (!message && detailReason === 'missing_config') {
    message = '当前店铺缺少订单详情查询配置，请先检查 accessToken、appSecret 和详情接口地址'
  }

  if (!message) {
    message = `未查询到订单 ${platformOrderId} 的商品明细`
  }

  throw createHttpError(message, {
    statusCode: 404,
    errorCode: 'admin_fulfillment_lookup_order_items_not_found',
  })
}

export function buildFulfillmentLookupResult({
  provider = '',
  platform = '',
  shopId = '',
  platformOrderId = '',
  detail = {},
  detailResult = {},
  bindings = [],
  fallbackShopName = '',
}: {
  provider?: string
  platform?: string
  shopId?: string
  platformOrderId?: string
  detail?: JsonObject
  detailResult?: JsonObject
  bindings?: JsonObject[]
  fallbackShopName?: string
} = {}) {
  const resolvedShopName = pickFirstNonEmpty([detail.shopName, fallbackShopName])
  const items = Array.isArray(detail.items) ? detail.items : []

  return {
    order: {
      provider,
      platform,
      shopId,
      shopName: resolvedShopName,
      platformOrderId,
      buyerName: String(detail.buyerName || '').trim(),
      totalAmountFen: Number(detail.totalAmount || 0),
      totalAmount: formatFenToAmount(detail.totalAmount),
      paidAt: detail.paidAt || null,
      enriched: Boolean(detailResult?.enriched),
      enrichReason: String(detailResult?.reason || '').trim(),
      errorMessage: String(detailResult?.errorMessage || '').trim(),
    },
    items: items.map((item, index) => {
      const observed = {
        provider,
        platform,
        shopId,
        shopName: resolvedShopName,
        externalItemId: pickFirstNonEmpty([item?.externalItemId, item?.itemId]),
        externalSkuCode: pickFirstNonEmpty([
          item?.externalSkuCode,
          item?.skuCode,
          item?.externalItemId,
          item?.itemId,
        ]),
        externalSkuName: pickFirstNonEmpty([item?.externalSkuName, item?.skuName]),
        latestSeenAt: null,
        orderItemCount: Math.max(1, Number(item?.quantity || 0) || 1),
      }

      return {
        lineId: [
          platformOrderId,
          index + 1,
          observed.externalSkuCode || 'na',
          observed.externalItemId || 'na',
        ].join(':'),
        itemTitle: pickFirstNonEmpty([
          item?.skuName,
          item?.externalSkuName,
          item?.externalSkuCode,
          item?.externalItemId,
        ]),
        quantity: observed.orderItemCount,
        ...mapAdminObservedProductItem(observed, bindings),
      }
    }),
  }
}
