import { getOrderById } from '../../../repositories/order-repo.js'
import { listTasksByOrderId, updateTask } from '../../../repositories/task-repo.js'
import { createTaskEvent } from '../../../repositories/task-event-repo.js'
import type { JsonObject } from '../../../types/json.js'
import {
  findKuaishouIndustryVoucherByCode,
  listKuaishouIndustryVouchersByOid,
  listKuaishouIndustryVouchersByTaskId,
} from '../../../repositories/kuaishou-industry-voucher-repo.js'
import { resendKuaishouIndustryVoucherSendCallback } from '../../platforms/kuaishou-industry/send-code-service.js'
import { consumeKuaishouIndustryVoucher } from '../../platforms/kuaishou-industry/voucher-service.js'
import {
  attachKuaishouIndustryVoucherToTask,
  bindKuaishouIndustryVouchersToOrderTasks,
} from '../../platforms/kuaishou-industry/voucher-binding-service.js'
import { createHttpError } from '../../../utils/http.js'
import { nowIso } from '../../../utils/time.js'
import { TASK_STATUS } from '../../../domain/task-status.js'
import { createAdminViewerContext, parseTaskContext } from '../admin-read-shared-helpers.js'
import { getRequiredTask, mapTaskActionPayload } from '../admin-task-read-helpers.js'
import {
  dispatchFulfillmentTask,
  prepareFulfillmentBinding,
  rebindFulfillmentRole,
  refreshFulfillmentRole,
  returnFulfillmentNumber,
} from '../../fulfillment/executors/registry.js'
import { isKuaishouCloudTask, normalizeKuaishouCloudFlow } from './kuaishou-cloud-helpers.js'

import type {
  AdminEntityIdInput,
  AdminViewerSessionInput,
} from '../../../types/admin/read-inputs.js'
import type { AdminTaskKuaishouIndustryConsumeInput } from '../../../types/admin/write-inputs.js'
import type { AdminTaskActionResponse } from '../../../types/admin/write-models.js'
import type { KuaishouIndustryVoucherRow, TaskRow } from '../../../types/repository/rows.js'

export async function prepareAdminTaskKuaishouCloudFulfillment(
  taskId: AdminEntityIdInput,
  session: AdminViewerSessionInput | null = null,
): Promise<AdminTaskActionResponse> {
  const task = await getRequiredTask(taskId)
  const viewerContext = createAdminViewerContext(session)

  if (!viewerContext.canManageTaskLifecycle) {
    throw createHttpError('当前账号没有权限准备绑定资源', {
      statusCode: 403,
      errorCode: 'admin_task_prepare_kuaishou_cloud_forbidden',
    })
  }

  if (!isKuaishouCloudTask(task)) {
    throw createHttpError('当前任务不是 kuaishou-lewan 履约任务', {
      statusCode: 409,
      errorCode: 'admin_task_not_kuaishou_cloud',
    })
  }

  const result = await prepareFulfillmentBinding(task, {
    source: 'admin_task_prepare',
    actor: buildAdminActionActor(session),
    force: true,
  })
  if (!result?.task) {
    throw createHttpError('当前任务不支持准备绑定资源', {
      statusCode: 409,
      errorCode: 'admin_task_prepare_not_supported',
    })
  }

  return {
    task: mapTaskActionPayload(result.task),
    claimUrl: String(result.claimUrl || ''),
    token: String(result.token || ''),
  }
}

export async function dispatchAdminTaskKuaishouCloudFulfillment(
  taskId: AdminEntityIdInput,
  session: AdminViewerSessionInput | null = null,
): Promise<AdminTaskActionResponse> {
  const task = await getRequiredTask(taskId)
  const viewerContext = createAdminViewerContext(session)

  if (!viewerContext.canManageTaskLifecycle) {
    throw createHttpError('当前账号没有权限执行发货', {
      statusCode: 403,
      errorCode: 'admin_task_dispatch_kuaishou_cloud_forbidden',
    })
  }

  if (!isKuaishouCloudTask(task)) {
    throw createHttpError('当前任务不是 kuaishou-lewan 履约任务', {
      statusCode: 409,
      errorCode: 'admin_task_not_kuaishou_cloud',
    })
  }

  const result = await dispatchFulfillmentTask(task, {
    source: 'admin_task_dispatch',
    actor: buildAdminActionActor(session),
    autoFinalize: false,
  })
  if (!result?.task) {
    throw createHttpError('当前任务不支持 executor 发货', {
      statusCode: 409,
      errorCode: 'admin_task_dispatch_not_supported',
    })
  }

  return {
    task: mapTaskActionPayload(result.task),
  }
}

export async function refreshAdminTaskKuaishouCloudRoleInfo(
  taskId: AdminEntityIdInput,
  session: AdminViewerSessionInput | null = null,
): Promise<AdminTaskActionResponse> {
  const task = await getRequiredTask(taskId)
  const viewerContext = createAdminViewerContext(session)

  if (!viewerContext.canOperateAssistedTask) {
    throw createHttpError('当前账号没有权限刷新角色信息', {
      statusCode: 403,
      errorCode: 'admin_task_refresh_kuaishou_cloud_role_forbidden',
    })
  }

  if (!isKuaishouCloudTask(task)) {
    throw createHttpError('当前任务不是 kuaishou-lewan 履约任务', {
      statusCode: 409,
      errorCode: 'admin_task_not_kuaishou_cloud',
    })
  }

  const result = await refreshFulfillmentRole(task, {
    source: 'admin_task_refresh_role',
    actor: buildAdminActionActor(session),
    forceProbe: true,
    recordEvent: true,
  })
  if (!result?.task) {
    throw createHttpError('当前任务不支持刷新角色信息', {
      statusCode: 409,
      errorCode: 'admin_task_refresh_not_supported',
    })
  }

  return {
    task: mapTaskActionPayload(result.task),
  }
}

export async function rebindAdminTaskKuaishouCloudRole(
  taskId: AdminEntityIdInput,
  session: AdminViewerSessionInput | null = null,
): Promise<AdminTaskActionResponse> {
  const task = await getRequiredTask(taskId)
  const viewerContext = createAdminViewerContext(session)

  // 与刷新角色一致：客服可换绑协助处理 UID 绑错，不开放完整任务生命周期
  if (!viewerContext.canOperateAssistedTask) {
    throw createHttpError('当前账号没有权限换绑角色', {
      statusCode: 403,
      errorCode: 'admin_task_rebind_kuaishou_cloud_forbidden',
    })
  }

  const result = await rebindFulfillmentRole(task, {
    source: 'admin_task_rebind_role',
    actor: buildAdminActionActor(session),
  })
  if (!result?.task) {
    throw createHttpError('当前任务不支持换绑角色', {
      statusCode: 409,
      errorCode: 'admin_task_rebind_not_supported',
    })
  }

  return {
    task: mapTaskActionPayload(result.task),
    claimUrl: String(result.claimUrl || ''),
    token: String(result.token || ''),
  }
}

export async function returnNumberAdminTaskKuaishouCloudFulfillment(
  taskId: AdminEntityIdInput,
  session: AdminViewerSessionInput | null = null,
): Promise<AdminTaskActionResponse> {
  const task = await getRequiredTask(taskId)
  const viewerContext = createAdminViewerContext(session)

  if (!viewerContext.canManageTaskLifecycle) {
    throw createHttpError('当前账号没有权限退还号码', {
      statusCode: 403,
      errorCode: 'admin_task_return_kuaishou_cloud_forbidden',
    })
  }

  if (!isKuaishouCloudTask(task)) {
    throw createHttpError('当前任务不是 kuaishou-lewan 履约任务', {
      statusCode: 409,
      errorCode: 'admin_task_not_kuaishou_cloud',
    })
  }

  // admin 退号 = 清理虚拟号占位，不核销电子凭证
  const result = await returnFulfillmentNumber(task, {
    source: 'admin_task_return_number',
    actor: buildAdminActionActor(session),
    consumeIndustryVoucher: false,
  })
  if (!result?.task) {
    throw createHttpError('当前任务不支持退还号码', {
      statusCode: 409,
      errorCode: 'admin_task_return_not_supported',
    })
  }

  return {
    task: mapTaskActionPayload(result.task),
  }
}

export async function resendAdminTaskKuaishouIndustryVoucherCode(
  taskId: AdminEntityIdInput,
  session: AdminViewerSessionInput | null = null,
): Promise<AdminTaskActionResponse> {
  const task = await getRequiredTask(taskId)
  const now = nowIso()
  const viewerContext = createAdminViewerContext(session)

  if (!viewerContext.canOperateKuaishouIndustryVoucher) {
    throw createHttpError('当前账号没有权限重发电子凭证发码回调', {
      statusCode: 403,
      errorCode: 'admin_task_kuaishou_industry_resend_forbidden',
    })
  }

  const voucher = await getRequiredIndustryVoucherForTask(task)
  const order = await getOrderById(task.order_id)
  const result = await resendKuaishouIndustryVoucherSendCallback({
    voucherCode: voucher.voucher_code,
    oid: voucher.oid,
    preferredTotalGoodsValue: Number(order?.total_amount || 0) || 0,
  })
  const updatedVoucher = result.voucher || voucher

  if (!result.success) {
    const message = String(result.error || '电子凭证发码回调重发失败').trim()
    const failedTask = await updateTask(task.id, {
      task_status: TASK_STATUS.MANUAL_REVIEW,
      result_code: 'kuaishou_industry_send_callback_resend_failed',
      result_message: message,
      last_error: message,
      updated_at: now,
    })
    await createTaskEvent(
      task.id,
      'kuaishou_industry_send_callback_resend_failed',
      {
        oid: voucher.oid,
        voucherCode: voucher.voucher_code,
        errorMessage: message,
        actor: buildAdminActionActor(session),
      },
      now,
    )
    void failedTask
    throw createHttpError(message, {
      statusCode: 409,
      errorCode: 'admin_task_kuaishou_industry_resend_failed',
    })
  }

  const attachedTask = await attachKuaishouIndustryVoucherToTask(task, updatedVoucher, {
    source: 'admin_resend_kuaishou_industry_code',
    now,
  })
  const resendTargetTask = attachedTask || task
  const refreshedTask = await updateTask(resendTargetTask.id, {
    result_code: 'kuaishou_industry_send_callback_resent',
    result_message: '电子凭证发码回调已重发成功',
    last_error: '',
    updated_at: now,
  })

  await createTaskEvent(
    task.id,
    'kuaishou_industry_send_callback_resent',
    {
      oid: voucher.oid,
      voucherCode: voucher.voucher_code,
      actor: buildAdminActionActor(session),
    },
    now,
  )

  return { task: mapTaskActionPayload(refreshedTask || resendTargetTask) }
}

export async function resendAdminOrderKuaishouIndustryVoucherCodes(
  orderId: AdminEntityIdInput,
  session: AdminViewerSessionInput | null = null,
): Promise<{ success: boolean; resentCount: number; failedCount: number; errorMessage: string }> {
  const order = await getOrderById(Number(orderId))
  const viewerContext = createAdminViewerContext(session)
  const now = nowIso()

  if (!viewerContext.canOperateKuaishouIndustryVoucher) {
    throw createHttpError('当前账号没有权限重发电子凭证发码回调', {
      statusCode: 403,
      errorCode: 'admin_order_kuaishou_industry_resend_forbidden',
    })
  }

  if (!order) {
    throw createHttpError('订单不存在', {
      statusCode: 404,
      errorCode: 'admin_order_not_found',
    })
  }

  const vouchers = await resolveIndustryVouchersForOrder(order.platform_order_id)
  if (vouchers.length === 0) {
    throw createHttpError('当前订单没有关联电子凭证，无法重发发码回调', {
      statusCode: 409,
      errorCode: 'admin_order_kuaishou_industry_voucher_missing',
    })
  }

  let resentCount = 0
  let failedCount = 0
  let errorMessage = ''

  for (const voucher of vouchers) {
    const result = await resendKuaishouIndustryVoucherSendCallback({
      voucherCode: voucher.voucher_code,
      oid: voucher.oid,
      preferredTotalGoodsValue: Number(order.total_amount || 0) || 0,
    })

    if (result.success) {
      resentCount += 1
      continue
    }

    failedCount += 1
    errorMessage = errorMessage || String(result.error || '电子凭证发码回调重发失败').trim()
  }

  if (failedCount > 0) {
    throw createHttpError(errorMessage || '电子凭证发码回调重发失败', {
      statusCode: 409,
      errorCode: 'admin_order_kuaishou_industry_resend_failed',
      context: { resentCount, failedCount },
    })
  }

  const tasks = await listTasksByOrderId(order.id)
  await bindKuaishouIndustryVouchersToOrderTasks(order, tasks, {
    source: 'admin_order_resend_kuaishou_industry_code',
    now,
  })

  return {
    success: failedCount === 0,
    resentCount,
    failedCount,
    errorMessage,
  }
}

export async function consumeAdminTaskKuaishouIndustryVoucher(
  taskId: AdminEntityIdInput,
  payload: AdminTaskKuaishouIndustryConsumeInput = {},
  session: AdminViewerSessionInput | null = null,
): Promise<AdminTaskActionResponse> {
  const task = await getRequiredTask(taskId)
  const now = nowIso()
  const viewerContext = createAdminViewerContext(session)

  if (!viewerContext.canOperateKuaishouIndustryVoucher) {
    throw createHttpError('当前账号没有权限执行电子凭证核销', {
      statusCode: 403,
      errorCode: 'admin_task_kuaishou_industry_consume_forbidden',
    })
  }

  const voucher = await getRequiredIndustryVoucherForTask(task)
  const consumeType = String(payload.consumeType || '').trim()
  const result = await consumeKuaishouIndustryVoucher(voucher, {
    source: 'admin_manual_consume',
    task,
    token: voucher.token,
    consumeTime: Date.now(),
    ...(consumeType ? { consumeType } : {}),
    ...(payload.storeName ? { storeName: payload.storeName } : {}),
    ...(payload.storeAddress ? { storeAddress: payload.storeAddress } : {}),
    ...(payload.expressCode ? { expressCode: payload.expressCode } : {}),
    ...(payload.expressNo ? { expressNo: payload.expressNo } : {}),
  })

  if (!result.ok || !result.voucher) {
    const message = String(result.errorMessage || '电子凭证核销失败').trim()
    const failedTask = await updateTask(task.id, {
      task_status: TASK_STATUS.MANUAL_REVIEW,
      result_code: 'kuaishou_industry_manual_consume_failed',
      result_message: message,
      last_error: message,
      updated_at: now,
    })
    await createTaskEvent(
      task.id,
      'kuaishou_industry_manual_consume_failed',
      {
        oid: voucher.oid,
        voucherCode: voucher.voucher_code,
        errorMessage: message,
        actor: buildAdminActionActor(session),
      },
      now,
    )
    void failedTask
    throw createHttpError(message, {
      statusCode: 409,
      errorCode: 'admin_task_kuaishou_industry_consume_failed',
    })
  }

  const attachedConsumeTask = await attachKuaishouIndustryVoucherToTask(task, result.voucher, {
    source: 'admin_manual_consume',
    now,
  })
  const consumeTargetTask = attachedConsumeTask || task
  const taskContext = parseTaskContext(consumeTargetTask)
  const hasCloudFulfillmentContext = Boolean(
    taskContext.kuaishouCloudFulfillment &&
    typeof taskContext.kuaishouCloudFulfillment === 'object' &&
    !Array.isArray(taskContext.kuaishouCloudFulfillment),
  )
  const flow = hasCloudFulfillmentContext
    ? normalizeKuaishouCloudFlow(taskContext.kuaishouCloudFulfillment)
    : null
  const nextContext = {
    ...taskContext,
    ...(flow
      ? {
          kuaishouCloudFulfillment: {
            ...flow,
            consume: {
              ...flow.consume,
              status: 'success',
              consumedAt: result.voucher.consumed_at || now,
              errorMessage: '',
            },
          },
        }
      : {}),
  }
  const updatedTask = await updateTask(consumeTargetTask.id, {
    task_status: TASK_STATUS.COMPLETED,
    delivery_status: 'delivered',
    result_code: 'kuaishou_industry_manual_consumed',
    result_message: '电子凭证已手动核销完成',
    redeemed_at: result.voucher.consumed_at || now,
    last_error: '',
    context_json: JSON.stringify(nextContext),
    updated_at: now,
  })

  await createTaskEvent(
    task.id,
    'kuaishou_industry_manual_consumed',
    {
      oid: result.voucher.oid,
      voucherCode: result.voucher.voucher_code,
      consumeSerialNum: result.voucher.consume_serial_num,
      actor: buildAdminActionActor(session),
    },
    now,
  )

  return { task: mapTaskActionPayload(updatedTask || consumeTargetTask) }
}

async function getRequiredIndustryVoucherForTask(
  task: TaskRow,
): Promise<KuaishouIndustryVoucherRow> {
  const vouchers = await listKuaishouIndustryVouchersByTaskId(task.id)
  const firstVoucher = vouchers[0]
  if (firstVoucher) {
    return firstVoucher
  }

  const taskContext = parseTaskContext(task)
  const voucherContext = normalizeAdminTaskIndustryVoucherContext(
    taskContext.kuaishouIndustryVoucher,
  )
  const voucherCode = String(voucherContext.voucherCode || voucherContext.eticketId || '').trim()
  if (voucherCode) {
    const voucher = await findKuaishouIndustryVoucherByCode(voucherCode, task.platform_order_id)
    if (voucher) {
      return voucher
    }
  }

  const oidVouchers = await resolveIndustryVouchersForOrder(task.platform_order_id)
  if (voucherCode) {
    const matchedByCode = oidVouchers.find(
      (voucher) => String(voucher.voucher_code || '').trim() === voucherCode,
    )
    if (matchedByCode) {
      return matchedByCode
    }
  }

  const unitIndex = Number(task.unit_index || 0) || 0
  if (unitIndex > 0) {
    const matchedByUnit = oidVouchers.find(
      (voucher) => Number(voucher.unit_index || 0) === unitIndex,
    )
    if (matchedByUnit) {
      return matchedByUnit
    }
  }

  if (oidVouchers.length === 1 && oidVouchers[0]) {
    return oidVouchers[0]
  }

  throw createHttpError('当前任务没有关联电子凭证，无法执行该操作', {
    statusCode: 409,
    errorCode: 'admin_task_kuaishou_industry_voucher_missing',
  })
}

function normalizeAdminTaskIndustryVoucherContext(value: unknown): JsonObject {
  return value && typeof value === 'object' && !Array.isArray(value) ? (value as JsonObject) : {}
}

async function resolveIndustryVouchersForOrder(
  platformOrderId: string,
): Promise<KuaishouIndustryVoucherRow[]> {
  const normalizedOid = String(platformOrderId || '').trim()
  if (!normalizedOid) {
    return []
  }

  return listKuaishouIndustryVouchersByOid(normalizedOid)
}

function buildAdminActionActor(session: AdminViewerSessionInput | null) {
  return session
    ? {
        userId: Number(session.userId || 0) || 0,
        username: String(session.username || '').trim(),
        role: String(session.role || '').trim(),
      }
    : null
}
