/**
 * 日期和时间相关
 *
 * 更复杂的日期操作建议直接使用 dayjs https://dayjs.gitee.io/docs/zh-CN/installation/installation
 */
import dayjs from "dayjs";
import customParseFormat from "dayjs/plugin/customParseFormat";

dayjs.extend(customParseFormat);

export { dayjs };

/**
 * @group 日期格式
 * @groupOrder 4
 */
export const DATE_FORMAT = "YYYY-MM-DD";

/**
 * @group 日期格式
 * @groupOrder 4
 */
export const DATE_TIME_FORMAT = "YYYY-MM-DD HH:mm:ss";

export const SECOND = 1000; // 毫秒
export const MINUTE = 60 * SECOND;
export const HOUR = 60 * MINUTE;
export const DAY = 24 * HOUR;

/**
 * 日期解析
 *
 * @group 日期
 * @groupOrder 5
 *
 * @remarks
 * 如果传入数字，我们假定为`毫秒` <br/>
 *` parseDate`会先尝试常见的日期格式（例如 YYYY/MM/DD HH:mm:ss、YYYY-MM-DD HH:mm:ss、YYYY-MM-DD），如果`parse`失败就会使用`format`
 *
 * @param dateString - 要转换成日期的数字和字符串.
 * @param format - 用于指定日期的格式。如果你的日期格式不是常见的格式，可以显式指定
 * @link https://dayjs.gitee.io/docs/zh-CN/parse/string-format
 *
 * @example
 * 例子:
 * ```typescript
 * parseDate(3600)
 * // => 1970-01-01T00:00:03.600Z
 *
 * parseDate('2012/12/10 12:12:12')
 * // => 2012-02-10T04:12:12.000Z
 * ```
 * @public
 */
export function parseDate(
  dateString: string | number | Date,
  format?: string | string[]
): Date | null {
  if (typeof dateString === "number") {
    return new Date(dateString);
  } else if (dateString instanceof Date) {
    return dateString;
  }

  const day = dayjs(dateString, format);

  if (day.isValid()) {
    return day.toDate();
  } else {
    if (!format) {
      // 兼容 ios
      dateString = dateString.replace(/-/g, "/");
      dateString = dateString.replace(/T/g, " ");
    }

    const retry = dayjs(dateString);

    if (retry.isValid()) {
      return retry.toDate();
    }

    return null;
  }
}

/**
 * 格式化日期
 *
 * @group 日期
 * @groupOrder 5
 *
 * @remarks
 * 如果传入数字，我们假定为`毫秒`
 *
 * @param date - 日期.
 * @param format - 详见 {@link https://dayjs.gitee.io/docs/zh-CN/parse/string-format}.
 *
 * @example
 * 例子:
 * ```
 * const day = new Date('2012/12/12 12:12:12');
 *
 * const target = formatDate(day);
 * // => target = "2012-02-10"
 *
 * const target2 = formatDate(day, 'YYYY-MM-DD HH:mm:ss');
 * // => target2 = "2012-02-10 12:12:12"
 * ```
 * @public
 */
export function formatDate(
  date: string | number | Date,
  format: string = DATE_FORMAT,
  parseFormat?: string | string[]
): string {
  const parsed = parseDate(date, parseFormat);
  return dayjs(parsed).format(format);
}
