package com.ag.rate.tariff.service;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ag.base.BaseService;
import com.ag.base.DefaultBussniessImpl;
import com.ag.base.IBaseRepository;
import com.ag.base.IRedisService;
import com.ag.commonFace.ITariffExtService;
import com.ag.entity.fee.ItemProperties;
import com.ag.entity.fee.Tariff;
import com.ag.entity.fee.TariffRitem;
import com.ag.entity.fee.face.IRuleCondition;
import com.ag.entity.fee.face.ReqSource;
import com.ag.entity.fee.vo.TariffVO;
import com.ag.secp.platform.spring.SpringApplicationContext;
import com.ag.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wb.common.KvBean;
import com.wb.util.WebUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * Created by yangxh on 2019/9/11.
 */
@Service
public class TariffExtService extends BaseService implements ITariffExtService {

    /*@Autowired
    private BaseRepositoryImpl feeDao;*/
    @Resource(name="baseRepositoryImpl")
    private IBaseRepository feeDao;
    @Autowired
    private DefaultBussniessImpl bizDao;

    /**
     * ####费率更新的扩展功能####
     * 1、按合同号和费目编号查询所有费率和费率元素
     * 2、生成所有费率的keyDescription，规则如下：
     * 费率排除RATE元素，按C_ITEM_PROPERTY的顺序的组合
     * 组合连接串&&
     * 如果运算符不是=，元素key前增加运算符
     * 3、keyDescription重复检查
     * 有相同keyDescription抛出异常回滚提示用户重复的费率
     * 4、更新费率表的keyDescription和valDescription
     */
    public void synDescription(String contractId, String itemId, String tenancyId){
        Assert.isTrue(!StrUtil.isEmpty(contractId), "数据异常，合同号不能为空！");
        Assert.isTrue(!StrUtil.isEmpty(itemId), "数据异常，费目编号不能为空！");
        //Assert.isTrue(!StrUtil.isEmpty(tenancyId), "数据异常，租户不能为空！");
        Tariff tariff = new Tariff();
        tariff.setContractId(contractId);
        tariff.setChargingId(itemId);
        tariff.setTenancyId(tenancyId);
        tariff.setDelFlag(0);
        List<TariffVO> tariffs = feeDao.findByEntity(tariff, TariffVO.class);
        /*ItemProperties itemProperty = new ItemProperties();
        itemProperty.setTenancyId(tenancyId);
        itemProperty.setItemId(itemId);
        List<ItemProperties> properties = feeDao.findByEqCriteria(itemProperty, ItemProperties.class, "ITEM_ID");
        String tariffIds = new SqlUtil<TariffVO>().getAddInIds(tariffs, "id");
        TariffRitem ritem = new TariffRitem();
        String sql = feeDao.findByEqSql(ritem);
        sql = StrUtil.join(sql, " where RULE_ID in (", tariffIds, ") and DEL_FLAG=0");
        List<TariffRitem> ritems = feeDao.list(sql, TariffRitem.class);*/
        //mergeTariffVO(tariffs, ritems);//费率+费率条件=组合对象
        //generateDescription(tariffs, properties);
        checkDuplicate(tariffs);
        //saveDescription(tariffs);


    }

    private void saveDescription(List<TariffVO> tariffs) {
        List<Tariff> tariffsUpd = new ArrayList<>();
        for (TariffVO tariffVO : tariffs){
            if (StrUtil.isEmpty(tariffVO.getKeyDescription())) {
                continue;
            }
            Tariff tariff = new Tariff();
            tariff.setId(tariffVO.getId());

            tariff.setKeyDescription(tariffVO.getKeyDescription());
            tariff.setValDescription(tariffVO.getValDescription());
            tariffsUpd.add(tariff);
        }
        feeDao.updateAll(tariffsUpd, "ID");
    }

    private void checkDuplicate(List<TariffVO> tariffs) {
        Set<String> set = new HashSet<>();
        for(TariffVO tariffVO : tariffs){
            String compareStr = tariffVO.getKeyDescription() +","+ tariffVO.getSort();
            if (set.contains(compareStr)){
                throw new RuntimeException("检查发现重复费率，请修改【"+tariffVO.getValDescription()+"】");
            }
            set.add(compareStr);
        }
    }

    private void generateDescription(List<TariffVO> tariffs, List<ItemProperties> properties) {
        if (CollectionUtils.isEmpty(properties)){
            return;
        }
        properties.sort((a, b) -> a.getDispOrder() - b.getDispOrder());
        IRedisService service = (IRedisService) SpringApplicationContext.getBean("redisServiceImpl");
        for (TariffVO vo : tariffs){
            String keyDescription = "", valDescription = "", sortStr = "";
            for (ItemProperties property : properties){
                //过滤掉非查找 要素
                if (property.getIsShowOperator() == 1){
                    continue;
                }
                for (IRuleCondition ritem : vo.getRitemList()){
                    if (ritem.getKeyName().equals(property.getPropertyCode())){
                        sortStr = StrUtil.join(sortStr, Convert.toStr(property.getDispOrder()));
                        if ("=".equals(ritem.getOperChar())) {
                            keyDescription = StrUtil.join(keyDescription, "&&", ritem.getCompareVal());
                            String val = service.getTargetName(ritem.getKeyName(), ritem.getCompareVal());
                            if (!StrUtil.isEmpty(val)) {
                                valDescription = StrUtil.join(valDescription, "&&", val);
                            }
                        } else {
                            keyDescription = StrUtil.join(keyDescription, "&&", ritem.getOperChar(), " ", ritem.getCompareVal());
                            String val = service.getTargetName(ritem.getKeyName(), ritem.getCompareVal());
                            if (!StrUtil.isEmpty(val)) {
                                valDescription = StrUtil.join(valDescription, "&&", ritem.getOperChar(), " ", val);
                            }
                            //valDescription = StrUtil.join(valDescription, "&&", ritem.getOperChar(), " ", KVBuffer.getNameByCode(ritem.getKeyName(), ritem.getCompareVal()));
                        }
                        break;
                    }
                }
            }
            if (StrUtil.isEmpty(keyDescription)){
                continue;
            }
            vo.setKeyDescription(keyDescription.substring(2));
            vo.setValDescription(valDescription.substring(2));
            vo.setSort(Convert.toInt(sortStr));
        }


    }

    private void mergeTariffVO(List<TariffVO> tariffs, List<TariffRitem> ritems) {
        for (TariffVO vo : tariffs){
            List<TariffRitem> ritemList = new ArrayList<>();
            vo.setRitemList(ritemList);
            for (TariffRitem ritem : ritems){
                if ("RATE".equals(ritem.getKeyName())){
                    continue;
                }
                if (vo.getId().equals(ritem.getRuleId())){
                    ritemList.add(ritem);
                }
            }
        }
    }


    public Map<String, String> getSpecialOperChar(String tariffId) {
        TariffRitem ritemQuery = new TariffRitem();
        ritemQuery.setRuleId(tariffId);
        String sql = feeDao.getSelectByEntity(ritemQuery, false);
        sql = StrUtil.join(sql, " and OPER_CHAR<>'=' and DEL_FLAG=0");
        List<TariffRitem> ritems = feeDao.list(sql, TariffRitem.class);
        Map<String, String> operMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(ritems)){
            for (TariffRitem ritem : ritems){
                operMap.put(ritem.getKeyName(), ritem.getOperChar());
            }
        }
        return operMap;
    }

    public void getItemProperties(org.json.JSONObject param, HttpServletResponse response, HttpServletRequest request) throws IOException {
        ItemProperties condition = new ItemProperties();
        condition.setItemId(param.getString("ITEM_ID"));
        List<ItemProperties> properties = feeDao.findByEqCriteria(condition, ItemProperties.class, "ITEM_ID");
        properties.sort((a, b)->a.getDispOrder() - b.getDispOrder());
        JSONObject json = new JSONObject();
        json.put("ItemProperties", properties);
        IRedisService service = (IRedisService) SpringApplicationContext.getBean("redisServiceImpl");
        for (ItemProperties property : properties) {
            List<KvBean> kvBeanList = service.getAllByKey(property.getPropertyCode(), super.getTenancyId(param));
            json.put(property.getPropertyCode(), kvBeanList);
        }
        WebUtil.send(response, json);
    }

    public void generateDescription(Tariff tariff, List<TariffRitem> ritems, List<ItemProperties> properties) {
        StringBuilder keyDesc = new StringBuilder();
        StringBuilder valDesc = new StringBuilder();
        String sortStr = "";
        //排序号
        for (ItemProperties property : properties) {
            //目标元素
            for (TariffRitem ritem : ritems) {
                if (ObjectUtil.equal(property.getPropertyCode(), ritem.getKeyName())) {
                    //存在查找要素
                    if (!StrUtil.isEmpty(ritem.getCompareName())) {
                        sortStr = StrUtil.join(sortStr, Convert.toStr(property.getDispOrder()));
                        //运算符=
                        if (ObjectUtil.equal(ritem.getOperChar(), "=")){
                            keyDesc.append("&&").append(ritem.getCompareVal());
                            valDesc.append("&&").append(ritem.getCompareName());
                        }else{
                            keyDesc.append("&&").append(ritem.getOperChar()).append(" ").append(ritem.getCompareVal());
                            valDesc.append("&&").append(ritem.getOperChar()).append(" ").append(ritem.getCompareName());
                        }
                    }
                    break;
                }
            }
        }
        //Assert.isTrue(!StrUtil.isEmpty(keyDesc), "费率维护异常，没找到查找要素");
        if (!StrUtil.isEmpty(keyDesc.toString())){
            tariff.setKeyDescription(keyDesc.substring(2));
            tariff.setValDescription(valDesc.substring(2));
            tariff.setSort(Convert.toInt(sortStr));
        }
        if(tariff.getEffectiveDate() != null && tariff.getExpiredDate() != null){
            tariff.setKeyDescription(tariff.getKeyDescription() + "(" +
                    DateUtil.format(tariff.getEffectiveDate(), "yyyyMMdd") + "-" +
                    DateUtil.format(tariff.getExpiredDate(), "yyyyMMdd") + ")");
        }
    }

    /*public void checkRate(org.json.JSONObject param, HttpServletResponse response, HttpServletRequest request){
        ReqSource reqSource = JSON.parseObject(param.getString("reqSource"), ReqSource.class);
        String tariffId = param.getString("tariffId");

    }*/

}
