/*
 * Copyright 2019-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package easydo.technology.utils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;

/**
 * @author: liaojinlong
 * @date: 2020/6/11 16:28
 * @apiNote: JDK 8  新日期类 格式化与字符串转换 工具类
 */
public class LocalDateUtil {

    public static final DateTimeFormatter DFY_MD_HMS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public static final DateTimeFormatter DFY_MD = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    public static final DateTimeFormatter DFY_MD_2 = DateTimeFormatter.ofPattern("yyyyMMdd");

    /**
     * LocalDateTime 转时间戳
     *
     * @param localDateTime /
     * @return /
     */
    public static Long getTimeStamp(LocalDateTime localDateTime) {
        return localDateTime.atZone(ZoneId.systemDefault()).toEpochSecond();
    }

    /**
     * 时间戳转LocalDateTime
     *
     * @param timeStamp /
     * @return /
     */
    public static LocalDateTime fromTimeStamp(Long timeStamp) {
        return LocalDateTime.ofEpochSecond(timeStamp, 0, OffsetDateTime.now().getOffset());
    }

    /**
     * LocalDateTime 转 Date
     * Jdk8 后 不推荐使用 {@link Date} Date
     *
     * @param localDateTime /
     * @return /
     */
    public static Date toDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * LocalDate 转 Date
     * Jdk8 后 不推荐使用 {@link Date} Date
     *
     * @param localDate /
     * @return /
     */
    public static Date toDate(LocalDate localDate) {
        return toDate(localDate.atTime(LocalTime.now(ZoneId.systemDefault())));
    }


    /**
     * Date转 LocalDateTime
     * Jdk8 后 不推荐使用 {@link Date} Date
     *
     * @param date /
     * @return /
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * 日期 格式化
     *
     * @param localDateTime /
     * @param patten        /
     * @return /
     */
    public static String localDateTimeFormat(LocalDateTime localDateTime, String patten) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(patten);
        return df.format(localDateTime);
    }

    public static String localDateTimeFormat(LocalDate localDate, String patten) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(patten);
        return df.format(localDate);
    }

    /**
     * 日期 格式化
     *
     * @param localDateTime /
     * @param df            /
     * @return /
     */
    public static String localDateTimeFormat(LocalDateTime localDateTime, DateTimeFormatter df) {
        return df.format(localDateTime);
    }

    /**
     * 日期格式化 yyyy-MM-dd HH:mm:ss
     *
     * @param localDateTime /
     * @return /
     */
    public static String localDateTimeFormatyMdHms(LocalDateTime localDateTime) {
        return DFY_MD_HMS.format(localDateTime);
    }

    /**
     * 日期格式化 yyyy-MM-dd
     *
     * @param localDateTime /
     * @return /
     */
    public static String localDateTimeFormatyMd(LocalDateTime localDateTime) {
        return DFY_MD.format(localDateTime);
    }

    /**
     * 日期格式化 yyyyMMdd
     *
     * @param localDateTime /
     * @return /
     */
    public static String localDateTimeFormatyMd2(LocalDateTime localDateTime) {
        return DFY_MD_2.format(localDateTime);
    }

    /**
     * 字符串转 LocalDateTime ，字符串格式 yyyy-MM-dd
     *
     * @param localDateTime /
     * @return /
     */
    public static LocalDateTime parseLocalDateTimeFormat(String localDateTime, String pattern) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
        return LocalDateTime.from(dateTimeFormatter.parse(localDateTime));
    }

    /**
     * 字符串转 LocalDateTime ，字符串格式 yyyy-MM-dd
     *
     * @param localDateTime /
     * @return /
     */
    public static LocalDateTime parseLocalDateTimeFormat(String localDateTime, DateTimeFormatter dateTimeFormatter) {
        return LocalDateTime.from(dateTimeFormatter.parse(localDateTime));
    }

    /**
     * 字符串转 LocalDateTime ，字符串格式 yyyy-MM-dd HH:mm:ss
     *
     * @param localDateTime /
     * @return /
     */
    public static LocalDateTime parseLocalDateTimeFormatyMdHms(String localDateTime) {
        return LocalDateTime.from(DFY_MD_HMS.parse(localDateTime));
    }

    public static LocalDateTime formatTimeStr(String dateStr) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localTime;
        try {
            if (dateStr.contains("-")) {
                localTime = LocalDateTime.parse(dateStr, df);
            } else {
                localTime = new Date(Long.valueOf(dateStr)).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();
            }
        } catch (Exception e) {
            // 提取年月部分
            String[] parts = dateStr.split("[- :]");
            int year = Integer.parseInt(parts[0]);
            int month = Integer.parseInt(parts[1]);

            // 获取该月的最后一天
            LocalDateTime lastDay = LocalDateTime.of(year, month, 1, 0, 0)
                    .with(TemporalAdjusters.lastDayOfMonth());

            // 设置时间部分
            int hour = Integer.parseInt(parts[3]);
            int minute = Integer.parseInt(parts[4]);
            int second = Integer.parseInt(parts[5]);

            return lastDay.withHour(hour).withMinute(minute).withSecond(second);
        }

        return localTime;
    }

    public static LocalDate formatDateStr(String dateStr) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate localTime;
        if (dateStr.contains("-")) {
            localTime = LocalDate.parse(dateStr, df);
        } else {
            localTime = new Date(Long.valueOf(dateStr)).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDate();
        }
        return localTime;
    }

    public static LocalDateTime replaceFormatTimeStr(String timeStr, String replaceStr) {
        if (StringUtil.isEmpty(replaceStr)) {
            return formatTimeStr(timeStr);
        }
        int paramLen = replaceStr.length();
        String targetTimeStr = replaceStr + timeStr.substring(paramLen);
        return formatTimeStr(targetTimeStr);
    }

    public static String replaceLocalDateTimeStr(String timeStr, String replaceStr) {
        if (StringUtil.isEmpty(replaceStr) || StringUtil.isEmpty(timeStr)) {
            return timeStr;
        }
        int paramLen = replaceStr.length();
        String targetTimeStr = replaceStr + timeStr.substring(paramLen);
        LocalDateTime dateTime = formatTimeStr(targetTimeStr);
        return localDateTimeFormatyMdHms(dateTime);
    }
}
