package com.qmth.teachcloud.common.util;

import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description: 转换工具类
 * @Author: CaoZixuan
 * @Date: 2021-04-14
 */

@Component
public class ConvertUtil {

    @Resource
    RedisTemplate<String, Object> redisTemplate;

    // inputStream转outputStream
    public static ByteArrayOutputStream parse(final InputStream in) throws Exception {
        final ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        int ch;
        while ((ch = in.read()) != -1) {
            swapStream.write(ch);
        }
        return swapStream;
    }

    // outputStream转inputStream
    public static ByteArrayInputStream parse(final OutputStream out) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos = (ByteArrayOutputStream) out;
        return new ByteArrayInputStream(baos.toByteArray());
    }

    public static void inputStream2File(InputStream is, File file) throws IOException {
        OutputStream os = null;
        try {
            os = new FileOutputStream(file);
            int len = 0;
            byte[] buffer = new byte[8192];

            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
        } finally {
            os.close();
            is.close();
        }
    }

    /**
     * 转换，解析时间
     *
     * @param date 日期(考试日期，必须是同一天     example: 2021-04-13)
     * @param time 时间(考试时间，必须使用‘-’隔开  example: 18:00-20:00)
     * @return 开始时间和结束时间键值对(" startTime " : 1618308000000, " endTime " : 1618315200000)
     */
    public static Map<String, Object> analyzeStartAndEndTime(String date, String time) {
        time = time.replaceAll(" ", ""); // 去掉所有空格
        String[] arr = time.split("-");
        if (arr.length != 2) {
            // 不能使用'-'拆分成两个时间的报错
            throw ExceptionResultEnum.ERROR.exception("提供的时间格式异常 时间 : " + time + " 应该使用如下的格式 '考试时间' ：18:00-20:00");
        }
        String startTimeStr = date + " " + arr[0];
        String endTimeStr = date + " " + arr[1];
        if (Objects.isNull(DateDisposeUtils.parseDate(startTimeStr)) || Objects.isNull(DateDisposeUtils.parseDate(endTimeStr))){
            throw ExceptionResultEnum.ERROR.exception("提供的日期时间格式异常（请使用'-'隔开） \n【考试日期】 : " + date + "\n应该使用如下的格式 '考试日期' ：2021-09-01");
        }
        long startTime = DateDisposeUtils.parseDate(startTimeStr).getTime();
        long endTime = DateDisposeUtils.parseDate(endTimeStr).getTime();
        if (startTime >= endTime) {
            System.out.println("开始时间要小于结束时间 时间： " + time);
        }

        Map<String, Object> timeMap = new HashMap<>();
        timeMap.put("startTime", startTime);
        timeMap.put("endTime", endTime);
        return timeMap;
    }

    /**
     * 根据开始时间和结束时间解析日期和时间
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 键值对
     */
    public static Map<String, Object> analyzeDateAndTime(Long startTime, Long endTime) {
        String tmpDateStart;
        String tmpDateEnd;
        String tmpTimeStart;
        String tmpTimeEnd;
        String date;
        String time;


        Map<String, Object> map = new HashMap<>();

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(startTime));
        tmpDateStart = (new SimpleDateFormat("yyyy-MM-dd")).format(calendar.getTime());
        tmpTimeStart = (new SimpleDateFormat("HH:mm:ss")).format(calendar.getTime());

        calendar.setTime(new Date(endTime));
        tmpDateEnd = (new SimpleDateFormat("yyyy-MM-dd")).format(calendar.getTime());
        tmpTimeEnd = (new SimpleDateFormat("HH:mm:ss")).format(calendar.getTime());

        if (!tmpDateStart.equals(tmpDateEnd)) {
            throw ExceptionResultEnum.ERROR.exception("开始时间和结束时间不在同一天");
        }

        date = tmpDateStart;
        time = tmpTimeStart + " - " + tmpTimeEnd;
        map.put("date", date);
        map.put("time", time);

        return map;
    }


    /**
     * 获取递增序列号
     *
     * @param prefix 前缀
     * @param model  模块
     * @param digit  补齐位数
     * @return 序列号
     */
    public String getIncre(String prefix, String model, int digit) {
        StringBuilder temp = new StringBuilder();
        for (int i = 0; i < digit; i++) {
            temp.append("0");
        }
        //序列号前缀加特定标识，如系统模块名之类的 防止重复
        String key = model + prefix;
        String increResult = "";
        try {
            //如果该key不存在 会自动创建，值为第二个参数delta
            //最终调用的还是jedis的incrBy(byte[] key, long value)方法
            RedisAtomicLong counter = new RedisAtomicLong(key, Objects.requireNonNull(redisTemplate.getConnectionFactory()));
            Long increment = counter.incrementAndGet();
            //不足补位
            DecimalFormat df = new DecimalFormat(temp.toString());
            increResult = prefix + df.format(increment);
        } catch (Exception e) {
            // TODO: 2021/4/16  
            System.out.println("获取序列号失败");
            /*这里可以根据需求手动生成一个不重复的单号，
             * */
        }
        return increResult;
    }

    /**
     * 解析excel单元格类型
     *
     * @param cell 单元格
     * @return 转换成字符串后的值
     */
    public static String analyzeExcelCellValue(Cell cell) {
        String cellValue;
        CellType cellType = cell.getCellTypeEnum();
        switch (cellType) {
            case NUMERIC:
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    SimpleDateFormat sdf;
                    // 验证short值
                    if (cell.getCellStyle().getDataFormat() == 14) {
                        sdf = new SimpleDateFormat("yyyy/MM/dd");
                    } else if (cell.getCellStyle().getDataFormat() == 21) {
                        sdf = new SimpleDateFormat("HH:mm:ss");
                    } else if (cell.getCellStyle().getDataFormat() == 22) {
                        sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                    } else {
                        throw new RuntimeException("日期格式错误!!!");
                    }
                    Date date = cell.getDateCellValue();
                    cellValue = sdf.format(date);
                } else {//处理数值格式
                    cell.setCellType(CellType.STRING);
                    cellValue = String.valueOf(cell.getRichStringCellValue().getString());
                }
                break;
            case STRING:
                cellValue = String.valueOf(cell.getStringCellValue());
                break;
            case BOOLEAN:
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case FORMULA:
                cellValue = String.valueOf(cell.getCellFormula());
                break;
            case BLANK:
                cellValue = null;
                break;
            case ERROR:
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知类型";
                break;
        }
        return cellValue;
    }

    public static void delFolder(String folderPath) {
        try {
            delAllFile(folderPath); //删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            File myFilePath = new File(filePath);
            myFilePath.delete(); //删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return;
        }
        if (!file.isDirectory()) {
            return;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < Objects.requireNonNull(tempList).length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + tempList[i]);//先删除文件夹里面的文件
                delFolder(path + "/" + tempList[i]);//再删除空文件夹
                flag = true;
            }
        }
    }

    public File saveLocal(InputStream inputStream, String dirPath) throws IOException {
        File desFile = new File(dirPath);
        if (!desFile.getParentFile().exists()) {
            desFile.getParentFile().mkdirs(); //目标文件目录不存在的话需要创建目录
        }
        byte[] bytes = new byte[1024]; // 开辟一个拷贝缓冲区
        OutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(desFile);
            int length;
            while ((length = inputStream.read(bytes)) != -1) { //当读到尽头后，返回值为-1这个时候停止输出，拷贝结束
                outputStream.write(bytes, 0, length);
            }
            return desFile;
        } catch (Exception e) {
            throw e;
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }

    /**
     * 判断里面参数只要有一个为空 就是true 全部不为空时 false
     * @param strArr 字符串组
     * @return 全部有值 - false；任意一个为空 - true
     */
    public static boolean strAnyEmpty(String... strArr){
        if (strArr.length == 0){
            return true;
        }else {
            for (String str : strArr) {
                if (!SystemConstant.strNotNull(str)){
                    return true;
                }
            }
            return false;
        }
    }
}
