import { DateTime } from 'luxon'

import {
  isDate,
  isNumber,
  isString
} from '@/common/utils/types'
import { isNumStr } from '@/common/utils/objects.ts'
import { DateObjectUnits } from 'luxon/src/datetime'

/*
 * 文档：https://luxon.nodejs.cn/
 */

export enum FMT {
  month = 'yyyy-MM',
  date = 'yyyy-MM-dd',
  time = 'HH:mm',
  time_sec = 'HH:mm:ss',
  date_time = 'yyyy-MM-dd HH:mm',
  date_time_sec = 'yyyy-MM-dd HH:mm:ss',
  date_zh = 'yyyy年MM月dd日',
  time_zh = 'HH时mm分',
  time_sec_zh = 'HH时mm分ss秒',
  date_time_zh = 'yyyy年MM月dd日HH时mm分',
  date_time_sec_zh = 'yyyy年MM月dd日HH时mm分ss秒',
  timestamp = 'x',
}

/**
 * 获取当前时间
 *
 * @return luxon 库的时间对象
 */
export function now() {
  return DateTime.now()
}

/**
 * 解析时间
 *
 * @param date JS 时间对象、时间戳（数字、字符串）、时间字符串、时间描述对象
 * @param fmt 时间格式（仅时间字符串需要此参数，默认：yyyy-MM-dd HH:mm:ss）
 * @return luxon 库的时间对象
 */
export function parse(date: Date | number | string | DateObjectUnits, fmt: FMT = FMT.date_time_sec) {
  if (isDate(date)) {
    return DateTime.fromJSDate(<Date>date)
  } else if (isNumber(date) || isNumStr(date)) {
    return DateTime.fromMillis(Number(date))
  } else if (isString(date)) {
    return DateTime.fromFormat(<string>date, fmt)
  } else {
    return DateTime.fromObject(<DateObjectUnits>date)
  }
}

/**
 * 格式化时间
 *
 * @param date luxon 库的时间对象、JS 时间对象
 * @param fmt 时间格式（仅时间字符串需要此参数，默认：yyyy-MM-dd HH:mm:ss）
 */
export function format(date: DateTime<true | false> | Date, fmt: FMT = FMT.date_time_sec) {
  if (isDate(date)) {
    return DateTime.fromJSDate(<Date>date).toFormat(fmt)
  } else {
    return (<DateTime<true | false>>date).toFormat(fmt)
  }
}

/**
 * 时间美化（如：1年前）
 *
 * @param date luxon 库的时间对象、JS 时间对象、时间戳（数字、字符串）、时间字符串、时间描述对象
 */
export function pretty(date: DateTime<true | false> | Date | number | string) {
  if (!(date instanceof DateTime)) {
    date = parse(date)
  }

  let {
    seconds,
    minutes,
    hours,
    days,
    weeks,
    months,
    years
  } = date.diff(DateTime.now(), [ 'seconds', 'minutes', 'hours', 'days', 'weeks', 'months', 'years' ])

  if (years > 0) {
    return `${years}年后`
  } else if (years < 0) {
    return `${-years}年前`
  }

  if (months > 0) {
    return `${months}个月后`
  } else if (months < 0) {
    return `${-months}个月前`
  }

  if (weeks > 0) {
    return `${weeks}周后`
  } else if (weeks < 0) {
    return `${-weeks}周前`
  }

  if (days > 0) {
    return `${days}天后`
  } else if (days < 0) {
    return `${-days}天前`
  }

  if (hours > 0) {
    return `${hours}小时后`
  } else if (hours < 0) {
    return `${-hours}小时前`
  }

  if (minutes > 0) {
    return `${minutes}分钟后`
  } else if (minutes > -5 && minutes <= -1) {
    return '刚刚'
  } else if (minutes <= -5) {
    return `${minutes}分钟前`
  }

  if (seconds > 0) {
    return '片刻后'
  } else if (seconds < 0) {
    return '刚刚'
  }

  return '现在'
}

export function endOfMonth(date?: DateTime<true | false>) {
  if (date == null) {
    return date = now()
  }
  return date.endOf('month')
}

export function beginOfMonth(date?: DateTime<true | false>) {
  if (date == null) {
    return date = now()
  }
  return date.startOf('month')
}

export function toDate(date: DateTime<true | false>) {
  return date.toJSDate()
}

export default {
  now,
  parse,
  format,
  pretty,
  FMT,
  endOfMonth,
  beginOfMonth,
  toDate,
}
