/*
 * 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 com.youchain.utils;

import com.youchain.exception.BadRequestException;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

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

    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_HM = DateTimeFormatter.ofPattern("yyyy-MM-dd HH");

    private static SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 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);
    }

    /**
     * 日期 格式化
     *
     * @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);
    }


    public static Date ymd_date(String fomart) {
        try {
            return ymd.parse(fomart);
        } catch (ParseException e) {
            return null;
        }
    }


    public static Date md_date(String dateString) {
        try {
            // 设置中国地区Locale
            Locale chinaLocale = Locale.SIMPLIFIED_CHINESE;
            // 获取当前年份
            Calendar calendar = Calendar.getInstance();
            int currentYear = calendar.get(Calendar.YEAR);
            // 构建完整的日期字符串
            dateString = currentYear+"年" + dateString;
            // 创建日期格式化对象
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日", chinaLocale);
            // 解析日期字符串为Date对象
            return dateFormat.parse(dateString);
        } catch (ParseException e) {
           throw new BadRequestException(dateString+"日期格式错误");
        }
    }


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

        return DFY_MD.format(localDateTime);
    }

    public static String dateYmd(Date date) {
        return ymd.format(date);
    }

    //按周天生成批次
    public static String dateYmdz() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        String z="01-07";
        if(day<=7){
            z="01-07";
        }else if(day>7 && day<=14){
            z="08-14";
        }else if(day>14 && day<=21){
            z="15-21";
        }else if(day>21 && day<=28){
            z="22-28";
        }else if(day>28){
            z="29-31";
        }
        if(month<=9){
            return  year+"-0"+month+"-"+z;
        }else{
            return  year+"-"+month+"-"+z;
        }
    }

    public static String formatChageDay(Date date, String type, int value) {
        Calendar cal = new java.util.GregorianCalendar();
        cal.setTime(date);
        if (type.equals("DAY")) {
            cal.add(Calendar.DATE , value);
        }
        if (type.equals("HOUR")) {
            cal.add(Calendar.HOUR, value);
        }
        if (type.equals("MINUTE")) {
            cal.add(Calendar.MINUTE, value);
        }
        if (type.equals("SECOND")) {
            cal.add(Calendar.SECOND, value);
        }
        return ymd.format(cal.getTime());
    }

    public static Timestamp getBatchTime(int value,Date date) {
        Calendar cal = new java.util.GregorianCalendar();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY,8);
        cal.set(Calendar.MINUTE,30);
        cal.set(Calendar.MILLISECOND,0);
        cal.add(Calendar.MINUTE, value);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int minute = cal.get(Calendar.MINUTE);
        //11：30-12：30休息
        if(hour>11||(hour==11&&minute>=30)){
            cal.add(Calendar.HOUR, 1);
        }
//        //17：30-18：30休息
//        hour = cal.get(Calendar.HOUR_OF_DAY);
//        if(hour>17||(hour==17&&minute>=30)){
//            cal.add(Calendar.HOUR, 1);
//        }
        return new Timestamp(cal.getTime().getTime());
    }

    /**
     * 字符串转 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));
    }

    /**
     *获取两个字符串计算出小时
     * @param
     * @return
     */
    public static long hoursBetween(String startDateTimeStr,String endDateTimeStr) {
        // 解析日期时间字符串为 LocalDateTime 对象
        LocalDateTime startDateTime = LocalDateTime.parse(startDateTimeStr, DFY_MD_HM);
        LocalDateTime endDateTime = LocalDateTime.parse(endDateTimeStr, DFY_MD_HM);
        // 计算时间差
        Duration duration = Duration.between(startDateTime, endDateTime);
        long hours = duration.toHours(); // 将时间差转换为小时
        return hours;
    }

    /**
     *比较两个日期大小
     * @param
     * @return
     */
    public static int dateComparison (Date date1,Date date2) {
        int comparison = date1.compareTo(date2);
        return comparison;
    }
    /**
     * 将yyyyMMdd格式的字符串转换为Timestamp
     * 转换后时间默认为00:00:00.0
     *
     * @param dateStr 输入字符串，格式必须为yyyyMMdd（如"20250704"）
     * @return 转换后的Timestamp，若解析失败返回null
     * @throws DateTimeParseException 当输入字符串格式不符合yyyyMMdd时抛出
     */
    public static Timestamp stringToTimestamp(String dateStr) throws DateTimeParseException {
        // 校验输入参数
        if (dateStr == null || dateStr.trim().isEmpty()) {
            throw new IllegalArgumentException("输入字符串不能为空");
        }

        // 定义日期格式（严格匹配yyyyMMdd）
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");

        try {
            // 解析为LocalDate（仅日期）
            LocalDate localDate = LocalDate.parse(dateStr.trim(), formatter);
            // 补充时间为00:00:00，转换为LocalDateTime
            LocalDateTime localDateTime = localDate.atStartOfDay();
            // 转换为Timestamp
            return Timestamp.valueOf(localDateTime);
        } catch (DateTimeParseException e) {
            // 抛出格式不匹配异常，包含具体错误信息
            throw new DateTimeParseException("字符串格式错误，需符合yyyyMMdd（如20250704），错误内容：" + dateStr, dateStr, e.getErrorIndex(), e);
        }
    }
    /**
     * 获取当前时间并格式化为 yyyyMMddhhmmss 格式（12小时制）
     * 若需24小时制，将格式改为 "yyyyMMddHHmmss"（HH表示24小时制）
     *
     * @return 格式化后的时间字符串（如20251117034522，对应2025-11-17 03:45:22）
     */
    public static String getCurrentTimeAsString() {
        // 1. 获取当前时间（包含日期和时间）
        LocalDateTime now = LocalDateTime.now();

        // 2. 定义格式化模板：yyyyMMddhhmmss（12小时制）
        // 说明：
        // - yyyy：四位年份（如2025）
        // - MM：两位月份（01-12）
        // - dd：两位日期（01-31）
        // - hh：12小时制小时（01-12）
        // - mm：两位分钟（00-59）
        // - ss：两位秒数（00-59）
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

        // 3. 格式化当前时间并返回
        return now.format(formatter);
    }
}
