import { createTaskEvent } from '../../../repositories/task-event-repo.js'
import { updateTask } from '../../../repositories/task-repo.js'
import type { TaskRow } from '../../../types/repository/rows.js'
import { createHttpError } from '../../../utils/http.js'
import { getCloudtentaclesBindInfo } from '../../platforms/cloudtentacles/virtual-number-service.js'
import {
  assertLewanAutoFulfillmentUidReady,
  isClaimUidMatched,
  normalizeClaimUid,
} from '../../claim/claim-identity.js'
import { asJsonObject } from '../../../types/json.js'
import {
  normalizeKuaishouCloudFlow,
  normalizeKuaishouCloudRoleInfo,
  type JsonObject,
} from './domain.js'

export async function syncKuaishouCloudRoleInfoBeforeDispatch(
  task: TaskRow,
  input: JsonObject = {},
) {
  const now = String(input.now || '').trim() || new Date().toISOString()
  const source = String(input.source || 'system_before_dispatch').trim() || 'system_before_dispatch'
  const errorCodePrefix =
    String(input.errorCodePrefix || 'kuaishou_cloud').trim() || 'kuaishou_cloud'
  const cloudContext = asJsonObject(input.cloudContext)
  const taskContext = asJsonObject(input.taskContext)
  const flow = normalizeKuaishouCloudFlow(input.flow || taskContext.kuaishouCloudFulfillment)

  // 新策略：lewan 自动发货必须有 expectedUid，旧单无 UID 不可静默回落
  const expectedUid = assertLewanAutoFulfillmentUidReady(task, {
    allowMockSkip: true,
    errorCodePrefix,
  })

  if (!flow.binding.vnId || !flow.binding.vnKey) {
    throw createHttpError('当前任务缺少可同步角色的虚拟号信息，暂时不能发货', {
      statusCode: 409,
      errorCode: `${errorCodePrefix}_dispatch_missing_bind_info_context`,
    })
  }

  const bindInfoResult = await getCloudtentaclesBindInfo({
    ...cloudContext,
    key: flow.binding.vnKey,
    id: flow.binding.vnId,
  })
  const roleInfo = normalizeKuaishouCloudRoleInfo(bindInfoResult.bindInfo)

  if (!roleInfo.name || !roleInfo.rid) {
    throw createHttpError('cloudtentacles 还没有同步到客户绑定角色，请稍后刷新角色信息后再发货', {
      statusCode: 409,
      errorCode: `${errorCodePrefix}_dispatch_role_not_ready`,
    })
  }

  const liveBoundUid = normalizeClaimUid(roleInfo.rid)

  if (expectedUid && !isClaimUidMatched(expectedUid, liveBoundUid)) {
    await createTaskEvent(
      task.id,
      'kuaishou_cloud_dispatch_uid_mismatch',
      {
        source,
        vnId: flow.binding.vnId,
        expectedUid,
        cloudtentaclesRoleName: roleInfo.name,
        cloudtentaclesRoleId: roleInfo.rid,
        actor: input.actor || null,
      },
      now,
    )

    throw createHttpError(
      `cloudtentacles 当前绑定角色 ID（${roleInfo.rid}）与用户填写 UID（${expectedUid}）不一致，不能发货`,
      {
        statusCode: 409,
        errorCode: `${errorCodePrefix}_dispatch_uid_mismatch`,
      },
    )
  }

  const nextFlow = normalizeKuaishouCloudFlow({
    ...flow,
    binding: {
      ...flow.binding,
      roleName: roleInfo.name,
      roleId: roleInfo.rid,
    },
    role: {
      ...flow.role,
      status: 'ready',
      name: roleInfo.name,
      rid: roleInfo.rid,
      refreshedAt: now,
      errorMessage: '',
      rawInfo: roleInfo.rawInfo,
    },
  })
  const nextContext = {
    ...taskContext,
    kuaishouCloudFulfillment: nextFlow,
  }

  const updatedTask = await updateTask(task.id, {
    role_id: roleInfo.rid,
    role_name: roleInfo.name,
    context_json: JSON.stringify(nextContext),
    updated_at: now,
  })

  if (!updatedTask) {
    throw createHttpError('发货前角色信息同步失败', {
      statusCode: 500,
      errorCode: `${errorCodePrefix}_dispatch_role_update_failed`,
    })
  }

  await createTaskEvent(
    task.id,
    'kuaishou_cloud_role_info_synced_before_dispatch',
    {
      source,
      roleName: roleInfo.name,
      roleId: roleInfo.rid,
      vnId: flow.binding.vnId,
      actor: input.actor || null,
    },
    now,
  )

  return {
    task: updatedTask,
    taskContext: nextContext,
    flow: nextFlow,
    roleInfo,
  }
}
