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

import { PROJECT_ROOT } from '../../config/runtime.js'
import { createTaskEvent } from '../../repositories/task-event-repo.js'
import { updateTask } from '../../repositories/task-repo.js'
import { createHttpError } from '../../utils/http.js'
import { nowIso } from '../../utils/time.js'
import {
  getKuaishouEticketSourceConfig,
  resolveKuaishouEticketShopConfig,
} from '../platforms/kuaishou-eticket/source-config-service.js'
import { queryKuaishouEticketConsumeDetail } from '../platforms/kuaishou-eticket/consume-service.js'
import {
  dispatchKuaishouCloudFulfillmentTask,
  maskCode,
  normalizeKuaishouCloudFlow,
  prepareKuaishouCloudFulfillmentTask,
  refreshKuaishouCloudTaskRoleInfo,
} from '../fulfillment/kuaishou-cloud-task-service.js'
import { getClaimContext, getClaimDetail } from './claim-session-service.js'

const KUAISHOU_CLOUD_GUIDE_DIR = path.resolve(PROJECT_ROOT, '../../tems/imgs')
const ALLOWED_GUIDE_FILES = new Set(['1.png', '2.png', '3.png'])

type JsonObject = Record<string, any>

export async function verifyKuaishouCloudClaimTicket(token: unknown, payload: JsonObject = {}) {
  const context = await getClaimContext(token)
  const now = nowIso()

  if (String(context.task.executor_key || '').trim() !== 'kuaishou_ct_assisted') {
    throw createHttpError('当前领取链接不是快手 Cloud 客户领取流程', {
      statusCode: 409,
      errorCode: 'claim_not_kuaishou_cloud',
    })
  }

  const flow = normalizeKuaishouCloudFlow(parseTaskContext(context.task).kuaishouCloudFulfillment)

  const ticketCode = String(payload.ticketCode || payload.eTicketId || '').trim()
  if (!ticketCode) {
    throw createHttpError('请先粘贴快手小店核销码', {
      statusCode: 400,
      errorCode: 'claim_kuaishou_cloud_missing_ticket_code',
    })
  }

  const shopId = String(flow.consume.shopId || context.order.shop_id || '').trim()
  const shopConfig = resolveKuaishouEticketShopConfig({
    shopId,
    shopName: String(context.order.shop_name || '').trim(),
  })
  if (!shopConfig || shopConfig.enabled === false || !String(shopConfig.cookie || '').trim()) {
    throw createHttpError('这笔订单对应的快手小店还没有配置可用 Cookie，请联系客服处理', {
      statusCode: 409,
      errorCode: 'claim_kuaishou_cloud_shop_cookie_missing',
    })
  }

  const eticketSource = getKuaishouEticketSourceConfig()
  const detailResult = await queryKuaishouEticketConsumeDetail({
    baseUrl: eticketSource.baseUrl,
    cookie: shopConfig.cookie,
    eTicketId: ticketCode,
  })

  if (!detailResult.ok || detailResult.alreadyConsumed || !detailResult.detail) {
    throw createHttpError(detailResult.errorMessage || '核销码校验失败，请确认是否复制完整', {
      statusCode: 409,
      errorCode: detailResult.alreadyConsumed
        ? 'claim_kuaishou_cloud_ticket_already_consumed'
        : 'claim_kuaishou_cloud_ticket_invalid',
    })
  }

  const nextContext = {
    ...parseTaskContext(context.task),
    kuaishouCloudFulfillment: {
      ...flow,
      ticket: {
        ...flow.ticket,
        code: detailResult.eTicketId || ticketCode,
        status: 'verified',
        capturedAt: flow.ticket.capturedAt || now,
        capturedBy: flow.ticket.capturedBy || {
          source: 'claim_page',
        },
        verifiedAt: now,
        oid: String(detailResult.detail.oid || '').trim(),
        formToken: String(detailResult.detail.formToken || '').trim(),
        leftCount: Number(detailResult.detail.leftCount || 0) || 0,
        goodsTitle: String(detailResult.goods?.itemTitle || '').trim(),
      },
      consume: {
        ...flow.consume,
        shopId,
      },
    },
  }

  const preparedFlow = normalizeKuaishouCloudFlow(nextContext.kuaishouCloudFulfillment)
  if (preparedFlow.binding.prepareStatus !== 'ready' || !preparedFlow.binding.bindUrl) {
    await prepareKuaishouCloudFulfillmentTask({
      ...context.task,
      context_json: JSON.stringify(nextContext),
    }, {
      source: 'claim_page_ticket_verified',
      actor: { source: 'claim_page' },
    })
  } else {
    await updateTask(context.task.id, {
      claim_token: context.claimToken.token,
      claim_expires_at: context.claimToken.expired_at,
      context_json: JSON.stringify(nextContext),
      last_error: '',
      updated_at: now,
    })
  }

  if (!context.task.claimed_at) {
    await updateTask(context.task.id, {
      claimed_at: now,
      updated_at: now,
    })
  }

  await createTaskEvent(context.task.id, 'kuaishou_cloud_ticket_verified', {
    ticketCodeMasked: maskCode(detailResult.eTicketId || ticketCode),
    shopId,
    shopName: String(context.order.shop_name || '').trim(),
    goodsTitle: String(detailResult.goods?.itemTitle || '').trim(),
  }, now)

  return getClaimDetail(token, { includeQrImage: false })
}

export async function getKuaishouCloudClaimGuideAssetPath(filename) {
  const normalized = String(filename || '').trim()
  if (!ALLOWED_GUIDE_FILES.has(normalized)) {
    throw createHttpError('指引图片不存在', {
      statusCode: 404,
      errorCode: 'claim_kuaishou_cloud_asset_not_found',
    })
  }

  const filePath = path.resolve(KUAISHOU_CLOUD_GUIDE_DIR, normalized)
  if (!filePath.startsWith(KUAISHOU_CLOUD_GUIDE_DIR) || !fs.existsSync(filePath)) {
    throw createHttpError('指引图片不存在', {
      statusCode: 404,
      errorCode: 'claim_kuaishou_cloud_asset_not_found',
    })
  }

  return filePath
}

function parseTaskContext(task) {
  const rawValue = task?.context_json
  if (!rawValue) {
    return {}
  }

  if (typeof rawValue === 'object') {
    return rawValue
  }

  try {
    return JSON.parse(String(rawValue || '{}'))
  } catch {
    return {}
  }
}

export async function confirmKuaishouCloudClaimRole(token) {
  const context = await getClaimContext(token)
  const now = nowIso()

  if (String(context.task.executor_key || '').trim() !== 'kuaishou_ct_assisted') {
    throw createHttpError('当前领取链接不是快手 Cloud 客户领取流程', {
      statusCode: 409,
      errorCode: 'claim_not_kuaishou_cloud',
    })
  }

  if (['role_confirmed', 'dispatched_pending_return', 'completed'].includes(String(context.task.task_status || '').trim())) {
    return getClaimDetail(token, { includeQrImage: false })
  }

  const refreshed = await refreshKuaishouCloudTaskRoleInfo(context.task, {
    source: 'claim_page_role_confirm',
    actor: { source: 'claim_page' },
    recordEvent: false,
    forceProbe: true,
  })
  const flow = normalizeKuaishouCloudFlow(parseTaskContext(refreshed.task).kuaishouCloudFulfillment)

  if (flow.ticket.status !== 'verified') {
    throw createHttpError('请先验证核销码', {
      statusCode: 409,
      errorCode: 'claim_kuaishou_cloud_ticket_not_verified',
    })
  }

  if (!flow.binding.vnPhone || !flow.binding.roleName || !flow.binding.roleId) {
    throw createHttpError('角色信息还未刷新到系统，请完成绑定后稍等片刻再试', {
      statusCode: 409,
      errorCode: 'claim_kuaishou_cloud_role_not_ready',
    })
  }

  await updateTask(context.task.id, {
    task_status: 'role_confirmed',
    role_id: flow.binding.roleId,
    role_name: flow.binding.roleName,
    user_action_status: 'role_confirmed',
    role_confirmed_at: now,
    last_error: '',
    updated_at: now,
  })

  await createTaskEvent(context.task.id, 'kuaishou_cloud_role_confirmed', {
    vnPhone: flow.binding.vnPhone,
    roleName: flow.binding.roleName,
    roleId: flow.binding.roleId,
  }, now)

  return getClaimDetail(token, { includeQrImage: false })
}

export async function redeemKuaishouCloudClaim(token) {
  const context = await getClaimContext(token)
  const now = nowIso()

  if (String(context.task.executor_key || '').trim() !== 'kuaishou_ct_assisted') {
    throw createHttpError('当前领取链接不是快手 Cloud 客户领取流程', {
      statusCode: 409,
      errorCode: 'claim_not_kuaishou_cloud',
    })
  }

  if (context.task.task_status !== 'role_confirmed') {
    throw createHttpError('请先确认角色信息', {
      statusCode: 409,
      errorCode: 'claim_kuaishou_cloud_role_not_confirmed',
    })
  }

  await dispatchKuaishouCloudFulfillmentTask(context.task, {
    source: 'claim_page_redeem',
    actor: { source: 'claim_page' },
    autoFinalize: true,
  })

  return getClaimDetail(token, { includeQrImage: false })
}
