package com.ximai.common.utils.excel.converter;

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.ximai.common.exception.ServiceException;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>Title: LocalDateTimeConverter</p>
 * <p>Description: 时间转换</p>
 *
 * @author xi.feng
 * @version V1.0
 */
public class LocalDateTimeConverter implements Converter<LocalDateTime> {
    private static final String PATTERN = "yyyy-MM-dd HH:mm:ss";
    private static final String PATTERN1 = "yyyy.M.d HH:mm:ss";
    private static final String PATTERN2 = "yyyy/M/d HH:mm:ss";

    @Override
    public Class<?> supportJavaTypeKey() {
        return LocalDateTime.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    @Override
    public LocalDateTime convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        if (cellData.getType().equals(CellDataTypeEnum.NUMBER)) {
            BigDecimal bd = cellData.getNumberValue();
            //如果是数字 小于0则 返回
            int days = bd.intValue();//天数
            int mills = (int) Math.round(bd.subtract(new BigDecimal(days)).doubleValue() * 24 * 3600);
            //获取时间
            Calendar c = Calendar.getInstance();
            c.set(1900, 0, 1);
            c.add(Calendar.DATE, days - 2);
            int hour = mills / 3600;
            int minute = (mills - hour * 3600) / 60;
            int second = mills - hour * 3600 - minute * 60;
            c.set(Calendar.HOUR_OF_DAY, hour);
            c.set(Calendar.MINUTE, minute);
            c.set(Calendar.SECOND, second);

            Date d = c.getTime();//Date
            ZoneId zoneId = ZoneId.systemDefault();
            LocalDateTime localDateTime = LocalDateTime.ofInstant(d.toInstant(), zoneId);
            return localDateTime;
        }else if (cellData.getType().equals(CellDataTypeEnum.STRING)){
            //自动补位，2023=>2023-01-01 00:00:00，2023-05 => 2023-05-01 00:00:00，2023-05-01 => 2023-05-01 00:00:00，2023-05-01 00:00，2023-05-01 => 2023-05-01 00:00:00
            String dateStr = cellData.getStringValue();
            //只有年份
            if(dateStr.length()==4 && dateStr.matches("\\d\\d\\d\\d")){
                dateStr += "-01-01 00:00:00";
            }
            //包含”年/月“
            if(dateStr.length()==6||dateStr.length()==7){
                Matcher match = Pattern.compile("\\d{4}([-./])\\d\\d?").matcher(dateStr);
                if(match.find()){
                    String separator = match.group(1);
                    dateStr += separator + "01 00:00:00";
                }
            }
            //包含”年/月/日“
            if(dateStr.length()==10||dateStr.length()==9||dateStr.length()==8){
                dateStr += " 00:00:00";
            }
            //包含“年/月日 时:分”
            if(dateStr.length()==16||dateStr.length()==15||dateStr.length()==14){
                dateStr += ":00";
            }
            try {
                return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(PATTERN));
            } catch (Exception exception) {
            }
            try {
                return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(PATTERN1));
            } catch (Exception exception) {
            }
            try {
                return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(PATTERN2));
            } catch (Exception exception) {
            }
            throw new ServiceException("不能解析的日期时间格式" + dateStr);
        }else {
            return null;
        }
    }

    @Override
    public WriteCellData<?> convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        return new WriteCellData(value.format(DateTimeFormatter.ofPattern(PATTERN)));
    }
}