package com.zcloud.common.utils;

import org.apache.commons.lang.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;

/**
 * 说明：TODO
 * 作者：wangxuan
 * 官网：www.zcloudchina.com
 */
public class PaperTextValid {
    private static Pattern pattern = Pattern.compile("[0-9]*");

    /**
     * @Description: errorMsg 错误信息，sheet，行，操作项，单选名，列名，单选多选 ture 或 填空，判断 false
     * @Author: dearLin
     * @Date: 2023/3/15/015 9:31
     * @Param: [java.lang.StringBuilder, int, int, com.zcloud.entity.PageData, java.lang.String[], java.util.HashMap, boolean] [errorMsg, finalI, i, x, choice, column, cOrb]
     * @Return: void
     */
    public static void checkValid(StringBuilder errorMsg, int sheetNum, Map<Object, Object> x, String[] choice, HashMap<Integer, String> column, boolean cOrb) {

        for (int j = 0; j < choice.length; j++) {
            String item = (String) x.get("var" + j);

            if (StringUtils.isEmpty(item)) {
                addErrorMsg(errorMsg, sheetNum, (String) x.get("rowNum"), column.get(j), "不能为空");
                continue;
            }
            // 校验每一项长度不可超过254
            if (item.length() > 254) {
                addErrorMsg(errorMsg, sheetNum, (String) x.get("rowNum"), column.get(j), "长度超过254");
            }
            // 分值校验
            if ("分值".equals(column.get(j))) {
                if (!isNumeric(item)) {
                    addErrorMsg(errorMsg, sheetNum, (String) x.get("rowNum"), column.get(j), "分值只能是小数与整数");
                }
            }

            // 单选多选
            if (cOrb) {
                if ((j == 7 || j == 8) && item.equals("NO_Label_Type")) {
                    //标签类型
                    addErrorMsg(errorMsg, sheetNum, (String) x.get("rowNum"), column.get(j), "未找到,请与数据字典的标签类型对应上");
                }
                if ("单选答案".equals(column.get(j))) {
                    //校验答案位数
                    if (item.length() >= 2) {
                        addErrorMsg(errorMsg, sheetNum, (String) x.get("rowNum"), column.get(j), "该题为单选，答案位数不对");
                    }
                    //校验答案是否为 A, B, C, D 之一
                    if (!"A".equals(item) && !"B".equals(item) && !"C".equals(item) && !"D".equals(item)) {
                        addErrorMsg(errorMsg, sheetNum, (String) x.get("rowNum"), column.get(j), "单选答案只能是 A, B, C, D 中的一个");
                    }
                }
                if ("多选答案".equals(column.get(j))) {
                    //校验答案位数
                    if (item.length() < 1) {
                        addErrorMsg(errorMsg, sheetNum, (String) x.get("rowNum"), column.get(j), "该题为多选，答案位数不对");
                    }
                    //校验答案是否只包含 A, B, C, D
                    if (!item.matches("[ABCD]+")) {
                        addErrorMsg(errorMsg, sheetNum, (String) x.get("rowNum"), column.get(j), "多选答案只能包含 A, B, C, D 中的一个或多个组合");
                    }
                    //检查多选答案中是否有重复项
                    char[] chars = item.toCharArray();
                    Set<Character> charSet = new HashSet<>();
                    for (char c : chars) {
                        charSet.add(c);
                    }
                    if (charSet.size() != item.length()) {
                        addErrorMsg(errorMsg, sheetNum, (String) x.get("rowNum"), column.get(j), "多选答案中不能有重复选项");
                    }
                    // 对多选答案进行排序
                    List<Character> sortedChars = new ArrayList<>(charSet);
                    Collections.sort(sortedChars);
                    StringBuilder sortedItem = new StringBuilder();
                    for (Character c : sortedChars) {
                        sortedItem.append(c);
                    }
                    // 如果排序后的答案与原答案不同，则添加错误信息
                    if (!sortedItem.toString().equals(item)) {
                        addErrorMsg(errorMsg, sheetNum, (String) x.get("rowNum"), column.get(j), "多选答案未按 A, B, C, D 顺序排序");
                    }
                }
                x.put(choice[j], item);

            } else {
                // 判断，填空
                if ((j == 3 || j == 4) && item.equals("NO_Label_Type")) {
                    //标签类型
                    addErrorMsg(errorMsg, sheetNum, (String) x.get("rowNum"), column.get(j), "未找到,请与数据字典的标签类型对应上");
                }
                if ("判断答案".equals(column.get(j))) {
                    if ("T".equals(item) || "F".equals(item)) {
                        if ("T".equals(item)) {
                            x.put("ANSWER", "A");
                        } else {
                            x.put("ANSWER", "B");
                        }
                    } else {
                        addErrorMsg(errorMsg, sheetNum, (String) x.get("rowNum"), column.get(j), "判断答案只能填写T或F");
                    }
                } else {
                    x.put(choice[j], item);
                }
            }

        }
    }

    public static boolean isNumeric(String str) {
        if (StringUtils.isEmpty(str)) {
            return false;
        }
        if (str.indexOf(".") > 0) {
            //判断是否有小数点
            if (str.indexOf(".") == str.lastIndexOf(".") && str.split("\\.").length == 2) {
                //判断是否只有一个小数点
                return pattern.matcher(str.replace(".", "")).matches();
            } else {
                return false;
            }
        } else {
            return pattern.matcher(str).matches();
        }
    }

    private static void addErrorMsg(StringBuilder errorMsg, int sheetNum, String i, String describe, String reason) {
        String sheetNAME = "";
        switch (sheetNum) {
            case 0:
                sheetNAME = "单选题";
                break;
            case 1:
                sheetNAME = "多选题";
                break;
            case 2:
                sheetNAME = "判断题";
                break;
            case 3:
                sheetNAME = "填空题";
                break;
        }
        errorMsg.append("[" + sheetNAME + "]sheet:" + "行号" + i + "," + describe + reason + "，导入失败\n");
    }

    public static boolean betweenOn(LocalDateTime otherStartTime, LocalDateTime otherEndTime, LocalDateTime currStartTime, LocalDateTime currEndTime) {
        if (otherEndTime.isEqual(currStartTime)) {
            return true;
        }
        if (otherStartTime.isEqual(currEndTime)) {
            return true;
        }
        if (otherStartTime.isAfter(currStartTime)) {
            // 其他日期段开始日期大于当前日期段开始日日期，那么其他日期段开始日期小于等于当前日期段结束日则为重复
            return otherStartTime.isBefore(currEndTime);

        } else if (otherStartTime.isBefore(currStartTime)) {
            // 其他日期段开始日期小于当前开始日期，那么其他日期段结束日期大于等于当前日期段开始日期则为重复
            return otherEndTime.isAfter(currStartTime);
        } else {
            // 其他日期段开始日期=当前日期段开始日期，一定重复
            return true;
        }
    }
}
