import { createTaskEvent } from '../../../repositories/task-event-repo.js'
import { updateTask } from '../../../repositories/task-repo.js'
import { probeCloudtentaclesBindUrl } from '../../platforms/cloudtentacles/virtual-number-service.js'
import { resolveCloudtentaclesConfig } from '../../platforms/cloudtentacles/helpers.js'
import { notifyKuaishouCloudBindUrlRefreshFailed } from '../../notification/domain-notifications.js'
import { createHttpError } from '../../../utils/http.js'
import { nowIso } from '../../../utils/time.js'
import { TASK_STATUS } from '../../../domain/task-status.js'
import {
  isKuaishouCloudBindUrlFresh,
  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 { refreshKuaishouCloudTaskBindUrl } from './prepare-fulfillment.js'
import type { TaskRow } from '../../../types/repository/rows.js'

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

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

  // 已发货：禁止 probe 触发过期换号 / 覆盖角色
  if (isKuaishouCloudBindingMutationFrozen(task, flow)) {
    return {
      task,
      flow,
      probe: null as null,
    }
  }

  if (!flow.binding.bindUrl) {
    return {
      task,
      flow,
      probe: null as null,
    }
  }

  const probeIntervalMs =
    Number(resolveCloudtentaclesConfig().bindUrlProbeIntervalSeconds || 30) * 1000
  const lastProbeAt = flow.binding.bindProbeAt
    ? Date.parse(String(flow.binding.bindProbeAt))
    : NaN
  if (
    !options.force &&
    Number.isFinite(lastProbeAt) &&
    Date.now() - lastProbeAt < probeIntervalMs
  ) {
    return {
      task,
      flow,
      probe: null as null,
    }
  }

  const probe = await probeCloudtentaclesBindUrl({
    bindUrl: flow.binding.bindUrl,
  })

  if (probe.expired || !isKuaishouCloudBindUrlFresh(flow)) {
    const refreshed = await refreshKuaishouCloudTaskBindUrl(task, {
      source: options.source || 'claim_page_bind_url_expired',
      actor: options.actor || { source: 'system' },
    })
    return {
      ...refreshed,
      probe,
    }
  }

  const probeRoleInfo = normalizeKuaishouCloudRoleInfo(probe.roleInfo)
  const hasRoleInfo = Boolean(probeRoleInfo.name || probeRoleInfo.rid)
  const roleState = hasRoleInfo
    ? buildRoleStateFromCurrentInfo({
        flow,
        roleInfo: probeRoleInfo,
        now,
        emptyMessage: '当前还没有查询到角色信息，请完成绑定后稍等片刻再试',
      })
    : null
  const nextContext = {
    ...taskContext,
    kuaishouCloudFulfillment: {
      ...flow,
      binding: {
        ...flow.binding,
        bindProbeAt: now,
        bindProbeStatus: probe.valid ? 'valid' : 'invalid',
        bindProbeMessage: String(probe.message || probe.reason || '').trim(),
        roleName: roleState ? roleState.bindingRoleName : flow.binding.roleName,
        roleId: roleState ? roleState.bindingRoleId : flow.binding.roleId,
      },
      role: roleState ? roleState.role : flow.role,
    },
  }

  const updatedTask = await updateTask(task.id, {
    role_id: roleState && !roleState.isDefaultRole ? probeRoleInfo.rid : task.role_id,
    role_name: roleState && !roleState.isDefaultRole ? probeRoleInfo.name : task.role_name,
    context_json: JSON.stringify(nextContext),
    updated_at: now,
  })

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

/**
 * @param {any} task
 * @param {{ taskContext?: any, flow?: any, now?: string, actor?: any, error?: unknown }} [input]
 */
async function markKuaishouCloudBindUrlRefreshFailed(
  task: TaskRow,
  { taskContext, flow, now, actor, error }: JsonObject = {},
) {
  const errorMessage =
    error instanceof Error ? error.message : String(error || '新绑定链接准备失败')
  const nextContext = {
    ...taskContext,
    kuaishouCloudFulfillment: {
      ...flow,
      binding: {
        ...flow.binding,
        prepareStatus: 'pending',
        vnId: 0,
        vnPhone: '',
        bindUrl: '',
        bindPreparedAt: null,
        bindExpiresAt: null,
        bindProbeAt: now,
        bindProbeStatus: 'refresh_failed',
        bindProbeMessage: errorMessage,
        roleName: '',
        roleId: '',
      },
      role: {
        status: 'pending',
        name: '',
        rid: '',
        refreshedAt: now,
        errorMessage: '绑定链接已过期，旧号码已退还，新链接准备失败，请稍后刷新或联系客服处理',
        rawInfo: null,
      },
    },
  }

  const updatedTask = await updateTask(task.id, {
    task_status: TASK_STATUS.PENDING_BINDING_PREPARE,
    role_id: '',
    role_name: '',
    last_error: `绑定链接过期，旧号码已退还，新链接准备失败：${errorMessage}`,
    context_json: JSON.stringify(nextContext),
    updated_at: now,
  })

  await createTaskEvent(
    task.id,
    'kuaishou_cloud_bind_url_refresh_failed',
    {
      source: 'system_refresh_expired_bind_url',
      errorMessage,
      actor,
    },
    now,
  )

  await notifyKuaishouCloudBindUrlRefreshFailed({
    task: updatedTask,
    errorMessage,
  })

  return updatedTask
}

