import {
  getTencentBrowserSession,
  getTencentBrowserSessionSummary,
} from '../../session/session.js'
import { updateTask } from '../../../repositories/task-repo.js'
import { nowIso } from '../../../utils/time.js'
import { isRecoverableSessionError, parseTaskState } from './shared.js'

type JsonObject = Record<string, any>

export async function loadTaskSession(task: JsonObject, { includeQrImage = false }: { includeQrImage?: boolean } = {}) {
  if (!task.browser_session_id) {
    return {
      task,
      session: null,
    }
  }

  try {
    const session = includeQrImage
      ? await getTencentBrowserSession(task.browser_session_id)
      : await getTencentBrowserSessionSummary(task.browser_session_id)

    return {
      task,
      session,
    }
  } catch (error) {
    if (!isRecoverableSessionError(error)) {
      throw error
    }

    const nextTask = await clearTaskSession(task, {
      lastError: '浏览器会话已失效，请重新初始化登录',
    })

    return {
      task: nextTask,
      session: null,
    }
  }
}

export async function syncTaskWithSession(task: JsonObject, session: JsonObject) {
  const activityInfo = session.activityInfo || null
  const patch: JsonObject = {
    login_type: String(session.loginType || task.login_type || ''),
    updated_at: nowIso(),
  }

  if (activityInfo?.nickname) {
    patch.nickname = String(activityInfo.nickname)
  }

  if (activityInfo?.role?.ready) {
    patch.role_id = String(activityInfo.role.roleId || '')
    patch.role_name = String(activityInfo.role.roleName || '')
    patch.area = String(activityInfo.role.area || '')
    patch.partition_name = String(activityInfo.role.partition || '')
  }

  if (task.task_status === 'link_generated') {
    patch.task_status = 'claimed'
    patch.user_action_status = 'claimed'
    patch.claimed_at = task.claimed_at || nowIso()
  }

  if (session.review?.capturedAt) {
    patch.state_json = JSON.stringify({
      ...parseTaskState(task),
      reviewScreenshotReady: true,
      reviewCapturedAt: String(session.review.capturedAt || ''),
      reviewRoleId: String(session.review.roleId || ''),
      reviewRoleName: String(session.review.roleName || ''),
    })
  }

  if (session.status === 'redeemed' && session.artifacts?.hasScreenshot) {
    patch.screenshot_path = task.screenshot_path || ''
  }

  return updateTask(task.id, patch)
}

export async function clearTaskSession(task: JsonObject, { lastError = '' }: { lastError?: string } = {}) {
  const shouldResetClaimProgress = ['link_generated', 'claimed', 'role_confirmed'].includes(String(task.task_status || ''))
  const nextTaskStatus = shouldResetClaimProgress ? 'link_generated' : task.task_status
  const nextUserActionStatus = shouldResetClaimProgress ? 'pending_claim' : task.user_action_status
  const patch = {
    task_status: nextTaskStatus,
    user_action_status: nextUserActionStatus,
    browser_session_id: '',
    login_type: '',
    nickname: '',
    role_id: '',
    role_name: '',
    area: '',
    partition_name: '',
    artifacts_json: '{}',
    state_json: '{}',
    role_confirmed_at: nextTaskStatus === 'link_generated' ? null : task.role_confirmed_at,
    last_error: String(lastError || ''),
    updated_at: nowIso(),
  }

  return updateTask(task.id, patch)
}
