import { TaskStatusLabel } from '~/types/Task.enum'

export interface TimeInfo {
  totalDuration: number
  elapsed: number
  remaining: number
  isEnded: boolean
  isStarted: boolean
  isInProgress: boolean
}

/**
 * Calculates time information for a reservation.
 */
export const getTimeInfo = (
  startTimeStr: string,
  endTimeStr: string,
  now: Date,
): TimeInfo | null => {
  const startDate = parseStrToDate(startTimeStr)
  const endDate = parseStrToDate(endTimeStr)

  if (!startDate || !endDate) return null

  const totalDurationMinutes = Math.round((endDate.getTime() - startDate.getTime()) / (1000 * 60))
  let elapsedMinutes = Math.round((now.getTime() - startDate.getTime()) / (1000 * 60))

  if (now > endDate) {
    elapsedMinutes = totalDurationMinutes
  } else if (now < startDate) {
    elapsedMinutes = 0
  }

  const remainingMinutes = totalDurationMinutes - elapsedMinutes

  return {
    totalDuration: totalDurationMinutes,
    elapsed: elapsedMinutes,
    remaining: remainingMinutes,
    isEnded: now > endDate,
    isStarted: now >= startDate,
    isInProgress: now >= startDate && now <= endDate,
  }
}

/**
 * Determines the display status based on parent and child statuses.
 */
export const getDisplayStatus = (
  parentStatus: string,
  childStatus: string,
  hideMoney: boolean = false,
): string => {
  let status = childStatus

  if (hideMoney) {
    if (childStatus === TaskStatusLabel.MEMBER_FINISH_PAYMENT) {
      status = '會員已確認約會'
    }
    if (childStatus === TaskStatusLabel.MEMBER_REQUEST_REFUND_FOR_LATE) {
      status = '情人遲到會員取消約會'
    }
  }

  // 當子狀態為"情人同意縮短約會時間"時，統一使用父狀態
  if (childStatus === TaskStatusLabel.LOVER_ACCEPT_SHORTEN) {
    status = parentStatus || '約會完成'
  }

  // 當子狀態為"情人確認打槍"時，統一使用父狀態
  if (childStatus === TaskStatusLabel.LOVER_ACCEPT_BAN) {
    status = parentStatus || '約會取消'
  }

  return status
}

/**
 * Calculates the display end time including addTime adjustments.
 */
export const getDisplayEndTime = (
  endTime: string,
  childStatus: string,
  addTime: string | null | undefined,
): string => {
  if (!endTime) return ''

  // 檢查子狀態是否為"情人遲到同意延長時間"或"會員約會完成"且 addTime 是 + 開頭
  const isTargetStatus = childStatus === '會員約會完成' || childStatus === '情人遲到同意延長時間'
  const hasAddTime = addTime && addTime.trim() !== '' && addTime.trim().startsWith('+')

  if (isTargetStatus && hasAddTime) {
    const addTimeNum = Number(addTime)
    if (!isNaN(addTimeNum) && addTimeNum > 0) {
      const endDate = parseStrToDate(endTime)
      if (endDate) {
        const newEndTime = new Date(endDate.getTime() + addTimeNum * 60 * 1000)
        return dateToString(newEndTime, 'yyyy-MM-dd HH:mm:ss')
      }
    }
  }

  return endTime
}

/**
 * Checks if the threshold (e.g., 15 minutes) from start time has been exceeded.
 */
export const isLateThresholdExceeded = (
  startTimeStr: string,
  now: Date,
  thresholdMinutes: number = 15,
): boolean => {
  const startDate = parseStrToDate(startTimeStr)
  if (!startDate) return false

  const thresholdMs = thresholdMinutes * 60 * 1000
  return now.getTime() >= startDate.getTime() + thresholdMs
}

/**
 * Calculates late information: isLate status and refund amount.
 */
export const calculateLateInfo = (
  startTimeStr: string,
  arrivalTimeStr: string,
  oneTimePrice: number,
  totalHours: number,
  lateRefundRate: number, // e.g., 0.8
): { isLate: boolean; lateMinutes: number; refundAmount: number } => {
  const startDate = parseStrToDate(startTimeStr)
  const arrivalDate = parseStrToDate(arrivalTimeStr)

  const defaultResult = { isLate: false, lateMinutes: 0, refundAmount: 0 }

  if (!startDate || !arrivalDate || isNaN(startDate.getTime()) || isNaN(arrivalDate.getTime())) {
    return defaultResult
  }

  if (arrivalDate.getTime() <= startDate.getTime()) {
    return defaultResult
  }

  const lateMinutes = Math.floor((arrivalDate.getTime() - startDate.getTime()) / (60 * 1000))

  // Calculate refund
  const oneMinPrice = Math.floor(oneTimePrice / 60)
  const oneMinRefundPrice = Math.floor(oneMinPrice * lateRefundRate)
  const actualRefundAmount = oneMinRefundPrice * lateMinutes

  // Cap the refund (max = hourly price * hours * refund rate)
  const maxRefundAmount = Math.floor(oneTimePrice * totalHours * lateRefundRate)

  return {
    isLate: true,
    lateMinutes,
    refundAmount: Math.min(actualRefundAmount, maxRefundAmount),
  }
}

/**
 * Calculates the refund amount for shortening the dating time.
 */
export const calculateShortenRefund = (
  shortenMinutes: number,
  oneTimePrice: number,
  earlyRefundRate: number, // e.g., 0.8
): number => {
  if (shortenMinutes <= 0) return 0

  const oneMinPrice = Math.floor(oneTimePrice / 60)
  const oneMinRefundPrice = Math.floor(oneMinPrice * earlyRefundRate)
  return Math.floor(oneMinRefundPrice * shortenMinutes)
}

/**
 * Helper to parse string to date (duplicated from BaseFunction to keep this utility pure/self-contained for tests)
 */
function parseStrToDate(str: string): Date | null {
  if (!str) return null
  // Handle space between date and time
  const dateStr = str.replace(/-/g, '/')
  const date = new Date(dateStr)
  return isNaN(date.getTime()) ? null : date
}

/**
 * Helper to convert date to string
 */
function dateToString(date: Date, format: string): string {
  const z = {
    M: date.getMonth() + 1,
    d: date.getDate(),
    H: date.getHours(),
    m: date.getMinutes(),
    s: date.getSeconds(),
  }
  let result = format.replace(/(M+|d+|H+|m+|s+)/g, (v) => {
    // @ts-ignore
    return ((v.length > 1 ? '0' : '') + z[v.slice(-1)]).slice(-2)
  })

  return result.replace(/(y+)/g, (v) => {
    return date.getFullYear().toString().slice(-v.length)
  })
}
