package com.chaozhanggui.admin.system.service;

import cn.hutool.core.util.ObjectUtil;
import com.chaozhanggui.admin.system.model.CreateAgencyReq;
import com.chaozhanggui.admin.system.util.MD5Util;
import com.chaozhanggui.admin.system.util.StringUtil;
import com.chaozhanggui.common.system.config.RespBody;
import com.chaozhanggui.dao.system.dao.*;
import com.chaozhanggui.dao.system.entity.*;
import com.chaozhanggui.dao.system.model.CashStatus;
import com.chaozhanggui.dao.system.model.ProfitPO;
import com.chaozhanggui.dao.system.util.N;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.cache.CacheStats;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AgencyService {

    @Autowired
    TbPlussUserInfoMapper userInfoMapper;

    @Autowired
    TbPlussUserPromotionMapper userPromotionMapper;

    @Autowired
    TbPlussUserAppMapper userAppMapper;

    @Autowired
    TbPlussMerchantChannelMapper tbPlussMerchantChannelMapper;

    @Autowired
    TbPlussMerchantChannelStatusMapper tbPlussMerchantChannelStatusMapper;

    @Autowired
    TbPlussMerchantBackLklMapper tbPlussMerchantBackLklMapper;

    @Autowired
    TbPlussMerchantBaseInfoMapper tbPlussMerchantBaseInfoMapper;
    @Resource
    private TbPlussUserMarkerMapper userMarkerMapper;



    @Transactional(rollbackFor = Exception.class)
    public RespBody addAgency(String userId, CreateAgencyReq agencyReq) throws  RuntimeException{
        TbPlussUserInfo userInfo= userInfoMapper.selectByLoginName(agencyReq.getAngencyCode());
        if(ObjectUtil.isNotEmpty(userInfo)){
            log.error("机构编号已经存在:{}",agencyReq.getAngencyCode());
            return new RespBody("000008");
        }

        TbPlussUserPromotion userPromotion= userPromotionMapper.selectByPrimaryKey(Integer.valueOf(userId));
        if(ObjectUtil.isEmpty(userPromotion)){
            log.error("父级机构账号异常");
            return new RespBody("000009");
        }

        if(userPromotion.getTypeCode().equals(agencyReq.getUserType())){
            log.error("机构权限不足");
            return new RespBody("000010");
        }

        Boolean flag=true;
        switch (userPromotion.getTypeCode()){
            case "MG":
                if(agencyReq.getUserType().equals("FO")){
                    flag=false;
                }
                break;
            case "FO":
                if(agencyReq.getUserType().equals("SO")){
                    flag=false;
                }
                break;
            case "SO" :
                if(agencyReq.getUserType().equals("AG")){
                    flag=false;
                }
                break;
        }
        if(flag){
            log.error("错误的机构类型");
            return new RespBody("000013");
        }

//        if((userPromotion.getTypeCode().equals("MG")&&!agencyReq.getUserType().equals("FO"))||(userPromotion.getTypeCode().equals("FO")&&!agencyReq.getUserType().equals("SO"))
//                ||(userPromotion.getTypeCode().equals("SO")&&!agencyReq.getUserType().equals("AG"))){
//            log.error("错误的机构类型");
//            return new RespBody("000013");
//        }

        if(N.gt(userPromotion.getCurrentFee(),agencyReq.getFee())){
            log.error("费率错误，下级机构费率不能低于上级");
            return new RespBody("000011");
        }

        if(N.egt(agencyReq.getFee(), BigDecimal.ONE)){
            log.error("费率错误，费率值不允许大于1");
            return new RespBody("000012");
        }

        userInfo=new TbPlussUserInfo();
        userInfo.setLoginname(agencyReq.getAngencyCode());
        userInfo.setTruename(agencyReq.getAgencyName());
        userInfo.setPhone(agencyReq.getPhone());
        userInfo.setPassword(MD5Util.MD5Encode(agencyReq.getPassowrd(), "utf-8"));
        userInfo.setCreatetime(new Date());
        userInfo.setFacecert("0");
        userInfoMapper.insert(userInfo);

        TbPlussUserApp userApp=new TbPlussUserApp();
        userApp.setLoginname(agencyReq.getAngencyCode());
        userApp.setUsername(agencyReq.getAgencyName());
        userApp.setUserid(userInfo.getId().intValue());
        userApp.setUsertype("promoter");
        userApp.setLevel(1);
        userApp.setCreatedt(new Date());
        userApp.setStatus(0);
        userApp.setParentid(userPromotion.getUserId());
        userApp.setInvitenum(getRandomNum());
        userApp.setToken(agencyReq.getAngencyCode());
        userApp.setIsfixedrate("0");
        userApp.setAutoaudit("");
        userApp.setPayecdemicswitch("1");
        userApp.setIsdirectseller("0");
        userApp.setIsmarket("1");
        userApp.setIsunionpay("1");
        userApp.setRolecode("SV2");
        userApp.setLevelcode("LV1");
        userApp.setSort(-1);
        userApp.setSpreadflag("1");
        userApp.setTypemark(0);
        userApp.setEvasionvoiceflag("1");
        userApp.setMembervoiceflag("1");
        userAppMapper.insert(userApp);

        TbPlussUserPromotion newPromotion=new TbPlussUserPromotion();
        newPromotion.setUserId(userInfo.getId().intValue());
        newPromotion.setTypeCode(agencyReq.getUserType());
        newPromotion.setParentUserId(userId);
        newPromotion.setIsExtend("1");
        newPromotion.setCurrentFee(agencyReq.getFee());
        newPromotion.setCreateTime(new Date());
        userPromotionMapper.insert(newPromotion);

        return new RespBody("000000");

    }


    public RespBody queryCustormFlow(String userId,String userType,String agencyCode,String isExtend,
                                     String merchantCode,String status,String merchantType,String reqUserId,
                                     Integer pageNum,Integer pageSize,String phone){
        PageHelper.startPage(pageNum, pageSize);
        List<Map<String,Object>>  list=userPromotionMapper.selectOrderByUserIdOrAgecyCode(userId,userType,agencyCode,isExtend,merchantCode,status,merchantType,reqUserId,phone);
        if(ObjectUtil.isNotEmpty(list)&&list.size()>0){
            list.stream().forEach(it->{
               String id= it.get("id")+"";
              Map<String,BigDecimal> map=userPromotionMapper.selectPromotionByUserId(id);
              if(ObjectUtil.isNotEmpty(map)&&map.size()>0){
                it.put("sumfansShareMoney",map.get("sumfansShareMoney"));
                it.put("yestedayShareMoney",map.get("yestedayShareMoney"));
              }else {
                  it.put("sumfansShareMoney",0);
                  it.put("yestedayShareMoney",0);
              }
              List<Map<String,Object>> list1=new ArrayList<>();
              List<TbPlussMerchantChannel> channels= tbPlussMerchantChannelMapper.selectAll();
              if(ObjectUtil.isNotEmpty(channels)&&channels.size()>0){
                  for (TbPlussMerchantChannel channel : channels) {
                      Map<String,Object> hashMap=new HashMap<>();
                      hashMap.put("channelname",channel.getChannelname());
                      hashMap.put("channelcode",channel.getChannelcode());
                      hashMap.put("channel",channel.getId());
                      Map<String,Object> baseInfo=tbPlussMerchantChannelStatusMapper.selectByUserId(id,channel.getId().toString());
                      if(ObjectUtil.isNotEmpty(baseInfo)&&baseInfo.size()>0){
                       if(5==channel.getId()&&"3".equals(baseInfo.get("status").toString())&&ObjectUtil.isNotEmpty(baseInfo.get("merchantId"))){
                           TbPlussMerchantBackLkl backLkl= tbPlussMerchantBackLklMapper.selectByMercdeMerId(it.get("merchantCode").toString(),baseInfo.get("merchantId").toString());
                           if(ObjectUtil.isNotEmpty(backLkl)){
                               baseInfo.put("merchantId",backLkl.getExternalCustomerNo());
                           }

                       }

                      }
                      hashMap.put("baseInfo",baseInfo);
                      list1.add(hashMap);
                  }
              }
                Map<String,Object> stringObjectMap=new HashMap<>();
              TbPlussMerchantBaseInfo baseInfo=tbPlussMerchantBaseInfoMapper.selectByUserId(id);
              if(ObjectUtil.isNotEmpty(baseInfo)){
                    stringObjectMap.put("merchantCode",baseInfo.getMerchantcode());
                    stringObjectMap.put("alias",baseInfo.getAlias());
                    stringObjectMap.put("merchantType",baseInfo.getMerchanttype());
                    switch (baseInfo.getMerchanttype()){
                        case "1":
                            stringObjectMap.put("merchantTypeName","小微");
                            break;
                        case "2":
                            stringObjectMap.put("merchantTypeName","个体");
                            break;
                        case "3":
                            stringObjectMap.put("merchantTypeName","企业");
                            break;
                    }
              }

              it.put("merchantBaseInfo",stringObjectMap);
              it.put("merchantChannel",list1);
            }
            );
        }
        PageInfo pageInfo=new PageInfo(list);
        return new RespBody("000000",pageInfo);
    }

    public RespBody queryCustormSum(String userId){
        return new RespBody("000000",userPromotionMapper.selectCountNumByUserId(userId));
    }


    public RespBody queryAgency(String userId,String userType,String agencyCode,String isExtend,Integer pageNum,Integer pageSize){


        PageHelper.startPage(pageNum, pageSize);
        List<Map<String,Object>>  list=userPromotionMapper.selectByUserIdOrAgecyCode(userId,userType,agencyCode,isExtend);
        list.stream().forEach(it->{
           String id= it.get("id").toString();
            Integer count= userPromotionMapper.selectCountByUserId(id);
            if(count<=0){
                it.put("sumfansShareMoney",0);
                it.put("yestedayConsumeFee",0);
                it.put("yestedayShareMoney",0);
                it.put("sumConsumeFee",0);
                it.put("sumAccount",0);
            }else {
                Map<String,Object> map= userPromotionMapper.selectByUserId(id);
                if(ObjectUtil.isEmpty(map)){
                    it.put("sumfansShareMoney",0);
                    it.put("yestedayConsumeFee",0);
                    it.put("yestedayShareMoney",0);
                    it.put("sumConsumeFee",0);
                    it.put("sumAccount",0);
                }else{
                    it.put("sumfansShareMoney",map.get("sumfansShareMoney"));
                    it.put("yestedayConsumeFee",map.get("yestedayConsumeFee"));
                    it.put("yestedayShareMoney",map.get("yestedayShareMoney"));
                    it.put("sumConsumeFee",map.get("sumConsumeFee"));
                    it.put("sumAccount",count);
                }
            }


        });
        PageInfo pageInfo=new PageInfo(list);
        return new RespBody("000000",pageInfo);
    }

    public RespBody modifyFee(String userId,Integer id,BigDecimal fee){
        TbPlussUserPromotion promotion=  userPromotionMapper.selectByPrimaryKey(id);
        if(ObjectUtil.isEmpty(promotion)){
            log.error("需要修改的费率信息不存在");
            return new RespBody("000014");
        }
        TbPlussUserPromotion userPromotion=userPromotionMapper.selectByPrimaryKey(Integer.valueOf(userId));
        if(ObjectUtil.isEmpty(userPromotion)){
            log.error("父级机构信息异常");
            return new RespBody("000015");
        }

        Boolean flag=true;
        switch (userPromotion.getTypeCode()){
            case "MG":
                if(promotion.getTypeCode().equals("FO")){
                    flag=false;
                }
                break;
            case "FO":
                if(promotion.getTypeCode().equals("SO")){
                    flag=false;
                }
                break;
            case "SO" :
                if(promotion.getTypeCode().equals("AG")){
                    flag=false;
                }
                break;
        }
        if(flag){
            log.error("当前用户权限不足");
            return new RespBody("000016");
        }

        if(N.gt(userPromotion.getCurrentFee(),fee)){
            log.error("修改费率不允许小于上级费率:{},{},{},{}",id,userId,fee,userPromotion.getCurrentFee());
            return new RespBody("000017");
        }
        BigDecimal lowFee=userPromotionMapper.selectMaxFeeByUserId(id.toString());
        if(ObjectUtil.isNotEmpty(lowFee)&&N.gt(fee,lowFee)){
            log.error("修改费率不允许小于下级最大费率:{},{},{},{}",id,userId,fee,lowFee);
            return new RespBody("000018");
        }


        promotion.setCurrentFee(fee);
        promotion.setUpdateTime(new Date());
        userPromotionMapper.updateByPrimaryKey(promotion);
        return new RespBody("000000");
    }

    public  RespBody getSumDeviceStock(String userId){
        return new RespBody("000000",userPromotionMapper.selectCount(userId));
    }

    public RespBody getSumDeviceStockInfo(String userId,String merchantCode,Integer pageNum,Integer pageSize){
        PageHelper.startPage(pageNum, pageSize);
        List<Map<String,Object>> list= userPromotionMapper.selectDeviceStok(userId,merchantCode);
        PageInfo pageInfo=new PageInfo(list);
        return new RespBody("000000",pageInfo);
    }


    public RespBody getUserMark(String userId,String phone,String name,Integer pageNum,Integer pageSize){
        PageHelper.startPage(pageNum, pageSize);
        List<Map<String,Object>> list= userPromotionMapper.selectMarkByUserId(userId,phone,name);
        PageInfo pageInfo=new PageInfo(list);
        return new RespBody("000000",pageInfo);
    }
    @Transactional(rollbackFor = Exception.class)
    public RespBody updateUserMark(Integer id, String status, String remark){
        TbPlussUserPromotion userPromotion = userPromotionMapper.selectByPrimaryKey(id);
        if (ObjectUtil.isEmpty(userPromotion)){
            log.error("用户角色信息不存在");
            return new RespBody("999940");
        }
        //是否允许推广 1 初级创客 0 不允许 2  高级创客 3.审核中4通过5驳回
        if ( "5".equals(userPromotion.getIsExtend())){
            log.error("不允许成为创客");
            return new RespBody("999941");
        }
        if ("1".equals(userPromotion.getIsExtend()) || "4".equals(userPromotion.getIsExtend())){
            log.error("已成为创客或者正在审核中");
            return new RespBody("999942");
        }
        TbPlussUserPromotion tbPlussUserPromotion = new TbPlussUserPromotion();
        tbPlussUserPromotion.setUserId(id);
        tbPlussUserPromotion.setIsExtend(status);
        tbPlussUserPromotion.setUpdateTime(new Date());
        int i = userPromotionMapper.updateByPrimaryKeySelective(tbPlussUserPromotion);
        TbPlussUserMarker userMarker = new TbPlussUserMarker();
        userMarker.setUserId(id);
        userMarker.setStatus(status);
        int u = userMarkerMapper.updateByPrimaryKeySelective(userMarker);
        if (i>0 && u>0 ){
            return new RespBody("000000");
        }
        return new RespBody("999943");

    }


    public RespBody modifyMark(String userId,String id,String status,String remark){
        if(ObjectUtil.isEmpty(id)||ObjectUtil.isEmpty(status)){
            log.error("错误的参数");
            return new RespBody("000019");
        }


        return null;


    }


    public RespBody queryProfit(String userId,String orderNumber,String merchantCode,Integer pageNo,Integer pageSize){
        if(ObjectUtil.isEmpty(userId)){
            log.error("请求的用户id为空");
            return new RespBody("000019");
        }
        PageHelper.startPage(pageNo, pageSize);
        List<ProfitPO> list= userAppMapper.selectProfit(userId,orderNumber,merchantCode);

        if(ObjectUtil.isEmpty(list)||list.size()<=0){
            return new RespBody("000000");
        }
        list.stream().forEach(it->{
            TbPlussUserPromotion userPromotion= userPromotionMapper.selectUserPromotionByUserId(userId,it.getUserId());
            if(ObjectUtil.isNotEmpty(userPromotion)){
                it.setLoginName(userPromotion.getLoginName());
                it.setTypeCode(userPromotion.getTypeCode());
                it.setCurrentFee(String.format("%.2f",userPromotion.getCurrentFee()));

            }
        });
        PageInfo pageInfo=new PageInfo(list);

        return new RespBody("000000",pageInfo);
    }




    public List<TbPlussUserPromotion>  getUserId(String userId,List<TbPlussUserPromotion> list){
        TbPlussUserPromotion promotion=userPromotionMapper.selectByPrimaryKey(Integer.valueOf(userId));
       if(ObjectUtil.isNotEmpty(promotion)&&"0".equals(promotion.getParentUserId())){
           list.add(promotion);
            return list;
       }
       if("AG".equals(promotion.getTypeCode())||"SO".equals(promotion.getTypeCode())||"FO".equals(promotion.getTypeCode())){
           LinkedHashMap<String,CashStatus> cashStatusMap=new LinkedHashMap<>();
           CashStatus cashStatus=new CashStatus();
           cashStatus.setUserId(promotion.getUserId().toString());
           cashStatus.setUserType(promotion.getTypeCode());
           cashStatus.setStatus("0");
           cashStatusMap.put(promotion.getTypeCode(),cashStatus);
           list.add(promotion);
       }
       getUserId(promotion.getParentUserId(),list);
       return list;

    }


    public TbPlussUserPromotion getUserId(String userId){
        TbPlussUserPromotion promotion=userPromotionMapper.selectByPrimaryKey(Integer.valueOf(userId));
        if(ObjectUtil.isNotEmpty(promotion)){
            if("SB".equals(promotion.getTypeCode())||"1".equals(promotion.toString())){
                return promotion;
            }
        }
        getUserId(promotion.getParentUserId());
        return null;
    }



    public LinkedList<CashStatus> getCashMap(String userId,LinkedList<CashStatus>  list){
        TbPlussUserPromotion promotion=userPromotionMapper.selectByPrimaryKey(Integer.valueOf(userId));
        if(ObjectUtil.isNotEmpty(promotion)&&"0".equals(promotion.getParentUserId())){
            CashStatus cashStatus=new CashStatus();
            cashStatus.setUserId(promotion.getUserId().toString());
            cashStatus.setUserType(promotion.getTypeCode());
            cashStatus.setStatus("0");
            list.add(cashStatus);
            promotion.setCashStatus(list);
            return list;

        }
        if("AG".equals(promotion.getTypeCode())||"SO".equals(promotion.getTypeCode())||"FO".equals(promotion.getTypeCode())){
            CashStatus cashStatus=new CashStatus();
            cashStatus.setUserId(promotion.getUserId().toString());
            cashStatus.setUserType(promotion.getTypeCode());
            cashStatus.setStatus("0");
            list.add(cashStatus);
            promotion.setCashStatus(list);
        }
        getCashMap(promotion.getParentUserId(),list);
        return list;
    }


    public RespBody queryOrder(String userId,String orderNumber,Integer pageNum,Integer pageSize){
        PageHelper.startPage(pageNum, pageSize);
        List<Map<String,Object>> list=userPromotionMapper.selectOrdersByUserId(userId,orderNumber);
        PageInfo pageInfo=new PageInfo(list);
        return new RespBody("000000",pageInfo);
    }



    private String getRandomNum(){
        String inviteNum;
        do {
            inviteNum = StringUtil.genRandomNum(5);
            int count=userAppMapper.countByInviteNum(inviteNum);
            if (count<=0) {
                return inviteNum;
            }
        } while (true);
    }
}
