package com.xjrsoft.common.utils;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import oracle.sql.INTERVALDS;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Year;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;

public final class LocalDateTimeUtil {
    private LocalDateTimeUtil(){}

    public final static String LOCAL_TIME_FORMAT = "HH:mm:ss";

    public final static String LOCAL_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public final static String LOCAL_DATE_FORMAT = "yyyy-MM-dd";

    public final static String YEAR_MONTH_FORMAT = "yyyy-MM";

    public final static String YEAR_FORMAT = "yyyy";

    public static LocalTime parseTime(String value) {
        return parseTime(value, LOCAL_TIME_FORMAT);
    }

    public static LocalTime parseTime(String value, String format) {
        if (StrUtil.isBlank(value)) {
            return null;
        }
        return LocalTime.parse(value, DateTimeFormatter.ofPattern(format));
    }

    public static LocalDateTime parseDate(String value) {
        return parseDate(value, LOCAL_DATE_TIME_FORMAT);
    }

    public static LocalDateTime parseDate(String value, String format) {
        if (StrUtil.isBlank(value)) {
            return null;
        }
        // 根据format切掉多余的时间
        value = StringUtils.substring(value, 0, format.length());
        LocalDateTime localDateTime = null;
        format = convertFontFormat(format);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format);
        switch (format) {
            case YEAR_FORMAT:
                Year year = Year.parse(value, dateTimeFormatter);
                localDateTime =  LocalDateTime.from(year.atDay(1).atStartOfDay());
                break;
            case YEAR_MONTH_FORMAT:
                YearMonth yearMonth = YearMonth.parse(value, dateTimeFormatter);
                localDateTime = LocalDateTime.from(yearMonth.atDay(1).atStartOfDay());
                break;
            case LOCAL_DATE_FORMAT:
                LocalDate localDate = LocalDate.parse(value, dateTimeFormatter);
                localDateTime = LocalDateTime.from(localDate.atStartOfDay());
                break;
            default:
                localDateTime = LocalDateTime.parse(value, dateTimeFormatter);
                break;
        }
        return localDateTime;
    }

    public static String convertFontFormat(String fontFormat) {
        if (StrUtil.isEmpty(fontFormat)) {
            return fontFormat;
        }
        return fontFormat.replace("YYYY", "yyyy").replace("DD", "dd");
    }

    public static String format(LocalDateTime dateTime, String format) {
        if (dateTime == null) {
            return StringPool.EMPTY;
        }
        return dateTime.format(DateTimeFormatter.ofPattern(format));
    }

    public static String format(LocalTime time) {
        if (time == null) {
            return StringPool.EMPTY;
        }
        return time.format(DateTimeFormatter.ofPattern(LOCAL_TIME_FORMAT));
    }

    /**
     * 将时间字符串转换成数据库对应的时间类型
     * @param time 时间字符串 格式 HH:mm:ss
     * @param dbType 数据库类型
     * @return 据库对应的时间类型对象
     */
    public static Object parseDbTime(String time, DbType dbType) {
        if (dbType == DbType.ORACLE || dbType == DbType.ORACLE_12C) {
            return new INTERVALDS("0 " + time + ".0");
        } else {
            return parseTime(time);
        }
    }

    public static LocalDateTime parseDateByLength(String value) {
        if (StrUtil.isNotBlank(value)) {
            value = value.trim();
            int length = value.length();
            if (LOCAL_DATE_FORMAT.length() == length) {
                LocalDate localDate = LocalDate.parse(value, DateTimeFormatter.ofPattern(LOCAL_DATE_FORMAT));
                return LocalDateTime.from(localDate.atStartOfDay());
            } else if (LOCAL_DATE_TIME_FORMAT.length() == length) {
                return LocalDateTime.parse(value, DateTimeFormatter.ofPattern(LOCAL_DATE_TIME_FORMAT));
            } else if (YEAR_MONTH_FORMAT.length() == length) {
                YearMonth yearMonth = YearMonth.parse(value, DateTimeFormatter.ofPattern(YEAR_MONTH_FORMAT));
                return LocalDateTime.from(yearMonth.atDay(1).atStartOfDay());
            } else if (YEAR_FORMAT.length() == length) {
                Year year = Year.parse(value, DateTimeFormatter.ofPattern(YEAR_FORMAT));
                return LocalDateTime.from(year.atDay(1).atStartOfDay());
            }
        }
        return null;
    }

    public static LocalTime convertIntervalToLocalTime(INTERVALDS intervalDS) {
        if (intervalDS == null) {
            return null;
        }
        String str = intervalDS.stringValue();
        String timeStr = str.substring(str.indexOf(StringPool.SPACE) + 1, str.indexOf(StringPool.DOT));
        String[] array = timeStr.split(StringPool.COLON);
        return LocalTime.of(Integer.parseInt(array[0]), Integer.parseInt(array[1]), Integer.parseInt(array[2]));
    }
}
