package com.ag.ctc.domain.service;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.ag.base.*;
import com.ag.commonFace.ITariffExtService;
import com.ag.ctc.domain.pojo.Ctariff;
import com.ag.dynamicmodule.main.HotApplicationContext;
import com.ag.entity.fee.*;
import com.ag.log.OperLogServcie;
import com.ag.log.entity.LogParam;
import com.ag.util.StrUtil;
import com.ag.util.UUIDUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wb.util.WebUtil;
import lombok.extern.log4j.Log4j;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Log4j
public class TariffallService extends BaseService {

    @Autowired
    private ITariffExtService extService;
    @Autowired
    private BaseRepositoryImpl feeDao;
    @Autowired
    private DefaultBussniessImpl<TariffOperLog> bizDao;
    @Autowired
    private OperLogServcie logServcie;
    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;
    @Autowired
    private IRedisService redis;

    /**
     * 费率保存方法
     * 1。按合同id+费目id查询所有费率
     * 2。检查需要修改和删除额费率是否存在已审核的记录，存在则提示并退出
     * 3。分别处理新增（新增+新增），修改（修改+删除+新增），删除（修改+删除）三组费率列表，并写入日志表（原特殊运算符替换）
     * 4。新增和修改的费率name组合起来保存到费率主表（按费目元素排序号）
     * 5。按合同id+费目id查询所有费率
     * 6。检查是否存在重复费率。
     */
    @Transactional
    public void saveGrid(org.json.JSONObject reqParam, HttpServletResponse response, HttpServletRequest request) throws Exception {
        String tenancyId = null;
        if (reqParam.has("sys.tenancyId")) {
            tenancyId = reqParam.getString("sys.tenancyId");
        }
        String contractId = reqParam.getString("contractId");
        String itemId = reqParam.getString("itemId");
        String userName = reqParam.getString("sys.username");
        JSONObject datatable = JSON.parseArray(reqParam.getString("datatable")).getJSONObject(0);
        JSONArray createArray = JSON.parseArray(datatable.getString("create"));
        JSONArray updateArray = JSON.parseArray(datatable.getString("update"));
        JSONArray deleteArray = JSON.parseArray(datatable.getString("destroy"));

        ItemProperties query = new ItemProperties();
        query.setItemId(itemId);
        List<ItemProperties> properties = feeDao.findByEqCriteria(query, ItemProperties.class, "ITEM_ID");
        properties.sort((a, b) -> a.getDispOrder() - b.getDispOrder());
        //如果是更新，先删除再插入
        List<Tariff> addTariffs = new ArrayList<>();//新增
        List<Tariff> updTariffs = new ArrayList<>();// 修改和删除
        List<TariffRitem> addRitems = new ArrayList<>();//新增和修改
        List<TariffRitem> delRitems = new ArrayList<>();//修改和删除

        for (int i = 0; i < updateArray.size(); i++) {
            JSONObject jsonTariff = updateArray.getJSONObject(i);
            Tariff tariff = new Tariff();
            generateTariff(jsonTariff, tariff);
            tariff.setUpdatedBy(userName);
            tariff.setUpdatedOn(new Date());
            tariff.setTenancyId(tenancyId);
            tariff.setChargingId(itemId);
            tariff.setContractId(contractId);
            Map<String, String> operMap = extService.getSpecialOperChar(tariff.getId());
            updTariffs.add(tariff);//费率修改
            TariffRitem ritem = new TariffRitem();
            ritem.setRuleId(tariff.getId());
            delRitems.add(ritem);//条件删除
            //一条费率的多个费率条件处理
            List<TariffRitem> ritems = tariffRitemUpdate(jsonTariff, tariff, operMap, properties, tenancyId);
            addRitems.addAll(ritems);//条件新增
            //更新费率中的key备注与val备注
            extService.generateDescription(tariff, ritems, properties);
        }

        for (int i = 0; i < createArray.size(); i++) {
            JSONObject jsonTariff = createArray.getJSONObject(i);
            Tariff tariff = new Tariff();
            generateTariff(jsonTariff, tariff);
            tariff.setId(UUIDUtil.getUUID());
            tariff.setCreatedBy(userName);
            tariff.setCreatedOn(new Date());
            tariff.setUpdatedBy(userName);
            tariff.setUpdatedOn(new Date());
            tariff.setTenancyId(tenancyId);
            tariff.setChargingId(itemId);
            tariff.setContractId(contractId);
            addTariffs.add(tariff);//费率增加
            //一条费率的多个费率条件处理
            List<TariffRitem> ritems = tariffRitemUpdate(jsonTariff, tariff, new HashMap<>(), properties, tenancyId);
            addRitems.addAll(ritems);//条件增加
            //更新费率中的key备注与val备注
            extService.generateDescription(tariff, ritems, properties);
        }

        for (int i = 0; i < deleteArray.size(); i++) {
            JSONObject jsonTariff = deleteArray.getJSONObject(i);
            Tariff tariff = new Tariff();
            tariff.setId(jsonTariff.getString("RULE_ID"));//费率主表主键
            tariff.setDelFlag(1);
            updTariffs.add(tariff);//费率修改作废标记
            TariffRitem ritem = new TariffRitem();
            ritem.setRuleId(tariff.getId());
            delRitems.add(ritem);//条件删除
        }


        feeDao.deleteAll(delRitems, "RULE_ID");
        feeDao.updateAll(updTariffs, new String[]{"EFFECTIVE_DATE", "EXPIRED_DATE", "APPENDLX_NOTES"}, "ID");
        feeDao.saveAll(addTariffs);
        feeDao.saveAll(addRitems);
        try {
            LogParam logParam = new LogParam(reqParam, itemId, "fee", null, "datatable");
            logParam.setMenuName("费率维护");
            logServcie.saveLogGrid(logParam, response);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //检查是否存在重复费率
        extService.synDescription(contractId, itemId, tenancyId);

    }


    /**
     * 单条费率的修改-》多个费率条件的创建
     */
    private List<TariffRitem> tariffRitemUpdate(JSONObject jsonObject, Tariff tariff, Map<String, String> operMap, List<ItemProperties> properties, String tenancyId) {
        Set<Map.Entry<String, Object>> entriesdatset = jsonObject.entrySet();
        Map<String, Integer> propMap = properties.stream()
                .collect(Collectors.toMap(ItemProperties::getPropertyCode, ItemProperties::getIsShowOperator));
        //IRedisService service = (IRedisService) HotApplicationContext.getBean("redisServiceImpl");

        //费率项信息
        List<TariffRitem> tariffRitemList = new ArrayList<>();
        for (Map.Entry<String, Object> entry : entriesdatset) {
            //System.out.println(entry.getKey() + ":" + entry.getValue());
            if (StrUtil.isEmpty(entry.getValue())) {
                continue;
            }
            //RATE不在itemProperties中
            /*if (ObjectUtil.equal(entry.getKey(), "RATE")) {
                TariffRitem tariffRitem = new TariffRitem();
                generateRitem(tariffRitem, ctariff, entry, operMap);
                tariffRitemList.add(tariffRitem);
            }*/
            //key不在itemProperties中跳过
            if (!propMap.containsKey(entry.getKey())) {
                continue;
            }
            TariffRitem tariffRitem = new TariffRitem();
            generateRitem(tariffRitem, tariff, entry, operMap);
            String entryValue = entry.getValue().toString().replace("[", "").replace("]", "").replace("\"", "");
            if (StrUtil.isEmpty(entryValue.trim())) {
                continue;
            }
            if (propMap.get(entry.getKey()) == 1) {
                tariffRitem.setCompareVal(entryValue);
                //tariffRitem.setCompareName(Convert.toStr(entryValue));
            } else {
                tariffRitem.setCompareVal(entryValue);
                tariffRitem.setCompareName(redis.getTargetName(entry.getKey(), entryValue, tenancyId));
            }
            tariffRitemList.add(tariffRitem);
        }
        for (TariffRitem ritem : tariffRitemList) {
            for (ItemProperties propertie : properties) {
                if (ObjectUtil.equal(propertie.getPropertyCode(), ritem.getKeyName())) {
                    ritem.setComname1(propertie.getPropertyName());
                    break;
                }
            }
        }
        return tariffRitemList;
    }

    private void generateTariff(JSONObject jsonTariff, Tariff tariff) {
        tariff.setId(jsonTariff.getString("RULE_ID"));//费率主表主键
        Assert.isTrue(jsonTariff.containsKey("RATE"), "费率不允许为空！");
        Assert.isTrue(!StrUtil.isEmpty(jsonTariff.getString("RATE")), "费率不允许为空！");
        tariff.setRate(jsonTariff.getDouble("RATE"));
        tariff.setDelFlag(0);//默认0 未删除标识
        tariff.setEffectiveDate(jsonTariff.getDate("EFFECTIVE_DATE"));
        tariff.setExpiredDate(jsonTariff.getDate("EXPIRED_DATE"));
        tariff.setAppendlxNotes(jsonTariff.getString("APPENDLX_NOTES"));//附件备注
        tariff.setConfirmStatus(0);
    }

    private void generateRitem(TariffRitem tariffRitem, Tariff tariff, Map.Entry<String, Object> entry, Map<String, String> operMap) {
        tariffRitem.setId(UUIDUtil.getUUID());
        tariffRitem.setRuleId(tariff.getId());//子表外键,是主表的主键
        tariffRitem.setKeyName(entry.getKey());
        tariffRitem.setDelFlag(0);
        tariffRitem.setOperChar("=");
        //keyName是特殊运算符时，使用特殊运算符替换=
        if (operMap.containsKey(tariffRitem.getKeyName())) {
            tariffRitem.setOperChar(operMap.get(tariffRitem.getKeyName()));
        }
        tariffRitem.setCompareVal(Convert.toStr(entry.getValue()));
    }



    public void getdata(org.json.JSONObject reqParam, HttpServletResponse response, HttpServletRequest request) throws Exception {
        log.info("log4j print");
        log.info(JSON.toJSONString(reqParam));
//        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        //log.error("1."+feeJdbcTemplate1);
        Map<String, String> map = new HashMap<>();
        map.put("itemId", request.getParameter("itemId"));
        map.put("contractId", request.getParameter("contractId"));
        map.put("confirmStatus", request.getParameter("confirmStatus"));
        //log.error("3."+JSON.toJSONString(map));
        List<Ctariff> datactariffflist = sqlSessionTemplate.selectList("resources/ctariff.CtariffMapper.selectByitemid", map);
        //查询费目元素
        List<Map<String, String>> propertylist = sqlSessionTemplate.selectList("resources/ctariff.CtariffMapper.selectpropertyByitemid", request.getParameter("itemId"));
        String query = request.getParameter("query");
        filterCharacter(datactariffflist, query);

        String tariffIds = new SqlUtil<Ctariff>().getAddInIds(datactariffflist, "id");
        List<TariffRitem> ritems = feeDao.findInIds(com.ag.entity.fee.TariffRitem.class, tariffIds, "RULE_ID");
        Map<String, List<TariffRitem>> ritemMap = ritems.stream().collect(Collectors.groupingBy(com.ag.entity.fee.TariffRitem::getRuleId));

        StringBuilder buffer = new StringBuilder("");
        List<String> datafiled = new ArrayList<>();
        for (Ctariff ctariff : datactariffflist) {
            //List infoStateList = feeJdbcTemplate1.selectList("resources/ctariff.CtariffRitemMapper.selectByruleid",ctariff.getId());
            List<TariffRitem> infoStateList = ritemMap.get(ctariff.getId());
            buffer.append("{");

            //循环数据项
            for (int i = 0; infoStateList != null && i < infoStateList.size(); i++) {
                TariffRitem tariffRitem = infoStateList.get(i);
                try {
                    buffer.append("\"").append(tariffRitem.getKeyName()).append("\":\"").append(tariffRitem.getCompareVal()).append("\"");
                    buffer.append(",");

                } catch (Exception e) {
                    e.printStackTrace();
                }

                if (!datafiled.contains(tariffRitem.getKeyName())) {
                    datafiled.add(tariffRitem.getKeyName());
                }

                buffer.append("\"ID\":\"").append(tariffRitem.getId()).append("\"");
                buffer.append(",");

                buffer.append("\"RULE_ID\":\"").append(ctariff.getId()).append("\"").append(",");

                if (ctariff.getEffectiveDate() == null) {
                    buffer.append("\"EFFECTIVE_DATE\":\"\"");
                } else {
                    //System.out.println(formatter.format(ctariff.getEffectiveDate()));
                    //buffer.append("\"EFFECTIVE_DATE\":\""+formatter.format(ctariff.getEffectiveDate())+"\"");
                    buffer.append("\"EFFECTIVE_DATE\":\"" + ctariff.getEffectiveDate() + "\"");
                }
                buffer.append(",");
                buffer.append("\"RATE\":\"").append(ctariff.getRate()).append("\"").append(",");

                if (ctariff.getExpiredDate() == null) {
                    buffer.append("\"EXPIRED_DATE\":\"\"");
                } else {
                    buffer.append("\"EXPIRED_DATE\":\"" + ctariff.getExpiredDate() + "\"");
                }
                buffer.append(",");

                if (ctariff.getAppendlxNotes() == null) {
                    buffer.append("\"APPENDLX_NOTES\":\"\"");
                } else {
                    buffer.append("\"APPENDLX_NOTES\":\"" + ctariff.getAppendlxNotes() + "\"");
                }
                buffer.append(",");

                buffer.append("\"CONFIRM_STATUS\":\"" + ctariff.getConfirmStatus() + "\"");
                buffer.append(",");

                buffer.append("\"VERIFY_FLAG\":\"" + ctariff.getVerifyFlag() + "\"");
                buffer.append(",");

                //循环删除
                for (int hm = 0; hm < propertylist.size(); hm++) {
                    Map<String, String> mapproperty = propertylist.get(hm);
                    if (mapproperty.get("PROPERTY_CODE").equals(tariffRitem.getKeyName())) {
                        propertylist.remove(mapproperty);
                    }
                }
            }

            for (Map<String, String> mapproperty : propertylist) {
                buffer.append("\"").append(mapproperty.get("PROPERTY_CODE")).append("\":\"\"");
                buffer.append(",");
                datafiled.add(mapproperty.get("PROPERTY_CODE"));
            }
            buffer.append("},");
            //  buffer.append("}");
        }
        datafiled.add("ID");//子表id
        datafiled.add("RATE");
        datafiled.add("RULE_ID");//费率主表id
        datafiled.add("EFFECTIVE_DATE");//生效日期
        datafiled.add("EXPIRED_DATE");//失效日期
        datafiled.add("APPENDLX_NOTES");//附件备注
        datafiled.add("CONFIRM_STATUS");//审核状态
        datafiled.add("VERIFY_FLAG");//校验状态

        StringBuffer str = new StringBuffer();
        str.append("{\"success\":true");
        str.append(",\"metaData\":{\"fields\":[");

        processfieldTypelist(str, datafiled);

        str.append("]},\"rows\":[");
        str.append(buffer).append("],\"total\":").append(ritemMap.size()).append("}");
        try {
            WebUtil.send(response, str);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void filterCharacter(List<Ctariff> datactariffflist, String query) {
        if (StrUtil.isEmpty(query)) {
            return;
        }
        String[] arr = query.split(",");

        Iterator<Ctariff> iterator = datactariffflist.iterator();
        while (iterator.hasNext()) {
            Ctariff ctariff = iterator.next();
            boolean status = false;
            for (String fc : arr) {
                if (StrUtil.isEmpty(fc)) {
                    continue;
                }
                if (fc.contains("&")) {
                    continue;
                }
                if (!ctariff.getKeyDescription().contains(fc) && !ctariff.getValDescription().contains(fc)) {
                    status = true;
                }
            }
            if (status) {
                iterator.remove();
            }
        }
    }


    /**
     * json??????
     *
     * @param str
     * @param fields
     */
    public static void processfieldTypelist(StringBuffer str, List<String> fields) {
        for (int ia = 0; ia < fields.size(); ia++) {
            if (ia > 0) str.append(",");
            String name = fields.get(ia);

            String types = "string";
            String datetypes = "date";
            if (("EFFECTIVE_DATE").equals(name.toUpperCase()) || ("EXPIRED_DATE").equals(name.toUpperCase())) {
                str.append("{\"name\":\"" + name.toUpperCase() + "\",\"type\":\"" + datetypes + "\"}");
            } else {
                str.append("{\"name\":\"" + name.toUpperCase() + "\",\"type\":\"" + types + "\"}");
            }
        }
    }

    /**
     * 费率增删改日志
     */
    private void handleTariffLog(Integer status, String contractId, String itemId, String ruleId, String username) {
        try {
            Contract contract = new Contract();
            contract.setId(contractId);
            BaseChargingItem item = new BaseChargingItem();
            item.setId(itemId);
            ItemProperties entity = new ItemProperties();
            entity.setItemId(itemId);
            contract = (Contract) feeDao.findById(contract, Contract.class, "ID");//合同
            item = (BaseChargingItem) feeDao.findById(item, BaseChargingItem.class, "ID");//费目的基本要素
            List<TariffRitem> ritems = feeDao.findInIds(com.ag.entity.fee.TariffRitem.class, ruleId, "RULE_ID");//该费率的子表
            List<ItemProperties> properties = feeDao.findByEqCriteria(entity, ItemProperties.class, "ITEM_ID");
            List<TariffOperLog> logs = new ArrayList<>();
            String note = "", rate = "";
            for (com.ag.entity.fee.TariffRitem ritem : ritems) {
                if (ObjectUtil.equal(ritem.getKeyName(), "RATE")) {
                    rate = Convert.toStr(ritem.getCompareVal());
                }
                for (ItemProperties propertie : properties) {
                    if (ObjectUtil.equal(propertie.getPropertyCode(), ritem.getKeyName())) {
                        note += propertie.getPropertyName() + ritem.getOperChar() + ritem.getCompareName() + ";";
                        break;
                    }
                }

            }
            note = "[费率：" + rate + "]" + note;
            if (status == 1) {
                note = "新增-->" + note;
            } else if (status == 2) {
                note = "修改<--" + note;
            } else if (status == 3) {
                note = "删除<--" + note;
            }
            TariffOperLog log = new TariffOperLog();
            log.setId(UUIDUtil.getUUID());
            log.setContractName(contract.getDescription());
            log.setItemName(item.getDescription());
            log.setCreatedBy(username);
            log.setCreatedOn(new Date());
            log.setDescription(note);
            bizDao.save(log);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

}
