package com.sifang.modules.sunshine.handler;

import com.google.common.collect.Maps;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.order.utils.excelExt.handler.ExcelAbstractHandler;
import com.sifang.modules.sunshine.SystemSetting.form.AddTrader;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.sys.util.SqlBuilder;
import org.apache.commons.lang.StringUtils;

import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Pattern;

public class TraderExcelImportHandler extends ExcelAbstractHandler {
    private List<Map<String,Object>> errorRowData=new ArrayList<>();
    public List<Map<String, Object>> getErrorRowData() {
        return errorRowData;
    }

    private List<AddTrader> retList = new ArrayList<>();

    private List<String> traderNameList = new ArrayList<>();
    private List<String> loginNameList = new ArrayList<>();

    private List<String> loginMobileList = new ArrayList<>();

    boolean checkFlag;

    static Pattern pattern = Pattern.compile("(-?\\d+\\.?\\d*)[Ee]{1}[\\+-]?[0-9]*");
    static DecimalFormat ds = new DecimalFormat("0");
    /**
     * 如果返回false，则表示终止继续遍历Excel,截至到当前的行数
     */
    @SuppressWarnings("unchecked")
    @Override
    public Boolean handler(Map<String, Object> rowData, int rowIndex) {
        AddTrader addTrader = transToModel(rowData);
        retList.add(addTrader);
        return true;
    }

    private AddTrader transToModel(Map<String, Object> rowData){
        AddTrader addTrader = new AddTrader();
        addTrader.setTraderName(String.valueOf(rowData.get("1")));
        addTrader.setLoginName(String.valueOf(rowData.get("2")));
        addTrader.setPassword(String.valueOf(rowData.get("3")));
        addTrader.setUserName(String.valueOf(rowData.get("4")));
        addTrader.setTelephone(zhMobile(String.valueOf(rowData.get("5"))));
        addTrader.setProvince(String.valueOf(rowData.get("6")));
        addTrader.setCity(String.valueOf(rowData.get("7")));
        addTrader.setArea(String.valueOf(rowData.get("8")));
        addTrader.setAddress(String.valueOf(rowData.get("9")));
        addTrader.setRemarks(String.valueOf(rowData.get("10")));
        return addTrader;
    }

    //匹配模板
    public boolean matchTemplate(Map<String, Object> rowData){
        List<String> titles = new ArrayList<>();
        titles.add("名称");
        titles.add("登录账号");
        titles.add("登录密码");
        titles.add("联系人");
        titles.add("联系电话");
        titles.add("省");
        titles.add("市");
        titles.add("区");
        titles.add("详细地址");
        titles.add("备注");

        return checkTemplate(titles, rowData);
    }

    public boolean checkTemplate(List<String> titles, Map<String, Object> rowData){
        boolean ret = true;
        for (int i = 0; i < titles.size(); i++) {
            String title = String.valueOf(rowData.get(String.valueOf(i + 1)));
            if (!titles.get(i).equals(title.trim())) {
                //模板不匹配
                ret = false;
                break;
            }
        }
        return ret;
    }

    public String  zhMobile(String mobile){
        if (isENum(mobile)) {
            String sPhone = ds.format(Double.parseDouble(mobile)).trim();
            System.out.println(sPhone);
            return sPhone;
        }
        return mobile;
    }

    static boolean isENum(String input) {//判断输入字符串是否为科学计数法
        return pattern.matcher(input).matches();
    }

    /**
     * 如果返回false，则表示终止继续遍历Excel,截至到当前的行数
     */
    //验证Excel模板
    @SuppressWarnings("unchecked")
    @Override
    public Boolean checkExcel(Map<String, Object> rowData, int rowIndex) {
        Map<String, Object> result = (Map<String, Object>) this.getHandlerResult();
        if (result == null) {
            result = Maps.newHashMap();
            this.setHandlerResult(result);
        }
        // check excel title match
        if (rowIndex == (getStartRow() - 1)) {//如果是title列，则直接检查是否同一个Excel模板,包括顺序和列名匹配
            boolean match = matchTemplate(rowData);
            boolean flag = true;
            if(!match){
                result.put("TemplateError", "<p>模板不匹配</p>");
                flag = false;
            }
            return flag;
        }

        if (rowIndex > (getStartRow() - 1)) {
            checkFlag = true;
            if (rowData.get("1") == null || StringUtils.isBlank(String.valueOf(rowData.get("1")))) {
                appendErrorDetail("<p>第" + (rowIndex + 1) + "行数据：代理商名称为空" + "</p>");
                return true;
            }
            if (traderNameList.contains(String.valueOf(rowData.get("1")))) {
                appendErrorDetail("<p>第" + (rowIndex + 1) + "行数据：代理商名称重复" + "</p>");
                return true;
            }
            traderNameList.add(String.valueOf(rowData.get("1")));
            if (rowData.get("2") == null || StringUtils.isBlank(String.valueOf(rowData.get("2")))) {
                appendErrorDetail("<p>第" + (rowIndex + 1) + "行数据：登录账号为空" + "</p>");
                return true;
            }
            if (loginNameList.contains(String.valueOf(rowData.get("2")))) {
                appendErrorDetail("<p>第" + (rowIndex + 1) + "行数据：登录账号重复" + "</p>");
                return true;
            }
            loginNameList.add(String.valueOf(rowData.get("2")));
            if (rowData.get("3") == null || StringUtils.isBlank(String.valueOf(rowData.get("3")))) {
                appendErrorDetail("<p>第" + (rowIndex + 1) + "行数据：登录密码为空" + "</p>");
                return true;
            }
            if (rowData.get("4") == null || StringUtils.isBlank(String.valueOf(rowData.get("4")))) {
                appendErrorDetail("<p>第" + (rowIndex + 1) + "行数据：联系人为空" + "</p>");
                return true;
            }
            if (rowData.get("5") == null || StringUtils.isBlank(String.valueOf(rowData.get("5")))) {
                appendErrorDetail("<p>第" + (rowIndex + 1) + "行数据：联系电话为空" + "</p>");
                return true;
            }
            String mobile = zhMobile(String.valueOf(rowData.get("5")));
            if (loginMobileList.contains(mobile)) {
                appendErrorDetail("<p>第" + (rowIndex + 1) + "行数据：联系电话重复" + "</p>");
                return true;
            }
            loginMobileList.add(mobile);
            if (rowData.get("6") == null || StringUtils.isBlank(String.valueOf(rowData.get("6")))) {
                appendErrorDetail("<p>第" + (rowIndex + 1) + "行数据：省为空" + "</p>");
                return true;
            }
            if (rowData.get("7") == null || StringUtils.isBlank(String.valueOf(rowData.get("7")))) {
                appendErrorDetail("<p>第" + (rowIndex + 1) + "行数据：市为空" + "</p>");
                return true;
            }
            if (rowData.get("8") == null || StringUtils.isBlank(String.valueOf(rowData.get("8")))) {
                appendErrorDetail("<p>第" + (rowIndex + 1) + "行数据：区为空" + "</p>");
                return true;
            }
            if (rowData.get("9") == null || StringUtils.isBlank(String.valueOf(rowData.get("9")))) {
                appendErrorDetail("<p>第" + (rowIndex + 1) + "行数据：详细地址为空" + "</p>");
                return true;
            }
            retList.add(transToModel(rowData));
            if (isLastRow(rowIndex)) {
                checkTraderNameExists(retList);
                checkLoginNameExists(retList);
            }
            if (rowIndex > getMaxRows()) {
                result.put("overLimit", "overLimit");
                return false;
            }
        }

        return true;
    }

    private void checkTraderNameExists(List<AddTrader> traders){
        Set<String> traderNames = new HashSet<>();
        for(AddTrader trader: traders){
            traderNames.add(trader.getTraderName());
        }
        if (!traderNames.isEmpty()) {
            SqlBuilder builder = new SqlBuilder();
            builder.line("select name ")
                    .line("from crm_trader")
                    .line("where status='0' and name in (" + StringUtil.joinInSql(traderNames.toArray(new String[traderNames.size()])) + ") ");
            List<String> existsNames = getNames(Db.find(builder.build()), "name");
            if (!existsNames.isEmpty()) {
                for (int i = 0; i < traders.size(); i++) {
                    AddTrader trader = traders.get(i);
                    if (existsNames.contains(trader.getTraderName())) {
                        appendErrorDetail("<p>第" + (i + 1) + "行数据：代理商名称已存在" + "</p>");
                    }
                }
            }
        }
    }

    private void checkLoginNameExists(List<AddTrader> traders){
        Set<String> loginNames = new HashSet<>();
        for(AddTrader trader: traders){
            loginNames.add(trader.getLoginName());
        }
        if (!loginNames.isEmpty()) {
            SqlBuilder builder = new SqlBuilder();
            builder.line("select login_name ")
                    .line("from sys_user")
                    .line("where status='0' and login_name in (" + StringUtil.joinInSql(loginNames.toArray(new String[loginNames.size()])) + ") ");
            List<String> existsNames = getNames(Db.find(builder.build()), "login_name");
            if (!existsNames.isEmpty()) {
                for (int i = 0; i < traders.size(); i++) {
                    AddTrader trader = traders.get(i);
                    if (existsNames.contains(trader.getLoginName())) {
                        appendErrorDetail("<p>第" + (i + 1) + "行数据：登录账号已存在" + "</p>");
                    }
                }
            }
        }
    }

    private List<String> getNames(List<Record> records, String column){
        List<String> names = new ArrayList<>();
        for(Record record: records){
            names.add(record.getStr(column));
        }
        return names;
    }

    private boolean isLastRow(int rowIndex) {
        return rowIndex >= totalRow - 1;
    }

    public List<AddTrader> getRetList() {
        return retList;
    }

    public void setRetList(List<AddTrader> retList) {
        this.retList = retList;
    }

    public boolean isCheckFlag() {
        return checkFlag;
    }

    public void setCheckFlag(boolean checkFlag) {
        this.checkFlag = checkFlag;
    }
}
