import { buildClaimUrl } from '../claim-service.js'
import { createHttpError } from '../../../utils/http.js'
import { maskCode as maskCodeValue } from '../../../utils/masking.js'
import { formatFenToAmount, normalizeFen } from '../../../utils/money.js'
import {
  parseTaskContext as parseTaskContextValue,
  parseTaskState as parseTaskStateValue,
} from '../../../utils/task-json.js'

export const CLAIM_TERMINAL_STATUSES = new Set(['expired', 'closed'])
export const REDEEM_REPLACEMENT_LIMIT = 10
export const KUAISHOU_CLOUD_CLAIM_GUIDE_BASE_PATH = '/kuaishou-cloud-guide'

export function buildClaimDetailPayload({ claimToken, task, order, orderItem, session }) {
  const screenshotReady = Boolean(task.screenshot_path) || Boolean(session?.artifacts?.hasScreenshot)
  const screenshotUrl = screenshotReady ? `/api/v1/claim/${claimToken.token}/screenshot` : ''
  const finalRedeem = session?.redeem?.final?.redeem || null
  const kuaishouCloudFulfillment = mapClaimKuaishouCloudFulfillment(task, order)

  return {
    tokenStatus: claimToken.status,
    claimUrl: buildClaimUrl(claimToken.token),
    flowType: kuaishouCloudFulfillment ? 'kuaishou_cloud' : 'tencent_claim',
    task: {
      taskId: task.id,
      taskNo: task.task_no,
      status: task.task_status,
      executorKey: task.executor_key || '',
      requiresSupportReview: isAssistedClaimTask(task),
      expiresAt: claimToken.expired_at,
      claimedAt: task.claimed_at,
      roleConfirmedAt: task.role_confirmed_at,
      redeemedAt: task.redeemed_at,
      loginType: task.login_type,
      lastError: task.last_error,
      browserSessionId: task.browser_session_id,
    },
    order: {
      orderId: order.id,
      platform: order.platform,
      platformOrderId: order.platform_order_id,
      payStatus: order.pay_status,
      orderStatus: order.order_status,
      totalAmount: formatFenToAmount(order.total_amount),
      totalAmountFen: normalizeFen(order.total_amount),
      currency: order.currency,
    },
    orderItem: {
      orderItemId: orderItem.id,
      skuCode: orderItem.sku_code,
      skuName: orderItem.sku_name,
      quantity: orderItem.quantity,
    },
    session,
    kuaishouCloudFulfillment,
    result: task.redeemed_at || session?.status === 'redeemed'
      ? {
        resultCode: String(task.result_code || finalRedeem?.iRet || finalRedeem?.ret || ''),
        resultMessage: String(task.result_message || finalRedeem?.sMsg || finalRedeem?.msg || session?.notice || ''),
        screenshotReady,
        screenshotUrl,
      }
      : null,
  }
}

export function mapClaimKuaishouCloudFulfillment(task, order) {
  if (String(task?.executor_key || '').trim() !== 'kuaishou_ct_assisted') {
    return null
  }

  const source = parseTaskContext(task).kuaishouCloudFulfillment
  if (!source || typeof source !== 'object') {
    return null
  }

  const binding = source.binding && typeof source.binding === 'object' ? source.binding : {}
  const role = source.role && typeof source.role === 'object' ? source.role : {}
  const purchase = source.purchase && typeof source.purchase === 'object' ? source.purchase : {}
  const ticket = source.ticket && typeof source.ticket === 'object' ? source.ticket : {}
  const dispatch = source.dispatch && typeof source.dispatch === 'object' ? source.dispatch : {}
  const returnNumber = source.returnNumber && typeof source.returnNumber === 'object' ? source.returnNumber : {}
  const consume = source.consume && typeof source.consume === 'object' ? source.consume : {}

  return {
    flowType: 'kuaishou_cloud',
    shopId: String(order?.shop_id || '').trim(),
    shopName: String(order?.shop_name || '').trim(),
    guideImages: [
      `${KUAISHOU_CLOUD_CLAIM_GUIDE_BASE_PATH}/1.png`,
      `${KUAISHOU_CLOUD_CLAIM_GUIDE_BASE_PATH}/2.png`,
      `${KUAISHOU_CLOUD_CLAIM_GUIDE_BASE_PATH}/3.png`,
    ],
    ticket: {
      code: String(ticket.code || '').trim(),
      status: String(ticket.status || 'pending').trim() || 'pending',
      capturedAt: ticket.capturedAt || null,
      verifiedAt: ticket.verifiedAt || null,
      goodsTitle: String(ticket.goodsTitle || '').trim(),
      leftCount: Number(ticket.leftCount || 0) || 0,
    },
    binding: {
      prepareStatus: String(binding.prepareStatus || 'pending').trim() || 'pending',
      cloudSourceKey: String(binding.cloudSourceKey || '').trim(),
      skuId: Number(binding.skuId || 0) || 0,
      skuName: String(binding.skuName || '').trim(),
      vnKey: String(binding.vnKey || '').trim(),
      vnId: Number(binding.vnId || 0) || 0,
      bindUrl: String(binding.bindUrl || '').trim(),
      bindPreparedAt: binding.bindPreparedAt || null,
      bindExpiresAt: binding.bindExpiresAt || null,
      bindProbeAt: binding.bindProbeAt || null,
      bindProbeStatus: String(binding.bindProbeStatus || '').trim(),
      bindProbeMessage: String(binding.bindProbeMessage || '').trim(),
      vnPhone: String(binding.vnPhone || '').trim(),
      roleName: String(binding.roleName || '').trim(),
      roleId: String(binding.roleId || '').trim(),
    },
    role: {
      status: String(role.status || 'pending').trim() || 'pending',
      name: String(role.name || binding.roleName || '').trim(),
      rid: String(role.rid || binding.roleId || '').trim(),
      refreshedAt: role.refreshedAt || null,
      errorMessage: String(role.errorMessage || '').trim(),
    },
    purchase: {
      autoBuyEnabled: purchase.autoBuyEnabled !== false,
      minAssetReserve: Number(purchase.minAssetReserve || 0) || 0,
      usedKnapsack: purchase.usedKnapsack === true,
      purchaseTriggered: purchase.purchaseTriggered === true,
      assetBefore: Number(purchase.assetBefore || 0) || 0,
      assetAfter: Number(purchase.assetAfter || 0) || 0,
      purchaseAt: purchase.purchaseAt || null,
    },
    dispatch: {
      status: String(dispatch.status || 'pending').trim() || 'pending',
      dispatchAt: dispatch.dispatchAt || null,
      note: String(dispatch.note || '').trim(),
    },
    returnNumber: {
      status: String(returnNumber.status || 'pending').trim() || 'pending',
      returnedAt: returnNumber.returnedAt || null,
    },
    consume: {
      status: String(consume.status || 'pending').trim() || 'pending',
      shopId: String(consume.shopId || '').trim(),
      shopName: String(consume.shopName || '').trim(),
      consumedAt: consume.consumedAt || null,
      errorMessage: String(consume.errorMessage || '').trim(),
    },
  }
}

export function assertTaskCanProceed(task) {
  if (CLAIM_TERMINAL_STATUSES.has(String(task.task_status || ''))) {
    throw createHttpError('当前任务已经结束，不能继续操作', {
      statusCode: 410,
      errorCode: 'claim_task_closed',
    })
  }
}

export function assertPublicClaimActionAllowed(task, action) {
  if (!isAssistedClaimTask(task)) {
    return
  }

  const message = action === 'confirm'
    ? '当前商品需要客服复核角色，请登录后联系人工继续'
    : '当前商品需要客服确认后再执行兑换，请联系人工继续'

  throw createHttpError(message, {
    statusCode: 409,
    errorCode: 'claim_support_review_required',
  })
}

export function mergeTaskContext(task, patch = {}) {
  return {
    ...parseTaskContext(task),
    ...patch,
  }
}

export function parseTaskState(task) {
  return parseTaskStateValue(task)
}

export function isAssistedClaimTask(task) {
  return String(task?.executor_key || '').trim() === 'tencent_claim_assisted'
}

export function parseTaskContext(task) {
  return parseTaskContextValue(task)
}

export function normalizeClaimLoginType(loginType) {
  return String(loginType || '').trim() === 'wx' ? 'wx' : 'qq'
}

export function isRecoverableSessionError(error) {
  const errorCode = String(error?.errorCode || error?.code || '').trim()
  return errorCode === 'session_not_found' || errorCode === 'session_closed'
}

export function maskCode(value) {
  return maskCodeValue(value, { shortMask: '****' })
}
