export type UnifiedOrderSource = 'goods' | 'service'

export type OrderStatusSource = {
  source?: UnifiedOrderSource | string
  order_status: number
  payment_status: number
  pay_expire_at: string
  created_at: string
  cancel_reason: string
}

export const ORDER_STATUS_PENDING = 1
export const ORDER_STATUS_PAID_OR_SHIPPING = 2
export const ORDER_STATUS_RECEIVING = 3
export const ORDER_STATUS_COMPLETED = 4
export const ORDER_STATUS_CANCELLED = 5
export const ORDER_STATUS_REFUNDING = 6
export const ORDER_STATUS_REFUNDED = 7
export const ORDER_STATUS_TIMEOUT_LEGACY = 8

export const PAYMENT_STATUS_UNPAID = 1
export const PAYMENT_STATUS_PAID = 2
export const PAYMENT_STATUS_PARTIAL_REFUND = 3
export const PAYMENT_STATUS_REFUNDED = 4
export const PAYMENT_STATUS_TIMEOUT = 5

export const ORDER_PAY_TIMEOUT_SECONDS = 10 * 60
export const ORDER_TIMEOUT_CANCEL_REASON = '支付超时自动取消'

function parseDateMs(value: string): number {
  if (value == '') {
    return 0
  }
  const date = new Date(value)
  if (isNaN(date.getTime())) {
    return 0
  }
  return date.getTime()
}

function containsTimeoutReason(cancelReason: string): boolean {
  return cancelReason.indexOf('超时') >= 0
}

function getNormalizedSource(order: OrderStatusSource): UnifiedOrderSource {
  if (order.source == 'service') {
    return 'service'
  }
  return 'goods'
}

function isPendingSourceOrder(order: OrderStatusSource): boolean {
  return order.order_status == ORDER_STATUS_PENDING && order.payment_status == PAYMENT_STATUS_UNPAID
}

export function getOrderDeadlineMs(order: OrderStatusSource): number {
  const payExpireAtMs = parseDateMs(order.pay_expire_at)
  if (payExpireAtMs > 0) {
    return payExpireAtMs
  }
  const createdAtMs = parseDateMs(order.created_at)
  if (createdAtMs > 0) {
    return createdAtMs + ORDER_PAY_TIMEOUT_SECONDS * 1000
  }
  return 0
}

export function getRemainingSeconds(order: OrderStatusSource): number {
  const deadlineMs = getOrderDeadlineMs(order)
  if (deadlineMs <= 0) {
    return 0
  }
  const diff = Math.floor((deadlineMs - Date.now()) / 1000)
  return diff > 0 ? diff : 0
}

export function getUnifiedDisplayState(order: OrderStatusSource): string {
  const source = getNormalizedSource(order)
  const deadlineMs = getOrderDeadlineMs(order)
  const hasExpiredByDeadline = order.order_status == ORDER_STATUS_PENDING && deadlineMs > 0 && deadlineMs <= Date.now()

  if (source == 'service') {
    if (order.order_status == ORDER_STATUS_PENDING && order.payment_status == PAYMENT_STATUS_UNPAID && !hasExpiredByDeadline && !containsTimeoutReason(order.cancel_reason)) {
      return 'pending_pay'
    }
    if (order.order_status == ORDER_STATUS_TIMEOUT_LEGACY || order.payment_status == PAYMENT_STATUS_TIMEOUT || containsTimeoutReason(order.cancel_reason)) {
      return 'cancelled'
    }
    if (hasExpiredByDeadline) {
      return 'expired'
    }
    if (order.order_status == 2 || order.order_status == 3 || order.order_status == 4) {
      return 'processing'
    }
    if (order.order_status == ORDER_STATUS_COMPLETED) {
      return 'completed'
    }
    if (order.order_status == ORDER_STATUS_REFUNDING || order.order_status == ORDER_STATUS_REFUNDED) {
      return 'refund'
    }
    return 'unknown'
  }

  if (order.order_status == ORDER_STATUS_PENDING && order.payment_status == PAYMENT_STATUS_UNPAID && !hasExpiredByDeadline && !containsTimeoutReason(order.cancel_reason)) {
    return 'pending_pay'
  }
  if (order.order_status == ORDER_STATUS_CANCELLED || order.order_status == ORDER_STATUS_TIMEOUT_LEGACY || order.payment_status == PAYMENT_STATUS_TIMEOUT || containsTimeoutReason(order.cancel_reason)) {
    return 'cancelled'
  }
  if (hasExpiredByDeadline) {
    return 'expired'
  }
  if (order.order_status == ORDER_STATUS_PAID_OR_SHIPPING || order.order_status == ORDER_STATUS_RECEIVING) {
    return 'processing'
  }
  if (order.order_status == ORDER_STATUS_COMPLETED) {
    return 'completed'
  }
  if (order.order_status == ORDER_STATUS_REFUNDING || order.order_status == ORDER_STATUS_REFUNDED) {
    return 'refund'
  }
  return 'unknown'
}

export function isOrderPayExpired(order: OrderStatusSource): boolean {
  const displayState = getUnifiedDisplayState(order)
  return displayState == 'cancelled' || displayState == 'expired'
}

export function isPendingPayOrder(order: OrderStatusSource): boolean {
  return getUnifiedDisplayState(order) == 'pending_pay' && isPendingSourceOrder(order)
}

export function getOrderDisplayStatus(order: OrderStatusSource): string {
  const displayState = getUnifiedDisplayState(order)
  if (displayState == 'pending_pay') {
    return 'pending'
  }
  if (displayState == 'cancelled' || displayState == 'expired') {
    return 'cancelled'
  }
  if (displayState == 'processing') {
    return 'shipping'
  }
  if (displayState == 'completed') {
    return 'completed'
  }
  if (displayState == 'refund') {
    return 'refund'
  }
  return 'unknown'
}

function pad2(value: number): string {
  return value < 10 ? '0' + value : '' + value
}

export function formatCountdownHM(seconds: number): string {
  const safeSeconds = seconds > 0 ? seconds : 0
  const totalMinutes = Math.floor(safeSeconds / 60)
  const hours = Math.floor(totalMinutes / 60)
  const minutes = totalMinutes % 60
  return pad2(hours) + '时' + pad2(minutes) + '分钟'
}

export function formatCountdownHMS(seconds: number): string {
  const safeSeconds = seconds > 0 ? seconds : 0
  const hours = Math.floor(safeSeconds / 3600)
  const minutes = Math.floor((safeSeconds % 3600) / 60)
  const remainSeconds = safeSeconds % 60
  return pad2(hours) + ':' + pad2(minutes) + ':' + pad2(remainSeconds)
}