import type { ClaimDetailData } from '@/types/claim'
import type {
  TencentBrowserSessionData,
  TencentBrowserSessionSummaryData,
} from '@/types/tencent/session'

import type { ClaimTaskStatus } from '@/types/claim'
import { ACTIVE_TASK_STATUSES } from './sessionConstants'

/**
 * Generic merge of session detail data, preserving QR image and other
 * fields that may be absent in summary responses.
 *
 * The `extraSessionFields` callback lets callers inject domain-specific
 * session merge logic (e.g. `review` for admin, `redeem` for claim).
 */
export function mergeSessionDetail<T extends ClaimDetailData>(
  current: T | null,
  next: T,
  extraSessionFields?: (
    currentSession: NonNullable<T['session']>,
    nextSession: NonNullable<T['session']>,
  ) => Partial<NonNullable<T['session']>>,
): T {
  if (next.session === null) {
    return {
      ...next,
      session: null,
    } as T
  }

  if (!current?.session) {
    return next
  }

  const sessionBase = {
    ...current.session,
    ...next.session,
    qrImageBase64:
      typeof next.session.qrImageBase64 === 'string'
        ? next.session.qrImageBase64
        : current.session.qrImageBase64,
    activityInfo: next.session.activityInfo ?? current.session.activityInfo ?? null,
    redeem: next.session.redeem ?? current.session.redeem ?? null,
    artifacts: next.session.artifacts || current.session.artifacts,
  } as NonNullable<T['session']>

  const extras = extraSessionFields
    ? extraSessionFields(current.session as NonNullable<T['session']>, next.session as NonNullable<T['session']>)
    : {}

  return {
    ...next,
    session: {
      ...sessionBase,
      ...extras,
    },
  } as T
}

export function shouldRefreshQrImage(
  current: TencentBrowserSessionData | TencentBrowserSessionSummaryData | null,
  next: TencentBrowserSessionData | TencentBrowserSessionSummaryData | null,
): boolean {
  if (!current || !next || !next.artifacts?.hasQrImage) {
    return false
  }

  if (!current.qrImageBase64) {
    return true
  }

  return Boolean(next.qrUpdatedAt && next.qrUpdatedAt !== current.qrUpdatedAt)
}

export function shouldKeepPolling<T extends ClaimDetailData>(detail: T | null): boolean {
  if (!detail?.session?.sessionId) {
    return false
  }

  return ACTIVE_TASK_STATUSES.has(detail.task.status as ClaimTaskStatus)
}
