package com.gci.boot.annotation.importHandler;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.stereotype.Component;

import cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHandlerResult;
import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

@Component
public class MyExcelVerifyHandler<T> implements IExcelVerifyHandler<T> {

    private final ThreadLocal<List<T>> threadLocal = new ThreadLocal<>();
    private List<ExcelTypeHandler> list;
    private Map<String, List<ExcelTypeHandler>> map;

    public ThreadLocal<List<T>> getThreadLocal() {
        return threadLocal;
    }

    public List<ExcelTypeHandler> getList() {
        return list;
    }

    public void setList(List<ExcelTypeHandler> list) {
        this.list = list;
        if (!list.isEmpty()) {
            this.map = list.stream().collect(Collectors.groupingBy(ExcelTypeHandler::getType));
        }
    }

    @Override
    public ExcelVerifyHandlerResult verifyHandler(T t) {
        Class<?> aClass = t.getClass();

        return getExcelVerifyHandlerResult(t);

    }

    private ExcelVerifyHandlerResult getExcelVerifyHandlerResult(T t) {

        List<T> objects = threadLocal.get();
        if (objects == null) {
            objects = new ArrayList<>();
        }
        ArrayList<String> errorMsg = new ArrayList<>();

        List<ExcelTypeHandler> first = map.get("1");
        if (first != null) {
            for (ExcelTypeHandler excelTypeHandler : first) {
                // 获取需要检验的字段
                List<String> fields = excelTypeHandler.getFields();

                // 获取数据
                List<?> record = excelTypeHandler.getRecord();

                // 是否需要共同校验
                boolean needAll = excelTypeHandler.isNeedAll();
                if (record != null) {
                    boolean recordAnyMatch = record.stream().anyMatch(i -> {
                        if (needAll) {
                            // 共同校验数据
                            boolean allMatch = true;
                            for (String field : fields) {
                                boolean equal = ObjectUtil.equal(BeanUtil.getFieldValue(i, field),
                                    BeanUtil.getFieldValue(t, field));
                                if (!equal) {
                                    allMatch = false;
                                }
                            }
                            return allMatch;
                        } else {
                            for (String field : fields) {
                                boolean equal = ObjectUtil.equal(BeanUtil.getFieldValue(i, field),
                                    BeanUtil.getFieldValue(t, field));
                                if (equal) {
                                    return true;
                                }
                            }
                            return false;
                        }
                    });

                    if (recordAnyMatch) {
                        errorMsg.add(excelTypeHandler.getErrorMsg());
                    }
                }

                // excel内校验
                List<String> inExcel = new ArrayList<>();
                objects.forEach(e -> {
                    if (needAll) {
                        // 共同校验数据
                        boolean allMatch = true;
                        for (String field : fields) {
                            boolean equal =
                                ObjectUtil.equal(BeanUtil.getFieldValue(e, field), BeanUtil.getFieldValue(t, field));
                            if (!equal) {
                                allMatch = false;
                            }
                        }
                        if (allMatch) {
                            inExcel.add("与原始excel" + BeanUtil.getFieldValue(e, "rowNum") + "行"
                                + excelTypeHandler.getErrorMsg());
                        }
                    } else {
                        for (String field : fields) {
                            boolean equal =
                                ObjectUtil.equal(BeanUtil.getFieldValue(e, field), BeanUtil.getFieldValue(t, field));
                            if (equal) {
                                inExcel.add("与原始excel" + BeanUtil.getFieldValue(e, "rowNum") + "行"
                                    + excelTypeHandler.getErrorMsg());
                            }
                        }
                    }
                });
                if (!inExcel.isEmpty()) {
                    errorMsg.addAll(inExcel);
                }
            }
        }

        objects.add(t);
        threadLocal.set(objects);

        List<ExcelTypeHandler> second = map.get("2");
        if (second != null) {
            for (ExcelTypeHandler excelTypeHandler : second) {
                // 需要校验的字段
                List<String> fields = excelTypeHandler.getFields();
                // 获取数据
                List<?> record = excelTypeHandler.getRecord();
                for (String field : fields) {
                    Object fieldValue = BeanUtil.getFieldValue(t, field);
                    if (ObjectUtil.isNotEmpty(fieldValue)) {
                        boolean contains = record.contains(fieldValue);
                        // 不包含就报错
                        if (!contains) {
                            errorMsg.add(excelTypeHandler.getErrorMsg());
                        }
                    }
                }
            }
        }
        List<ExcelTypeHandler> third = map.get("3");
        if (third != null) {
            for (ExcelTypeHandler excelTypeHandler : third) {
                List<String> fields = excelTypeHandler.getFields();
                Map<String, Object> specifiedValueMap = excelTypeHandler.getSpecifiedValue();
                for (String field : fields) {
                    boolean equals = ObjectUtil.equals(BeanUtil.getFieldValue(t, field), specifiedValueMap.get(field));
                    if (equals) {
                        List<String> others = excelTypeHandler.getOthers();
                        for (String other : others) {
                            boolean empty = ObjectUtil.isEmpty(BeanUtil.getFieldValue(t, other));
                            if (empty) {
                                errorMsg.add(excelTypeHandler.getErrorMsg());
                                break;
                            }
                        }
                    }
                }
            }
        }

        if (errorMsg.isEmpty()) {
            return new ExcelVerifyHandlerResult(true);
        } else {
            errorMsg.add(0,"当前行为原始excel"+BeanUtil.getFieldValue(t, "rowNum") + "行");
            return new ExcelVerifyHandlerResult(false, StrUtil.join(";", errorMsg));
        }
    }
}
