import { createTaskEvent } from '../../../repositories/task-event-repo.js'
import { updateTask } from '../../../repositories/task-repo.js'
import { getCloudtentaclesBindInfo } from '../../platforms/cloudtentacles/virtual-number-service.js'
import { createHttpError } from '../../../utils/http.js'
import { nowIso } from '../../../utils/time.js'
import {
  isKuaishouCloudBindingMutationFrozen,
  isKuaishouCloudTask,
  normalizeKuaishouCloudFlow,
  normalizeKuaishouCloudRoleInfo,
  type JsonObject,
} from './domain.js'
import { resolvePersistedCloudtentaclesContextBySourceKeys } from './cloudtentacles-context.js'
import { normalizeActor, parseTaskContext } from './task-context.js'
import { buildRoleStateFromCurrentInfo } from './role-state.js'
import { probeKuaishouCloudTaskBindUrl } from './probe-bind-url.js'
import type { TaskRow } from '../../../types/repository/rows.js'

export async function refreshKuaishouCloudTaskRoleInfo(task: TaskRow, options: JsonObject = {}) {
  if (!isKuaishouCloudTask(task)) {
    throw createHttpError('当前任务不是 kuaishou-lewan 履约任务', {
      statusCode: 409,
      errorCode: 'kuaishou_cloud_task_invalid',
    })
  }

  const now = nowIso()
  const actor = normalizeActor(options.actor)
  const taskContext = parseTaskContext(task)
  const flow = normalizeKuaishouCloudFlow(taskContext.kuaishouCloudFulfillment)

  // 已发货：禁止 live 刷角色覆盖发货快照（claim 轮询 / 后台误触）
  if (isKuaishouCloudBindingMutationFrozen(task, flow)) {
    return {
      task,
      roleInfo: {
        name: flow.shipped?.roleName || flow.binding.roleName || flow.role.name,
        rid: flow.shipped?.roleId || flow.binding.roleId || flow.role.rid,
        rawInfo: flow.role.rawInfo,
      },
      flow,
    }
  }

  if (!flow.binding.vnId || !flow.binding.vnKey) {
    throw createHttpError('当前任务还没有可查询的绑定角色信息，请先准备绑定资源', {
      statusCode: 409,
      errorCode: 'kuaishou_cloud_missing_bind_info_context',
    })
  }

  if (flow.binding.bindUrl) {
    const probed = await probeKuaishouCloudTaskBindUrl(task, {
      source: options.source || 'system_role_refresh_bind_url_probe',
      actor,
      force: options.forceProbe === true,
    })
    const probedFlow = normalizeKuaishouCloudFlow(
      parseTaskContext(probed.task).kuaishouCloudFulfillment,
    )
    if (probed.probe?.expired) {
      return {
        task: probed.task,
        roleInfo: normalizeKuaishouCloudRoleInfo(null),
        flow: probedFlow,
      }
    }

    if (
      (probed.probe === null || probed.probe?.valid) &&
      (probedFlow.binding.roleName || probedFlow.binding.roleId)
    ) {
      return {
        task: probed.task,
        roleInfo: {
          name: probedFlow.binding.roleName,
          rid: probedFlow.binding.roleId,
          rawInfo: probedFlow.role.rawInfo,
        },
        flow: probedFlow,
      }
    }
  }

  const cloudContext = resolvePersistedCloudtentaclesContextBySourceKeys([
    flow.binding.resolvedSourceKey,
    ...flow.binding.cloudSourceKeys,
  ])
  const bindInfoResult = await getCloudtentaclesBindInfo({
    ...cloudContext,
    key: flow.binding.vnKey,
    id: flow.binding.vnId,
  })

  const bindInfo = normalizeKuaishouCloudRoleInfo(bindInfoResult.bindInfo)
  const roleState = buildRoleStateFromCurrentInfo({
    flow,
    roleInfo: bindInfo,
    now,
    emptyMessage: '当前还没有查询到角色信息，请完成绑定后稍等片刻再试',
  })
  const nextContext = {
    ...taskContext,
    kuaishouCloudFulfillment: {
      ...flow,
      binding: {
        ...flow.binding,
        roleName: roleState.bindingRoleName,
        roleId: roleState.bindingRoleId,
      },
      role: roleState.role,
    },
  }

  const updatedTask = await updateTask(task.id, {
    // UID 主闸：有绑定角色即落库，默认角色仅诊断
    role_id: roleState.hasRoleInfo ? bindInfo.rid : '',
    role_name: roleState.hasRoleInfo ? bindInfo.name : '',
    context_json: JSON.stringify(nextContext),
    updated_at: now,
  })

  if (options.recordEvent !== false) {
    await createTaskEvent(
      task.id,
      'kuaishou_cloud_role_info_refreshed',
      {
        source: String(options.source || 'system').trim() || 'system',
        roleName: bindInfo.name,
        roleId: bindInfo.rid,
        vnId: flow.binding.vnId,
        actor,
      },
      now,
    )
  }

  return {
    task: updatedTask,
    roleInfo: bindInfo,
    flow: normalizeKuaishouCloudFlow(nextContext.kuaishouCloudFulfillment),
  }
}
