/**
 * 开发环境专用 Mock 数据工厂。
 * 生产环境禁止调用；由路由层 isDevMockEnabled 拦截。
 */
import crypto from 'node:crypto'

import { createOrder, findOrderByPlatformOrderId } from '../../repositories/order-repo.js'
import { replaceOrderItems } from '../../repositories/order-item-repo.js'
import { createTask, updateTask } from '../../repositories/task-repo.js'
import { upsertKuaishouIndustryVoucher } from '../../repositories/kuaishou-industry-voucher-repo.js'
import {
  getFulfillmentProfileByKey,
  upsertFulfillmentProfile,
} from '../../repositories/fulfillment-profile-repo.js'
import { buildClaimUrl, createTaskClaimToken } from '../claim/claim-service.js'
import { assertValidClaimUid, normalizeClaimUid } from '../claim/claim-identity.js'
import { OPEN_91_PLATFORM, OPEN_91_PROVIDER, assertOpen91Config } from '../open-91/config.js'
import { parseOpen91ProductNo } from '../platforms/ninetyone/order-service.js'
import {
  getKuaishouIndustrySourceConfig,
  listKuaishouIndustryShopConfigs,
} from '../platforms/kuaishou-industry/source-config-service.js'
import { isProductionLike } from '../../config/runtime-validation.js'
import { createHttpError } from '../../utils/http.js'
import { addHours, nowIso } from '../../utils/time.js'
import { randomId } from '../../utils/random.js'
import { TASK_STATUS } from '../../domain/task-status.js'

export type LewanMockStep = 'uid' | 'binding' | 'confirm' | 'result'
export type FeifeiMockStep = 'uid' | 'ready' | 'completed' | 'failed'

export type DevMockCreateResult = {
  platform: 'lewan' | 'feifei' | 'affiliate_dash'
  orderId: number
  orderNo: string
  taskId: number
  taskNo: string
  claimToken: string
  claimUrl: string
  frontendClaimUrl: string
  expectedUid: string
  step: string
  productName: string
  tips: string[]
  open91QueryHint: string
}

export type DevMockKuaishouIndustryVoucherResult = {
  createdCount: number
  sellerId: string
  vouchers: Array<{
    voucherCode: string
    oid: string
    status: string
  }>
}

type DeliveryItem = {
  cloudSkuId: number
  cloudSkuName: string
  quantity: number
}

export function isDevMockEnabled(env: NodeJS.ProcessEnv = process.env): boolean {
  if (String(env.ENABLE_DEV_MOCK || '').trim() === '1') {
    return true
  }
  if (
    String(env.ENABLE_DEV_MOCK || '')
      .trim()
      .toLowerCase() === 'true'
  ) {
    return true
  }
  return !isProductionLike(env)
}

export function assertDevMockEnabled() {
  if (!isDevMockEnabled()) {
    throw createHttpError('当前环境未开启开发 Mock（仅非 production 或 ENABLE_DEV_MOCK=1）', {
      statusCode: 403,
      errorCode: 'dev_mock_disabled',
    })
  }
}

export function getDevMockStatus() {
  const enabled = isDevMockEnabled()
  return {
    enabled,
    nodeEnv: String(process.env.NODE_ENV || 'development'),
    platforms: enabled
      ? [
          {
            key: 'lewan',
            name: 'kuaishou-lewan',
            description: '本站 claim + 强制 UID 匹配 + mock 兑换（不调 CloudTentacles）',
            steps: ['uid', 'binding', 'confirm', 'result'],
          },
          {
            key: 'feifei',
            name: 'kuaishou-feifei',
            description: '本站 claim + 拼 uid 的 H5 链接（不调真实 feifei 下单）',
            steps: ['uid', 'ready', 'completed', 'failed'],
          },
          {
            key: 'affiliate_dash',
            name: 'affiliate-dash',
            description: '本站 claim + mock 绑定二维码/提交发货（不调真实 affiliate-dash 平台）',
            steps: ['uid', 'bind', 'submitted', 'completed', 'failed'],
          },
        ]
      : [],
    defaultUid: '10001',
  }
}

export async function createLewanMockClaim(
  input: {
    step?: unknown
    orderNo?: unknown
    productNo?: unknown
    uid?: unknown
    items?: unknown
    frontendBaseUrl?: unknown
  } = {},
): Promise<DevMockCreateResult> {
  assertDevMockEnabled()

  const step = normalizeLewanStep(input.step)
  const orderNo = String(input.orderNo || `MOCK91${Date.now()}`).trim()
  const productNo = String(input.productNo || '套餐_1----3676797936').trim()
  const productInfo = parseOpen91ProductNo(productNo)
  const productName = productInfo.productName || productInfo.rawProductNo || '套餐_1'
  const consumeShopId = productInfo.shopId || '3676797936'
  const expectedUid = resolveMockUid(input.uid, step === 'uid' ? '' : '10001')
  const deliveryItems = parseDeliveryItems(input.items)
  const now = nowIso()

  await assertOrderNoAvailable(orderNo)

  const profile = await ensureProfile('kuaishou_ct_assisted', 'kuaishou-lewan 履约', false)
  const order = await createBaseOrder({
    orderNo,
    productNo,
    productName,
    now,
    platformTag: 'lewan',
  })
  const orderItem = await createBaseOrderItem({
    orderId: order.id,
    orderNo,
    productNo,
    productName,
    consumeShopId,
    deliveryItems,
    now,
    executor: 'lewan',
  })

  const task = await createTask({
    orderId: order.id,
    orderItemId: orderItem.id,
    unitIndex: 1,
    provider: OPEN_91_PROVIDER,
    platform: OPEN_91_PLATFORM,
    shopId: OPEN_91_PROVIDER,
    shopName: '91卡券',
    platformOrderId: orderNo,
    taskNo: randomId('DT'),
    profileId: profile.id,
    executorKey: 'kuaishou_ct_assisted',
    taskStatus: resolveLewanTaskStatus(step),
    deliveryStatus: step === 'result' ? 'success' : 'pending',
    resultCode: step === 'result' ? 'mock_success' : '',
    resultMessage: step === 'result' ? '开发 mock 已模拟兑换成功' : '',
    claimToken: '',
    claimExpiresAt: null,
    automationMode: 'manual',
    requiresClaim: true,
    userActionStatus: step === 'result' ? 'not_required' : 'pending_claim',
    attemptCount: 0,
    lastError: '',
    contextJson: JSON.stringify(
      buildLewanMockContext({
        step,
        orderNo,
        productName,
        productNo,
        consumeShopId,
        deliveryItems,
        expectedUid,
        timestamp: now,
      }),
    ),
    createdAt: now,
    updatedAt: now,
  })

  if (!task) {
    throw createHttpError('履约任务创建失败', {
      statusCode: 500,
      errorCode: 'dev_mock_task_failed',
    })
  }

  const claimToken = await createTaskClaimToken(task.id)
  await updateTask(task.id, {
    claim_token: claimToken.token,
    claim_expires_at: claimToken.expired_at,
    claimed_at: step === 'uid' ? null : now,
    role_confirmed_at: step === 'confirm' || step === 'result' ? now : null,
    redeemed_at: step === 'result' ? now : null,
    role_id: ['binding', 'confirm', 'result'].includes(step) ? expectedUid || '10001' : '',
    role_name: ['binding', 'confirm', 'result'].includes(step) ? '测试角色' : '',
    updated_at: now,
  })

  return buildCreateResult({
    platform: 'lewan',
    orderId: order.id,
    orderNo,
    taskId: task.id,
    taskNo: task.task_no,
    claimToken: claimToken.token,
    claimUrl: buildClaimUrl(claimToken.token),
    frontendBaseUrl: input.frontendBaseUrl,
    expectedUid: expectedUid || '10001',
    step,
    productName,
    tips: buildLewanTips(step, expectedUid || '10001'),
  })
}

export async function createFeifeiMockClaim(
  input: {
    step?: unknown
    orderNo?: unknown
    productName?: unknown
    productCode?: unknown
    uid?: unknown
    h5Url?: unknown
    frontendBaseUrl?: unknown
  } = {},
): Promise<DevMockCreateResult> {
  assertDevMockEnabled()

  const step = normalizeFeifeiStep(input.step)
  const orderNo = String(input.orderNo || `MOCKFF${Date.now()}`).trim()
  const productName = String(input.productName || '套装-浪漫天命').trim()
  const productCode = String(input.productCode || `MOCK-FF-${Date.now()}`).trim()
  const expectedUid = resolveMockUid(input.uid, step === 'uid' ? '' : '166909256')
  const rawH5 =
    String(input.h5Url || '').trim() ||
    `http://skin-exchange.yiquyou.icu/h5/bind?code=mock_${encodeURIComponent(orderNo)}&product_name=${encodeURIComponent(productName)}`
  const now = nowIso()

  await assertOrderNoAvailable(orderNo)

  const profile = await ensureProfile('kuaishou_feifei', 'kuaishou-feifei 履约', true)
  const order = await createBaseOrder({
    orderNo,
    productNo: productName,
    productName,
    now,
    platformTag: 'feifei',
  })
  const orderItem = await createBaseOrderItem({
    orderId: order.id,
    orderNo,
    productNo: productName,
    productName,
    consumeShopId: '',
    deliveryItems: [],
    now,
    executor: 'feifei',
    productCode,
  })

  const rechargeStatus =
    step === 'completed' ? 30 : step === 'failed' ? 40 : step === 'ready' ? 15 : 15
  const rechargeStatusLabel =
    step === 'completed'
      ? '充值成功'
      : step === 'failed'
        ? '充值失败'
        : step === 'ready'
          ? '待绑定'
          : '待领取'

  const task = await createTask({
    orderId: order.id,
    orderItemId: orderItem.id,
    unitIndex: 1,
    provider: OPEN_91_PROVIDER,
    platform: OPEN_91_PLATFORM,
    shopId: OPEN_91_PROVIDER,
    shopName: '91卡券',
    platformOrderId: orderNo,
    taskNo: randomId('DT'),
    profileId: profile.id,
    executorKey: 'kuaishou_feifei',
    taskStatus:
      step === 'completed'
        ? TASK_STATUS.COMPLETED
        : step === 'failed'
          ? TASK_STATUS.MANUAL_REVIEW
          : TASK_STATUS.LINK_GENERATED,
    deliveryStatus: step === 'completed' ? 'delivered' : 'pending',
    resultCode:
      step === 'completed'
        ? 'kuaishou_feifei_completed'
        : step === 'failed'
          ? 'kuaishou_feifei_status_40'
          : '',
    resultMessage: rechargeStatusLabel,
    claimToken: '',
    claimExpiresAt: null,
    automationMode: 'manual',
    requiresClaim: true,
    userActionStatus: step === 'completed' ? 'not_required' : 'pending_claim',
    attemptCount: 0,
    lastError: step === 'failed' ? '开发 mock 模拟 feifei 失败' : '',
    contextJson: JSON.stringify({
      profileKey: 'kuaishou_feifei',
      profileName: 'kuaishou-feifei 履约',
      skuCode: productName,
      skuName: productName,
      claimIdentity: expectedUid
        ? {
            expectedUid,
            submittedAt: now,
            source: 'dev_mock',
          }
        : {
            expectedUid: '',
            submittedAt: null,
            source: '',
          },
      kuaishouFeifei: {
        flowType: 'kuaishou_feifei',
        productCode,
        productName,
        platformOrderNo: orderNo,
        orderNo: `FF-${orderNo}`,
        rechargeStatus,
        rechargeStatusLabel,
        rechargeResultMessage: step === 'failed' ? '开发 mock 失败' : '',
        claimUrl: '',
        consumeStatus: step === 'completed' ? 'not_required' : 'pending',
        h5: {
          entryUrl: rawH5,
          rechargeUrl: rawH5,
        },
        lastSyncedAt: now,
        mock: {
          enabled: true,
          orderNo,
          createdAt: now,
        },
      },
    }),
    createdAt: now,
    updatedAt: now,
  })

  if (!task) {
    throw createHttpError('履约任务创建失败', {
      statusCode: 500,
      errorCode: 'dev_mock_task_failed',
    })
  }

  const claimToken = await createTaskClaimToken(task.id)
  await updateTask(task.id, {
    claim_token: claimToken.token,
    claim_expires_at: claimToken.expired_at,
    claimed_at: expectedUid ? now : null,
    redeemed_at: step === 'completed' ? now : null,
    updated_at: now,
  })

  return buildCreateResult({
    platform: 'feifei',
    orderId: order.id,
    orderNo,
    taskId: task.id,
    taskNo: task.task_no,
    claimToken: claimToken.token,
    claimUrl: buildClaimUrl(claimToken.token),
    frontendBaseUrl: input.frontendBaseUrl,
    expectedUid: expectedUid || '166909256',
    step,
    productName,
    tips: buildFeifeiTips(step, expectedUid || '166909256'),
  })
}

type AffiliateDashMockStep = 'uid' | 'bind' | 'submitted' | 'completed' | 'failed'

/**
 * 生成 affiliate-dash 领取 mock：不调用真实 affiliate-dash 平台。
 * 上下文带 mock 标记，sync/refresh/submit 全部短路，领取页可走完四步。
 */
export async function createAffiliateDashMockClaim(
  input: {
    step?: unknown
    orderNo?: unknown
    productName?: unknown
    productSku?: unknown
    uid?: unknown
    frontendBaseUrl?: unknown
  } = {},
): Promise<DevMockCreateResult> {
  assertDevMockEnabled()

  const step = normalizeAffiliateDashStep(input.step)
  const orderNo = String(input.orderNo || `MOCKAD${Date.now()}`).trim()
  const productName = String(input.productName || '幸运币90个').trim()
  const productSku = String(input.productSku || 'lucky_coin_x90').trim()
  const expectedUid = resolveMockUid(input.uid, step === 'uid' ? '' : '166909256')
  const fallbackUid = expectedUid || '166909256'
  const bindUrl =
    step === 'uid'
      ? ''
      : `https://skin.khhao.com/mock/bind?order=${encodeURIComponent(orderNo)}&uid=${encodeURIComponent(fallbackUid)}`
  const bound = step === 'submitted' || step === 'completed' || step === 'failed'
  const orderStatus =
    step === 'completed'
      ? 'delivered'
      : step === 'failed'
        ? 'ship_failed'
        : step === 'submitted'
          ? 'delivering'
          : 'paid'
  const now = nowIso()

  await assertOrderNoAvailable(orderNo)

  const profile = await ensureProfile('affiliate_dash', 'affiliate-dash 履约', true)
  const order = await createBaseOrder({
    orderNo,
    productNo: productSku,
    productName,
    now,
    platformTag: 'affiliate-dash',
  })
  const orderItem = await createBaseOrderItem({
    orderId: order.id,
    orderNo,
    productNo: productSku,
    productName,
    consumeShopId: '',
    deliveryItems: [],
    now,
    executor: 'affiliate_dash',
    productCode: productSku,
  })

  const task = await createTask({
    orderId: order.id,
    orderItemId: orderItem.id,
    unitIndex: 1,
    provider: OPEN_91_PROVIDER,
    platform: OPEN_91_PLATFORM,
    shopId: OPEN_91_PROVIDER,
    shopName: '91卡券',
    platformOrderId: orderNo,
    taskNo: randomId('DT'),
    profileId: profile.id,
    executorKey: 'affiliate_dash',
    taskStatus:
      step === 'completed'
        ? TASK_STATUS.REDEEMED
        : step === 'failed'
          ? TASK_STATUS.RETRY_PENDING
          : step === 'submitted'
            ? TASK_STATUS.REDEEMING
            : TASK_STATUS.LINK_GENERATED,
    deliveryStatus:
      step === 'completed' ? 'delivered' : step === 'submitted' ? 'delivering' : 'pending',
    resultCode:
      step === 'completed'
        ? 'affiliate_dash_delivered'
        : step === 'failed'
          ? 'affiliate_dash_ship_failed'
          : '',
    resultMessage:
      step === 'completed'
        ? 'affiliate-dash 履约成功'
        : step === 'failed'
          ? '开发 mock 模拟发货失败'
          : '等待用户领取',
    claimToken: '',
    claimExpiresAt: null,
    automationMode: 'manual',
    requiresClaim: true,
    userActionStatus: step === 'completed' ? 'not_required' : 'pending_claim',
    attemptCount: 0,
    lastError: step === 'failed' ? '开发 mock 模拟发货失败' : '',
    contextJson: JSON.stringify({
      profileKey: 'affiliate_dash',
      profileName: 'affiliate-dash 履约',
      skuCode: productName,
      skuName: productName,
      claimIdentity: expectedUid
        ? {
            expectedUid,
            submittedAt: now,
            source: 'dev_mock',
          }
        : {
            expectedUid: '',
            submittedAt: null,
            source: '',
          },
      affiliateDash: {
        flowType: 'affiliate_dash',
        sku: productSku,
        productName,
        orderNo: `AD-${orderNo}`,
        clientOrderNo: '',
        orderStatus,
        canShip: true,
        cannotShipReason: '',
        providerOrderNo: '',
        failureReason: step === 'failed' ? '开发 mock 模拟发货失败' : '',
        amount: 20,
        currency: 'POINT',
        bindUuid: bound ? `mock-bind-${orderNo}` : '',
        bindUrl,
        qrUrl: '',
        gameAccount: bound ? fallbackUid : '',
        expectedGameAccount: expectedUid || '',
        bindMismatch: false,
        bound,
        boundAccount: bound ? fallbackUid : '',
        gameChannel: 'Android',
        submitStatus:
          step === 'completed'
            ? 'delivered'
            : step === 'failed'
              ? 'ship_failed'
              : step === 'submitted'
                ? 'submitting'
                : '',
        consumeStatus: step === 'completed' ? 'not_required' : 'pending',
        lastSyncedAt: now,
        mock: {
          enabled: true,
          orderNo,
          createdAt: now,
        },
      },
    }),
    createdAt: now,
    updatedAt: now,
  })

  if (!task) {
    throw createHttpError('履约任务创建失败', {
      statusCode: 500,
      errorCode: 'dev_mock_task_failed',
    })
  }

  const claimToken = await createTaskClaimToken(task.id)
  await updateTask(task.id, {
    claim_token: claimToken.token,
    claim_expires_at: claimToken.expired_at,
    claimed_at: expectedUid ? now : null,
    redeemed_at: step === 'completed' ? now : null,
    updated_at: now,
  })

  return buildCreateResult({
    platform: 'affiliate_dash',
    orderId: order.id,
    orderNo,
    taskId: task.id,
    taskNo: task.task_no,
    claimToken: claimToken.token,
    claimUrl: buildClaimUrl(claimToken.token),
    frontendBaseUrl: input.frontendBaseUrl,
    expectedUid: fallbackUid,
    step,
    productName,
    tips: buildAffiliateDashTips(step, fallbackUid),
  })
}

/**
 * 生成电子凭证列表测试数据，不调用快手接口。
 * 覆盖未使用、已核销、已销毁和发码失败等运营页面常见状态。
 */
export async function createKuaishouIndustryVoucherMockData(
  input: {
    sellerId?: unknown
  } = {},
): Promise<DevMockKuaishouIndustryVoucherResult> {
  assertDevMockEnabled()

  const now = nowIso()
  const timestamp = Date.now()
  const sellerId = resolveMockIndustrySellerId(input.sellerId)
  const specimens = [
    { status: 'UNUSED', callbackStatus: 'success', productName: '周卡 VIP 尊享礼包' },
    {
      status: 'UNUSED',
      callbackStatus: 'failed',
      callbackError: '开发 Mock 模拟发码回调失败',
      productName: '幸运盲盒 限定款',
    },
    {
      status: 'CONSUMED',
      callbackStatus: 'success',
      consumeSerialNum: `CONSUME-MOCK-${timestamp}-3`,
      consumedAt: now,
      productName: '星轨通行证月卡',
    },
    { status: 'UNUSED', callbackStatus: 'success', productName: '精英荣耀专属礼盒' },
    {
      status: 'DESTROYED',
      callbackStatus: 'success',
      destroyedAt: now,
      productName: '退款销毁测试券',
    },
    {
      status: 'CONSUMED',
      callbackStatus: 'success',
      consumeSerialNum: `CONSUME-MOCK-${timestamp}-6`,
      consumedAt: now,
      productName: '浪漫天命皮肤礼包',
    },
  ]

  const vouchers: DevMockKuaishouIndustryVoucherResult['vouchers'] = []
  for (const [index, specimen] of specimens.entries()) {
    const oid = `MOCK-KS-${timestamp}-${index + 1}`
    const voucher = await upsertKuaishouIndustryVoucher({
      oid,
      unitIndex: 1,
      sellerId,
      token: `mock-token-${timestamp}-${index + 1}`,
      eticketType: 'GAME_OPEN_TICKET_CONSUME',
      status: specimen.status,
      validStartTime: timestamp - 60 * 60 * 1000,
      validEndTime: timestamp + 7 * 24 * 60 * 60 * 1000,
      consumeSerialNum: specimen.consumeSerialNum || '',
      consumedAt: specimen.consumedAt || null,
      destroyedAt: specimen.destroyedAt || null,
      sendCallbackStatus: specimen.callbackStatus,
      sendCallbackAttemptCount: specimen.callbackStatus === 'failed' ? 1 : 0,
      sendCallbackLastError: specimen.callbackError || '',
      sendCallbackResponseJson: {
        mock: true,
        success: specimen.callbackStatus === 'success',
      },
      sendCallbackSentAt: now,
      rawPayloadJson: {
        source: 'dev_mock',
        mock: true,
        productName: specimen.productName,
      },
      createdAt: now,
      updatedAt: now,
    })

    if (!voucher) {
      throw createHttpError('电子凭证 Mock 创建失败', {
        statusCode: 500,
        errorCode: 'dev_mock_kuaishou_industry_voucher_failed',
      })
    }

    vouchers.push({
      voucherCode: voucher.voucher_code,
      oid: voucher.oid,
      status: voucher.status,
    })
  }

  return {
    createdCount: vouchers.length,
    sellerId,
    vouchers,
  }
}

/**
 * 生成 91 查询请求体（带签名），可选对本机发起查询。
 */
export async function buildOpen91QueryMock(
  input: {
    orderNo?: unknown
    execute?: unknown
    baseUrl?: unknown
  } = {},
) {
  assertDevMockEnabled()

  const orderNo = String(input.orderNo || '').trim()
  if (!orderNo) {
    throw createHttpError('请填写 orderNo', {
      statusCode: 400,
      errorCode: 'dev_mock_order_no_required',
    })
  }

  const config = assertOpen91Config()
  const timestamp = Math.floor(Date.now() / 1000)
  const payload = {
    orderNo,
    timestamp,
    version: config.version || '1.0',
  }
  const sign = signOpen91Payload(payload, config.secret)
  const body = { ...payload, sign }
  const port = String(process.env.PORT || process.env.BACKEND_PORT || '3000').trim() || '3000'
  const defaultBase = `http://127.0.0.1:${port}`
  const baseUrl = String(input.baseUrl || defaultBase)
    .replace(/\/#\/claim\/?$/, '')
    .replace(/\/$/, '')
  const endpoint = `${baseUrl || defaultBase}/api/v1/open/91/orders/query`

  let response: unknown = null
  if (input.execute === true || input.execute === 'true' || input.execute === 1) {
    try {
      const res = await fetch(endpoint, {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify(body),
      })
      const text = await res.text()
      try {
        response = { status: res.status, body: JSON.parse(text) }
      } catch {
        response = { status: res.status, body: text }
      }
    } catch (error) {
      response = {
        status: 0,
        error: error instanceof Error ? error.message : String(error),
        tip: '本机请求失败时，可复制 requestBody 用 curl 手动打到 backend',
      }
    }
  }

  return {
    endpoint,
    requestBody: body,
    curl: `curl -sS -X POST '${endpoint}' -H 'content-type: application/json' -d '${JSON.stringify(body)}'`,
    response,
  }
}

// --- helpers ---

async function assertOrderNoAvailable(orderNo: string) {
  const existing = await findOrderByPlatformOrderId({
    provider: OPEN_91_PROVIDER,
    platform: OPEN_91_PLATFORM,
    shopId: OPEN_91_PROVIDER,
    platformOrderId: orderNo,
  })
  if (existing) {
    throw createHttpError(`订单号已存在：${orderNo}，请换一个或留空自动生成`, {
      statusCode: 409,
      errorCode: 'dev_mock_order_exists',
    })
  }
}

async function ensureProfile(profileKey: string, name: string, requiresClaim: boolean) {
  const existing = await getFulfillmentProfileByKey(profileKey)
  if (existing) {
    return existing
  }

  const now = nowIso()
  const profile = await upsertFulfillmentProfile({
    profileKey,
    name,
    executorKey: profileKey,
    requiresClaim,
    autoDispatch: false,
    inventoryStrategy: 'external_platform',
    configJson: '{}',
    createdAt: now,
    updatedAt: now,
  })

  if (!profile) {
    throw createHttpError('履约配置创建失败', {
      statusCode: 500,
      errorCode: 'dev_mock_profile_failed',
    })
  }
  return profile
}

async function createBaseOrder(input: {
  orderNo: string
  productNo: string
  productName: string
  now: string
  platformTag: string
}) {
  const order = await createOrder({
    provider: OPEN_91_PROVIDER,
    platform: OPEN_91_PLATFORM,
    shopId: OPEN_91_PROVIDER,
    shopName: '91卡券',
    platformOrderId: input.orderNo,
    orderStatus: 'paid',
    payStatus: 'paid',
    buyerId: 'mock-buyer',
    buyerName: 'mock 领取客户',
    receiverContact: '',
    totalAmount: 100,
    currency: 'CNY',
    rawPayloadJson: JSON.stringify({
      source: OPEN_91_PROVIDER,
      mock: true,
      platformTag: input.platformTag,
      receivedAt: input.now,
      body: {
        orderNo: input.orderNo,
        productNo: input.productNo,
        productName: input.productName,
        buyNum: 1,
        maxAmount: '1.00',
      },
    }),
    paidAt: input.now,
    createdAt: input.now,
    updatedAt: input.now,
  })

  if (!order) {
    throw createHttpError('订单创建失败', { statusCode: 500, errorCode: 'dev_mock_order_failed' })
  }
  return order
}

async function createBaseOrderItem(input: {
  orderId: number
  orderNo: string
  productNo: string
  productName: string
  consumeShopId: string
  deliveryItems: DeliveryItem[]
  now: string
  executor: 'lewan' | 'feifei' | 'affiliate_dash'
  productCode?: string
}) {
  const snapshot =
    input.executor === 'feifei'
      ? {
          source: OPEN_91_PROVIDER,
          orderNo: input.orderNo,
          productNo: input.productNo,
          productName: input.productName,
          kuaishouFeifei: {
            productCode: input.productCode || '',
            productName: input.productName,
            matchMode: 'mock',
          },
        }
      : input.executor === 'affiliate_dash'
        ? {
            source: OPEN_91_PROVIDER,
            orderNo: input.orderNo,
            productNo: input.productNo,
            productName: input.productName,
            affiliateDash: {
              sku: input.productCode || input.productNo,
              productName: input.productName,
              matchMode: 'mock',
            },
          }
        : {
            source: OPEN_91_PROVIDER,
            orderNo: input.orderNo,
            productNo: input.productNo,
            productName: input.productName,
            shopId: input.consumeShopId,
            cloudtentacles: {
              matchMode: 'mock',
              normalizedProductName: input.productName,
              cloudSourceKeys: ['mock-cloudtentacles'],
              resolvedSourceKey: 'mock-cloudtentacles',
              deliveryItems: input.deliveryItems,
            },
          }

  const [orderItem] = await replaceOrderItems(input.orderId, [
    {
      skuCode: input.productName,
      skuName: input.productName,
      quantity: 1,
      specJson: JSON.stringify({
        source: OPEN_91_PROVIDER,
        orderNo: input.orderNo,
        productNo: input.productNo,
        productName: input.productName,
      }),
      itemSnapshotJson: JSON.stringify(snapshot),
      createdAt: input.now,
      updatedAt: input.now,
    },
  ])

  if (!orderItem) {
    throw createHttpError('订单商品创建失败', {
      statusCode: 500,
      errorCode: 'dev_mock_item_failed',
    })
  }
  return orderItem
}

function buildLewanMockContext(input: {
  step: LewanMockStep
  orderNo: string
  productName: string
  productNo: string
  consumeShopId: string
  deliveryItems: DeliveryItem[]
  expectedUid: string
  timestamp: string
}) {
  const roleReady = ['binding', 'confirm', 'result'].includes(input.step)
  const completed = input.step === 'result'
  const boundUid = roleReady ? input.expectedUid || '10001' : ''
  const primaryItem = input.deliveryItems[0] || {
    cloudSkuId: 910001,
    cloudSkuName: 'Mock 商品',
    quantity: 1,
  }

  return {
    profileKey: 'kuaishou_ct_assisted',
    profileName: 'kuaishou-lewan 履约',
    skuCode: input.productName,
    skuName: input.productName,
    claimIdentity: input.expectedUid
      ? {
          expectedUid: input.expectedUid,
          submittedAt: input.timestamp,
          source: 'dev_mock',
        }
      : {
          expectedUid: '',
          submittedAt: null,
          source: '',
        },
    kuaishouCloudFulfillment: {
      flowType: 'kuaishou_cloud_fulfillment',
      configId: `mock:${input.productName}`,
      internalSkuCode: input.productName,
      internalSkuName: input.productName,
      deliveryItems: input.deliveryItems.length ? input.deliveryItems : [primaryItem],
      mock: {
        enabled: true,
        orderNo: input.orderNo,
        productNo: input.productNo,
        createdAt: input.timestamp,
      },
      ticket: {
        code: roleReady ? `MOCK-${input.orderNo}` : '',
        status: roleReady ? 'verified' : 'pending',
        capturedAt: roleReady ? input.timestamp : null,
        capturedBy: roleReady ? { source: 'dev_mock' } : null,
        verifiedAt: roleReady ? input.timestamp : null,
        oid: roleReady ? `MOCK-OID-${input.orderNo}` : '',
        formToken: roleReady ? `MOCK-FORM-${input.orderNo}` : '',
        leftCount: roleReady ? 1 : 0,
        goodsTitle: roleReady ? input.productName : '',
      },
      binding: {
        prepareStatus: roleReady ? 'ready' : 'pending',
        cloudSourceKeys: ['mock-cloudtentacles'],
        resolvedSourceKey: 'mock-cloudtentacles',
        skuId: primaryItem.cloudSkuId,
        skuName: primaryItem.cloudSkuName,
        vnKey: '1',
        vnId: roleReady ? 900001 : 0,
        vnPhone: roleReady ? '13800000000' : '',
        bindUrl: roleReady ? `https://example.com/mock-kuaishou-cloud-bind/${input.orderNo}` : '',
        bindPreparedAt: roleReady ? input.timestamp : null,
        bindExpiresAt: roleReady ? addHours(input.timestamp, 24) : null,
        bindProbeAt: roleReady ? input.timestamp : null,
        bindProbeStatus: roleReady ? 'success' : '',
        bindProbeMessage: '',
        roleName: roleReady ? '测试角色' : '',
        roleId: boundUid,
      },
      role: {
        status: roleReady ? 'ready' : 'pending',
        name: roleReady ? '测试角色' : '',
        rid: boundUid,
        refreshedAt: roleReady ? input.timestamp : null,
        errorMessage: '',
        rawInfo: roleReady ? { mock: true } : null,
        defaultName: roleReady ? '默认机位角色' : '',
        defaultRid: roleReady ? 'DEFAULT-000' : '',
        defaultCapturedAt: roleReady ? input.timestamp : null,
        defaultCaptureStatus: roleReady ? 'captured' : '',
        defaultErrorMessage: '',
        isDefaultRole: false,
      },
      purchase: {
        autoBuyEnabled: true,
        minAssetReserve: 0,
        usedKnapsack: false,
        purchaseTriggered: false,
        assetBefore: 0,
        assetAfter: 0,
        purchaseAt: null,
        items: [],
      },
      dispatch: {
        status: completed ? 'success' : 'pending',
        dispatchAt: completed ? input.timestamp : null,
        dispatchBy: completed ? { source: 'dev_mock' } : null,
        sendType: 0,
        note: completed ? '开发 mock 已模拟发货成功' : '',
        items: completed ? input.deliveryItems : [],
      },
      returnNumber: {
        status: completed ? 'success' : 'pending',
        returnedAt: completed ? input.timestamp : null,
        returnedBy: completed ? { source: 'dev_mock' } : null,
        autoReturnEnabled: true,
      },
      consume: {
        status: completed ? 'success' : 'pending',
        shopId: input.consumeShopId,
        shopName: '',
        autoConsumeEnabled: true,
        consumedAt: completed ? input.timestamp : null,
        errorMessage: '',
      },
    },
  }
}

function resolveLewanTaskStatus(step: LewanMockStep) {
  if (step === 'result') return TASK_STATUS.COMPLETED
  if (step === 'confirm') return TASK_STATUS.ROLE_CONFIRMED
  if (step === 'binding') return TASK_STATUS.WAITING_BINDING
  return TASK_STATUS.LINK_GENERATED
}

function normalizeLewanStep(value: unknown): LewanMockStep {
  const step = String(value || 'uid').trim()
  if (['uid', 'binding', 'confirm', 'result'].includes(step)) {
    return step as LewanMockStep
  }
  // 兼容旧 ticket 命名
  if (step === 'ticket') return 'uid'
  return 'uid'
}

function normalizeFeifeiStep(value: unknown): FeifeiMockStep {
  const step = String(value || 'uid').trim()
  if (['uid', 'ready', 'completed', 'failed'].includes(step)) {
    return step as FeifeiMockStep
  }
  return 'uid'
}

function normalizeAffiliateDashStep(value: unknown): AffiliateDashMockStep {
  const step = String(value || 'uid').trim()
  if (['uid', 'bind', 'submitted', 'completed', 'failed'].includes(step)) {
    return step as AffiliateDashMockStep
  }
  return 'uid'
}

function resolveMockUid(value: unknown, fallback: string) {
  const raw = String(value ?? '').trim()
  if (!raw) {
    return normalizeClaimUid(fallback)
  }
  return assertValidClaimUid(raw)
}

function resolveMockIndustrySellerId(value: unknown): string {
  const sellerId = String(value || '').trim()
  if (sellerId) {
    return sellerId
  }

  const shop = listKuaishouIndustryShopConfigs(getKuaishouIndustrySourceConfig()).find(
    (item) => item.enabled !== false && (item.sellerId || item.shopId),
  )
  return String(shop?.sellerId || shop?.shopId || '141242642').trim()
}

function parseDeliveryItems(value: unknown): DeliveryItem[] {
  if (!value) {
    return [
      {
        cloudSkuId: 910001,
        cloudSkuName: 'Mock 商品',
        quantity: 1,
      },
    ]
  }

  if (typeof value === 'string') {
    try {
      return parseDeliveryItems(JSON.parse(value))
    } catch {
      return parseDeliveryItems(null)
    }
  }

  if (!Array.isArray(value)) {
    return parseDeliveryItems(null)
  }

  const items = value
    .map((item) => {
      const source = item && typeof item === 'object' ? (item as Record<string, unknown>) : {}
      const cloudSkuId = Number(source.cloudSkuId || source.skuId || 0) || 0
      const quantity = Number(source.quantity || 1) || 1
      if (!cloudSkuId) return null
      return {
        cloudSkuId,
        cloudSkuName: String(source.cloudSkuName || source.skuName || 'Mock 商品').trim(),
        quantity: quantity > 0 ? quantity : 1,
      }
    })
    .filter((item): item is DeliveryItem => Boolean(item))

  return items.length > 0 ? items : parseDeliveryItems(null)
}

function buildCreateResult(input: {
  platform: 'lewan' | 'feifei' | 'affiliate_dash'
  orderId: number
  orderNo: string
  taskId: number
  taskNo: string
  claimToken: string
  claimUrl: string
  frontendBaseUrl?: unknown
  expectedUid: string
  step: string
  productName: string
  tips: string[]
}): DevMockCreateResult {
  return {
    platform: input.platform,
    orderId: input.orderId,
    orderNo: input.orderNo,
    taskId: input.taskId,
    taskNo: input.taskNo,
    claimToken: input.claimToken,
    claimUrl: input.claimUrl,
    frontendClaimUrl: buildFrontendClaimUrl(input.claimToken, input.frontendBaseUrl),
    expectedUid: input.expectedUid,
    step: input.step,
    productName: input.productName,
    tips: input.tips,
    open91QueryHint: `可在 Mock 页「91 查单」使用 orderNo=${input.orderNo}，或 CLI：npm run mock:open91 -- --mode=query --orderNo=${input.orderNo}`,
  }
}

function buildFrontendClaimUrl(token: string, frontendBaseUrl?: unknown) {
  const base = String(frontendBaseUrl || '').trim()
  if (base) {
    return `${base.replace(/\/+$/, '')}/#/claim/${token}`
  }
  return `http://127.0.0.1/#/claim/${token}`
}

function buildLewanTips(step: LewanMockStep, uid: string) {
  if (step === 'uid') {
    return [
      `打开领取链接后，Step1 填写 UID：${uid}`,
      '提交后进入绑定步；mock 绑定链接仅作展示，点击刷新/确认前请保证 UID 与角色 ID 一致',
    ]
  }
  if (step === 'binding') {
    return [
      `已预填 UID=${uid} 且角色 ID 已匹配`,
      '可直接点「UID 已匹配，下一步」→ 确认兑换（mock 不会真实发货）',
    ]
  }
  if (step === 'confirm') {
    return ['已进入确认兑换步，点击确认兑换即可模拟成功']
  }
  return ['已模拟兑换完成，可直接看结果页']
}

function buildFeifeiTips(step: FeifeiMockStep, uid: string) {
  if (step === 'uid') {
    return [`打开领取链接，Step1 填 UID：${uid}`, '提交后点「打开领取链接」，URL 应带 uid 参数']
  }
  if (step === 'ready') {
    return [`已预填 UID=${uid}，可直接打开带 uid 的 H5（mock 链接，无需真实平台）`]
  }
  if (step === 'failed') {
    return ['已模拟 feifei 失败态，用于看领取页结果展示']
  }
  return ['已模拟 feifei 成功完成态']
}

function buildAffiliateDashTips(step: AffiliateDashMockStep, uid: string) {
  if (step === 'uid') {
    return [`打开领取链接，Step1 填 UID：${uid}（或自定义）`, '提交后进入绑定步，mock 会给出二维码']
  }
  if (step === 'bind') {
    return [
      `已预填 UID=${uid}，绑定二维码为 mock 生成（扫描无效）`,
      '正常流程：扫码完成真实绑定后自动进入下一步',
    ]
  }
  if (step === 'submitted') {
    return ['已模拟绑定成功，可点「提交发货」（mock 直接模拟发货成功）']
  }
  if (step === 'failed') {
    return ['已模拟发货失败态，用于看领取页结果展示']
  }
  return ['已模拟 affiliate-dash 发货完成态']
}

function signOpen91Payload(payload: Record<string, unknown>, secret: string) {
  const queryString = Object.entries(payload)
    .filter(([key]) => key !== 'sign')
    .sort(([left], [right]) => left.localeCompare(right))
    .map(([key, value]) => `${key}=${value == null ? '' : String(value)}`)
    .join('&')
  return crypto
    .createHash('md5')
    .update(`${secret}${queryString}${secret}`, 'utf8')
    .digest('hex')
    .toUpperCase()
}
