package com.iformall.service.impl;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iformall.common.ErrorCode;
import com.iformall.common.ResultData;
import com.iformall.domain.po.*;
import com.iformall.domain.po.msg.MailMsg;
import com.iformall.domain.vo.WxBillAll;
import com.iformall.domain.vo.WxBillAllVo;
import com.iformall.enums.*;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.*;
import com.iformall.mq.MqBaseProducer;
import com.iformall.service.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author gongbiao
 */
@Service
public class WxBillAllServiceImpl implements WxBillAllService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    WxBillAllMapper wxBillAllMapper;

    @Autowired
    WxBillDailyService wxBillDailyService;

    @Autowired
    WxBillDepositService wxBillDepositService;

    @Autowired
    WxBillPropertyDepositService wxBillPropertyDepositService;

    @Autowired
    WxBillPropertyService wxBillPropertyService;

    @Autowired
    WxBillRentService wxBillRentService;

    @Autowired
    WxBillOtherService wxBillOtherService;

    @Autowired
    WxBillOtherDepositService wxBillOtherDepositService;

    @Autowired
    WxBillDailyMapper wxBillDailyMapper;

    @Autowired
    WxBillDepositMapper wxBillDepositMapper;

    @Autowired
    WxBillPropertyDepositMapper wxBillPropertyDepositMapper;

    @Autowired
    WxBillPropertyMapper wxBillPropertyMapper;

    @Autowired
    WxBillRentMapper wxBillRentMapper;

    @Autowired
    WxBillOtherMapper wxBillOtherMapper;

    @Autowired
    WxBillOtherDepositMapper wxBillOtherDepositMapper;

    @Autowired
    ExcelService excelService;

    @Autowired
    MqBaseProducer mqBaseProducer;

    @Autowired
    WxBillActionService wxBillActionService;

    @Autowired
    WxMerchantBUserMapper wxMerchantBUserMapper;

    @Override
    public Map<String, Object> listAsPage(WxBillAll record, Integer pageIndex, Integer pageSize) {
        //更新各账单状态
        updateBillStatus(record);
        PageInfo<WxBillAllVo> pageInfo = PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxBillAllMapper.list(record));

        Map<String, Object> result = new HashMap<>();
        result.put("pageInfo", pageInfo);
        return result;
    }

    @Override
    public List<Map<String, Object>> listBillOweAndWaitPay(WxBillAll wxBillAll) {
        //更新各账单状态
        updateBillStatus(wxBillAll);
        ArrayList<Integer> statusList = new ArrayList<>();
        statusList.add(EnumBillRentStatus.NOT_PAID.getCode());
        statusList.add(EnumBillRentStatus.WAIT_PAY.getCode());
        wxBillAll.setStatusList(statusList);
        return wxBillAllMapper.listData(wxBillAll);
    }

    @Override
    public ResultData listBill(WxBillAll wxBillAll) {
        //更新各账单状态
        updateBillStatus(wxBillAll);
        //账单类型
        if (wxBillAll.getBillTypeValue() != null) {
            if (wxBillAll.getBillTypeValue().equals(EnumBillType.RENT.getCode())) {
                wxBillAll.setBillTypeValue(EnumBillTypeParam.RENT.getCode());
            } else if (wxBillAll.getBillTypeValue().equals(EnumBillType.DEPOSIT.getCode())) {
                wxBillAll.setBillTypeValue(null);
                ArrayList typeList = new ArrayList();
                typeList.add(EnumBillTypeParam.RENT_DEPOSIT.getCode());
                typeList.add(EnumBillTypeParam.PROPERTY_DEPOSIT.getCode());
                typeList.add(EnumBillTypeParam.ATHER_DEPOSIT.getCode());
                wxBillAll.setTypeList(typeList);
            } else if (wxBillAll.getBillTypeValue().equals(EnumBillType.PROPERTY.getCode())) {
                wxBillAll.setBillTypeValue(EnumBillTypeParam.PROPERTY.getCode());
            } else if (wxBillAll.getBillTypeValue().equals(EnumBillType.WATER.getCode())) {
                wxBillAll.setBillTypeValue(EnumBillTypeParam.WATER.getCode());
            } else if (wxBillAll.getBillTypeValue().equals(EnumBillType.POWER.getCode())) {
                wxBillAll.setBillTypeValue(EnumBillTypeParam.POWER.getCode());
            } else if (wxBillAll.getBillTypeValue().equals(EnumBillType.ROUTINE.getCode())) {
                wxBillAll.setBillTypeValue(EnumBillTypeParam.ROUTINE.getCode());
            } else if (wxBillAll.getBillTypeValue().equals(EnumBillType.AIR_CONDITIONING.getCode())) {
                wxBillAll.setBillTypeValue(EnumBillTypeParam.AIR_CONDITIONING.getCode());
            } else {
                logger.info("账单不存在");
                return new ResultData(ErrorCode.BILL_ROUTINE_IS_NOT_FOUND);
            }
        }
        if (wxBillAll.getPageIndex() != null && wxBillAll.getPageIndex() != null) {
            PageHelper.startPage(wxBillAll.getPageIndex(), wxBillAll.getPageSize());
            List<Map<String, Object>> maps = wxBillAllMapper.listData(wxBillAll);
            PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(maps);
            return new ResultData(pageInfo);
        }
        List<Map<String, Object>> maps = wxBillAllMapper.listData(wxBillAll);
        return new ResultData(maps);
    }

    @Override
    public void updateBill(Map<String, Object> bill) {

        int billTypeValue = ((Long) bill.get("billTypeValue")).intValue();
        if (billTypeValue==EnumBillTypeParam.RENT.getCode().intValue()) {
            //更新租金账单
            WxBillRent billRent = wxBillRentMapper.selectByPrimaryKey(bill.get("id"));
            if(billRent!=null && !billRent.getStatus().equals(EnumBillRentStatus.PAID.getCode())){
                updateBillRent(bill);
            }
        } else if (billTypeValue==EnumBillTypeParam.RENT_DEPOSIT.getCode().intValue()) {
            //更新租金押金账单
            WxBillDeposit billDeposit = wxBillDepositMapper.selectByPrimaryKey(bill.get("id"));
            if(billDeposit!=null && !billDeposit.getStatus().equals(EnumBillRentStatus.PAID.getCode())){
                updateBillRentDeposit(bill);
            }
        } else if (billTypeValue==EnumBillTypeParam.PROPERTY.getCode().intValue()) {
            //更新物业账单
            WxBillProperty property = wxBillPropertyMapper.selectByPrimaryKey(bill.get("id"));
            if(property!=null && !property.getStatus().equals(EnumBillRentStatus.PAID.getCode())){
                updateBillProperty(bill);
            }
        } else if (billTypeValue==EnumBillTypeParam.PROPERTY_DEPOSIT.getCode().intValue()) {
            //更新物业押金账单
            WxBillPropertyDeposit wxBillPropertyDeposit = wxBillPropertyDepositMapper.selectByPrimaryKey(bill.get("id"));
            if(wxBillPropertyDeposit!=null && !wxBillPropertyDeposit.getStatus().equals(EnumBillRentStatus.PAID.getCode())){
                updateBillPropertyDeposit(bill);
            }
        } else if (billTypeValue==EnumBillTypeParam.WATER.getCode().intValue()) {
            //更新水费账单
            WxBillDaily wxBillDaily = wxBillDailyMapper.selectByPrimaryKey(bill.get("id"));
            if(wxBillDaily!=null && !wxBillDaily.getStatus().equals(EnumBillRentStatus.PAID.getCode())){
                updateBillDaily(bill);
            }
        } else if (billTypeValue==EnumBillTypeParam.POWER.getCode().intValue()) {
            //更新电费账单
            WxBillDaily wxBillDaily = wxBillDailyMapper.selectByPrimaryKey(bill.get("id"));
            if(wxBillDaily!=null && !wxBillDaily.getStatus().equals(EnumBillRentStatus.PAID.getCode())){
                updateBillDaily(bill);
            }
        } else if (billTypeValue == EnumBillTypeParam.AIR_CONDITIONING.getCode().intValue()) {
            //更新空调费账单
            WxBillDaily wxBillDaily = wxBillDailyMapper.selectByPrimaryKey(bill.get("id"));
            if (wxBillDaily != null && !wxBillDaily.getStatus().equals(EnumBillRentStatus.PAID.getCode())) {
                updateBillDaily(bill);
            }
        } else if (billTypeValue==EnumBillTypeParam.ROUTINE.getCode().intValue()) {
            //更新其他账单
            WxBillOther wxBillOther = wxBillOtherMapper.selectByPrimaryKey(bill.get("id"));
            if(wxBillOther!=null && !wxBillOther.getStatus().equals(EnumBillRentStatus.PAID.getCode())){
                updateBillOther(bill);
            }
        } else if (billTypeValue == EnumBillTypeParam.ATHER_DEPOSIT.getCode().intValue()) {
            //更新其他押金账单
            WxBillOtherDeposit wxBillOtherDeposit = wxBillOtherDepositMapper.selectByPrimaryKey(bill.get("id"));
            if (wxBillOtherDeposit != null && !wxBillOtherDeposit.getStatus().equals(EnumBillRentStatus.PAID.getCode())) {
                updateBillOtherDeposit(bill);
            }
        } else {
            logger.info("账单类型不存在");
        }
    }

    @Override
    public void exportBill(HttpServletRequest request, HttpServletResponse response, WxBillAll wxBillAll) {

        Map<Long, List<WxBillAllVo>> billMapList = wxBillAllMapper.list(wxBillAll)
                .parallelStream()
                .collect(Collectors.groupingBy(WxBillAllVo::getMerchantId));

        List<Map<String, Object>> list = new ArrayList<>();

        Iterator<Map.Entry<Long, List<WxBillAllVo>>> entries = billMapList.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<Long, List<WxBillAllVo>> entry = entries.next();
            Map<String,Object> map = new HashMap<>();
            ExportParams deptExportParams = new ExportParams();
            WxBillAllVo first = ((List<WxBillAllVo>)(entry.getValue())).get(0);
            deptExportParams.setSheetName(first.getMerchantName());
            deptExportParams.setTitle(first.getMerchantName()
                            + " ("
                            + EnumRentShopType.getEnum((Integer)first.getRentShopType()).getMessage()
                            + "-"+first.getShopNumber()
                            + ")");
            //deptExportParams.setSecondTitle();
            map.put("title", deptExportParams);
            map.put("entity", WxBillAllVo.class);
            map.put("data", entry.getValue());
            list.add(map);
        }

        excelService.exportExcel(list, "账单数据.xls", response);
    }

    private int updateBillOtherDeposit(Map<String, Object> bill) {
        logger.info("updateBillOtherDeposit params:" + bill.toString());
        Object id = bill.get("id");
        WxBillOtherDeposit wxBillOtherDeposit = wxBillOtherDepositMapper.selectByPrimaryKey(id);
        if (wxBillOtherDeposit == null) {
            return 0;
        }
        Date date = new Date();
        wxBillOtherDeposit.setPayDate(date);
        Integer owe = (Integer) bill.get("owe");
        wxBillOtherDeposit.setPay(wxBillOtherDeposit.getPay() + owe);
        wxBillOtherDeposit.setOwe(0);
        wxBillOtherDeposit.setStatus(EnumBillDailyStatus.PAID.getCode());
        wxBillOtherDeposit.setUpdatetime(date);
        wxBillOtherDeposit.setPayWay(EnumBillPayWay.WECHAT_PAY.getCode());
        int count = 0;
        try {
            count = wxBillOtherDepositMapper.updateByPrimaryKeySelective(wxBillOtherDeposit);
        } catch (Exception e) {
            logger.error("更新其他押金账单失败,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        //日志
        WxMerchantBUser wxMerchantBUser = wxMerchantBUserMapper.selectByPrimaryKey(bill.get("userId"));
        WxBillAction wxBillAction = new WxBillAction();
        wxBillAction.setBillId(wxBillOtherDeposit.getId());
        String price = new BigDecimal(owe).divide(new BigDecimal(100)).toPlainString();
        wxBillAction.setDetails("线上缴费" + price + "元");
        wxBillAction.setAction(EnumBillAction.SELF_SERVICE_PAY.getCode());
        wxBillAction.setUserId(wxMerchantBUser.getId());
        wxBillAction.setUserName(wxMerchantBUser.getName());
        wxBillAction.setPhone(wxMerchantBUser.getPhone());
        wxBillAction.setTenantId(wxMerchantBUser.getTenantId());
        try {
            wxBillActionService.save(wxBillAction);
        } catch (Exception e) {
            logger.error("添加其他押金账单行为日志,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        return count;
    }

    private int updateBillOther(Map<String, Object> bill) {
        logger.info("updateBillOther params:"+bill.toString());
        Object id = bill.get("id");
        WxBillOther wxBillOther = wxBillOtherMapper.selectByPrimaryKey(id);
        if(wxBillOther==null){
            return 0;
        }
        Date date = new Date();
        wxBillOther.setPayDate(date);
        Integer owe = (Integer) bill.get("owe");
        wxBillOther.setPay(wxBillOther.getPay()+owe);
        wxBillOther.setOwe(0);
        wxBillOther.setStatus(EnumBillDailyStatus.PAID.getCode());
        wxBillOther.setUpdatetime(date);
        wxBillOther.setPayWay(EnumBillPayWay.WECHAT_PAY.getCode());
        int count = 0;
        try {
            count = wxBillOtherMapper.updateByPrimaryKeySelective(wxBillOther);
        } catch (Exception e) {
            logger.error("更新其他账单失败,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        //日志
        WxMerchantBUser wxMerchantBUser = wxMerchantBUserMapper.selectByPrimaryKey(bill.get("userId"));
        WxBillAction wxBillAction = new WxBillAction();
        wxBillAction.setBillId(wxBillOther.getId());
        String price = new BigDecimal(owe).divide(new BigDecimal(100)).toPlainString();
        wxBillAction.setDetails("线上缴费" + price + "元");
        wxBillAction.setAction(EnumBillAction.SELF_SERVICE_PAY.getCode());
        wxBillAction.setUserId(wxMerchantBUser.getId());
        wxBillAction.setUserName(wxMerchantBUser.getName());
        wxBillAction.setPhone(wxMerchantBUser.getPhone());
        wxBillAction.setTenantId(wxMerchantBUser.getTenantId());
        try {
            wxBillActionService.save(wxBillAction);
        } catch (Exception e) {
            logger.error("添加其他账单行为日志,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        return count;
    }

    private int updateBillDaily(Map<String, Object> bill) {
        logger.info("updateBillDaily params:"+bill.toString());
        Object id = bill.get("id");
        WxBillDaily wxBillDaily = wxBillDailyMapper.selectByPrimaryKey(id);
        if(wxBillDaily==null){
            return 0;
        }
        Date date = new Date();
        wxBillDaily.setPayDate(date);
        Integer owe = (Integer) bill.get("owe");
        wxBillDaily.setPay(wxBillDaily.getPay()+owe);
        wxBillDaily.setOwe(0);
        wxBillDaily.setStatus(EnumBillDailyStatus.PAID.getCode());
        wxBillDaily.setUpdatetime(date);
        wxBillDaily.setPayWay(EnumBillPayWay.WECHAT_PAY.getCode());

        int count = 0;
        try {
            count = wxBillDailyMapper.updateByPrimaryKeySelective(wxBillDaily);
        } catch (Exception e) {
            logger.error("更新日常账单失败,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        //日志
        WxMerchantBUser wxMerchantBUser = wxMerchantBUserMapper.selectByPrimaryKey(bill.get("userId"));
        WxBillAction wxBillAction = new WxBillAction();
        wxBillAction.setBillId(wxBillDaily.getId());
        String price = new BigDecimal(owe).divide(new BigDecimal(100)).toPlainString();
        wxBillAction.setDetails("线上缴费" + price + "元");
        wxBillAction.setAction(EnumBillAction.SELF_SERVICE_PAY.getCode());
        wxBillAction.setUserId(wxMerchantBUser.getId());
        wxBillAction.setUserName(wxMerchantBUser.getName());
        wxBillAction.setPhone(wxMerchantBUser.getPhone());
        wxBillAction.setTenantId(wxMerchantBUser.getTenantId());
        try {
            wxBillActionService.save(wxBillAction);
        } catch (Exception e) {
            logger.error("添加日常账单行为日志,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        return count;
    }

    private int updateBillPropertyDeposit(Map<String, Object> bill) {
        logger.info("updateBillPropertyDeposit params:"+bill.toString());
        Object id = bill.get("id");
        WxBillPropertyDeposit wxBillPropertyDeposit = wxBillPropertyDepositMapper.selectByPrimaryKey(id);
        if(wxBillPropertyDeposit==null){
            return 0;
        }
        Date date = new Date();
        wxBillPropertyDeposit.setPayDate(date);
        Integer owe = (Integer) bill.get("owe");
        wxBillPropertyDeposit.setPay(wxBillPropertyDeposit.getPay()+owe);
        wxBillPropertyDeposit.setOwe(0);
        wxBillPropertyDeposit.setStatus(EnumBillDailyStatus.PAID.getCode());
        wxBillPropertyDeposit.setUpdatetime(date);
        wxBillPropertyDeposit.setPayWay(EnumBillPayWay.WECHAT_PAY.getCode());

        int count = 0;
        try {
            count = wxBillPropertyDepositMapper.updateByPrimaryKeySelective(wxBillPropertyDeposit);
        } catch (Exception e) {
            logger.error("更新物业押金账单失败,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        //日志
        WxMerchantBUser wxMerchantBUser = wxMerchantBUserMapper.selectByPrimaryKey(bill.get("userId"));
        WxBillAction wxBillAction = new WxBillAction();
        wxBillAction.setBillId(wxBillPropertyDeposit.getId());
        String price = new BigDecimal(owe).divide(new BigDecimal(100)).toPlainString();
        wxBillAction.setDetails("线上缴费" + price + "元");
        wxBillAction.setAction(EnumBillAction.SELF_SERVICE_PAY.getCode());
        wxBillAction.setUserId(wxMerchantBUser.getId());
        wxBillAction.setUserName(wxMerchantBUser.getName());
        wxBillAction.setPhone(wxMerchantBUser.getPhone());
        wxBillAction.setTenantId(wxMerchantBUser.getTenantId());
        try {
            wxBillActionService.save(wxBillAction);
        } catch (Exception e) {
            logger.error("添加物业押金账单行为日志,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        return count;
    }

    private int updateBillProperty(Map<String, Object> bill) {
        logger.info("updateBillProperty params:"+bill.toString());
        Object id = bill.get("id");
        WxBillProperty property = wxBillPropertyMapper.selectByPrimaryKey(id);
        if(property==null){
            return 0;
        }
        Date date = new Date();
        property.setPayDate(date);
        Integer owe = (Integer) bill.get("owe");
        property.setPay(property.getPay()+owe);
        property.setOwe(0);
        property.setStatus(EnumBillDailyStatus.PAID.getCode());
        property.setUpdatetime(date);
        property.setPayWay(EnumBillPayWay.WECHAT_PAY.getCode());

        int count = 0;
        try {
            count = wxBillPropertyMapper.updateByPrimaryKeySelective(property);
        } catch (Exception e) {
            logger.error("更新物业账单失败,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        //日志
        WxMerchantBUser wxMerchantBUser = wxMerchantBUserMapper.selectByPrimaryKey(bill.get("userId"));
        WxBillAction wxBillAction = new WxBillAction();
        wxBillAction.setBillId(property.getId());
        String price = new BigDecimal(owe).divide(new BigDecimal(100)).toPlainString();
        wxBillAction.setDetails("线上缴费" + price + "元");
        wxBillAction.setAction(EnumBillAction.SELF_SERVICE_PAY.getCode());
        wxBillAction.setUserId(wxMerchantBUser.getId());
        wxBillAction.setUserName(wxMerchantBUser.getName());
        wxBillAction.setPhone(wxMerchantBUser.getPhone());
        wxBillAction.setTenantId(wxMerchantBUser.getTenantId());
        try {
            wxBillActionService.save(wxBillAction);
        } catch (Exception e) {
            logger.error("添加物业账单行为日志,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        return count;
    }

    private int updateBillRentDeposit(Map<String, Object> bill) {
        logger.info("updateBillRentDeposit params:"+bill.toString());
        Object id = bill.get("id");
        WxBillDeposit wxBillDeposit = wxBillDepositMapper.selectByPrimaryKey(id);
        if(wxBillDeposit==null){
            return 0;
        }
        Date date = new Date();
        wxBillDeposit.setPayDate(date);
        Integer owe = (Integer) bill.get("owe");
        wxBillDeposit.setPay(wxBillDeposit.getPay()+owe);
        wxBillDeposit.setOwe(0);
        wxBillDeposit.setStatus(EnumBillDailyStatus.PAID.getCode());
        wxBillDeposit.setUpdatetime(date);
        wxBillDeposit.setPayWay(EnumBillPayWay.WECHAT_PAY.getCode());

        int count = 0;
        try {
            count = wxBillDepositMapper.updateByPrimaryKeySelective(wxBillDeposit);
        } catch (Exception e) {
            logger.error("更新租赁押金账单失败,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        //日志
        WxMerchantBUser wxMerchantBUser = wxMerchantBUserMapper.selectByPrimaryKey(bill.get("userId"));
        WxBillAction wxBillAction = new WxBillAction();
        wxBillAction.setBillId(wxBillDeposit.getId());
        String price = new BigDecimal(owe).divide(new BigDecimal(100)).toPlainString();
        wxBillAction.setDetails("线上缴费" + price + "元");
        wxBillAction.setAction(EnumBillAction.SELF_SERVICE_PAY.getCode());
        wxBillAction.setUserId(wxMerchantBUser.getId());
        wxBillAction.setUserName(wxMerchantBUser.getName());
        wxBillAction.setPhone(wxMerchantBUser.getPhone());
        wxBillAction.setTenantId(wxMerchantBUser.getTenantId());
        try {
            wxBillActionService.save(wxBillAction);
        } catch (Exception e) {
            logger.error("添加其他押金账单行为日志,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        return count;
    }

    private int updateBillRent(Map<String, Object> bill) {
        logger.info("updateBillRentDeposit params:"+bill.toString());
        Object id = bill.get("id");
        WxBillRent wxBillRent = wxBillRentMapper.selectByPrimaryKey(id);
        if(wxBillRent==null){
            return 0;
        }
        Date date = new Date();
        wxBillRent.setPayDate(date);
        Integer owe = (Integer) bill.get("owe");
        wxBillRent.setPay(wxBillRent.getPay()+owe);
        wxBillRent.setOwe(0);
        wxBillRent.setStatus(EnumBillDailyStatus.PAID.getCode());
        wxBillRent.setUpdatetime(date);
        wxBillRent.setPayWay(EnumBillPayWay.WECHAT_PAY.getCode());

        int count = 0;
        try {
            count = wxBillRentMapper.updateByPrimaryKeySelective(wxBillRent);
        } catch (Exception e) {
            logger.error("更新租金账单失败,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        //日志
        WxMerchantBUser wxMerchantBUser = wxMerchantBUserMapper.selectByPrimaryKey(bill.get("userId"));
        WxBillAction wxBillAction = new WxBillAction();
        wxBillAction.setBillId(wxBillRent.getId());
        String price = new BigDecimal(owe).divide(new BigDecimal(100)).toPlainString();
        wxBillAction.setDetails("线上缴费" + price + "元");
        wxBillAction.setAction(EnumBillAction.SELF_SERVICE_PAY.getCode());
        wxBillAction.setUserId(wxMerchantBUser.getId());
        wxBillAction.setUserName(wxMerchantBUser.getName());
        wxBillAction.setPhone(wxMerchantBUser.getPhone());
        wxBillAction.setTenantId(wxMerchantBUser.getTenantId());
        try {
            wxBillActionService.save(wxBillAction);
        } catch (Exception e) {
            logger.error("添加其他押金账单行为日志,e:" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());
        }
        return count;
    }


    private void updateBillStatus(WxBillAll record) {
        logger.info("更新各账单状态开始");
        //更新其他押金账单
        //WxBillOtherDeposit wxBillOtherDeposit = new WxBillOtherDeposit();
        //wxBillOtherDeposit.setTenantId(record.getTenantId());
        //wxBillOtherDepositService.updateBillStatus(wxBillOtherDeposit);
        //更新其他账单
        WxBillOther wxBillOther = new WxBillOther();
        wxBillOther.setTenantId(record.getTenantId());
        wxBillOtherService.updateBillStatus(wxBillOther);
        //更新日常账单状态
        WxBillDaily wxBillDaily = new WxBillDaily();
        wxBillDaily.setTenantId(record.getTenantId());
        wxBillDailyService.updateBillStatus(wxBillDaily);
        //更新租赁押金账单状态
        //WxBillDeposit wxBillDeposit = new WxBillDeposit();
        //wxBillDeposit.setTenantId(record.getTenantId());
        //wxBillDepositService.updateBillStatus(wxBillDeposit);
        //更新物业押金账单状态
        //WxBillPropertyDeposit wxBillPropertyDeposit = new WxBillPropertyDeposit();
        //wxBillPropertyDeposit.setTenantId(record.getTenantId());
        //wxBillPropertyDepositService.updateBillStatus(wxBillPropertyDeposit);
        //更新物业账单状态
        WxBillProperty wxBillProperty = new WxBillProperty();
        wxBillProperty.setTenantId(record.getTenantId());
        wxBillPropertyService.updateBillStatus(wxBillProperty);
        //更新租赁账单状态
        WxBillRent wxBillRent = new WxBillRent();
        wxBillRent.setTenantId(record.getTenantId());
        wxBillRentService.updateBillStatus(wxBillRent);
        logger.info("更新各账单状态结束");
    }

    @Override
    public Object getBillInfo(WxBillAll record) {

        record.setRentShopType(EnumRentShopType.SHOP.getCode());
        record.setStatus(EnumBillRentStatus.NOT_PAID.getCode());
        Map<String, Object> oweInfoForShop = wxBillAllMapper.queryOweInfo(record);
        record.setStatus(EnumBillRentStatus.PAID.getCode());
        Map<String, Object> paidInfoForShop = wxBillAllMapper.queryPaidInfo(record);

        record.setRentShopType(EnumRentShopType.POINT.getCode());
        record.setStatus(EnumBillRentStatus.NOT_PAID.getCode());
        Map<String, Object> oweInfoForPoint = wxBillAllMapper.queryOweInfo(record);
        record.setStatus(EnumBillRentStatus.PAID.getCode());
        Map<String, Object> paidInfoForPoint = wxBillAllMapper.queryPaidInfo(record);

        Map<String, Object> result = new HashMap<>(4);
        result.put("oweInfoForShop", oweInfoForShop);
        result.put("paidInfoForShop", paidInfoForShop);
        result.put("oweInfoForPoint", oweInfoForPoint);
        result.put("paidInfoForPoint", paidInfoForPoint);
        return result;
    }

    @Override
    public Long hasOweBill(Long contractId, Integer type) {
        if(type.intValue() == 1){
            return  wxBillRentMapper.oweBillCount(contractId);
        }else if(type.intValue() == 2){
            return  wxBillPropertyMapper.oweBillCount(contractId);
        }
        return 0l;
    }

    public Map<Long, List<Map<String, Object>>> toMap(List<Map<String, Object>> mapList){
        Map<Long, List<Map<String, Object>>> result = new HashMap<>();
        for (Map<String, Object> bill:mapList) {
            Long merchantId = (Long)bill.get("merchantId");
            List<Map<String, Object>> currList = result.get(merchantId);
            if(currList == null) currList = new ArrayList<>();
            currList.add(bill);
            result.put(merchantId,currList);
        }
        return result;
    }

    @Override
    public void sendWaitPayBillEmail() {
        List<Map<String, Object>> waitBillListForEmail = wxBillAllMapper.getWaitPayBillForEmail();

        if(CollectionUtils.isNotEmpty(waitBillListForEmail)) {
            Map<Long, List<Map<String, Object>>> merchantMap = toMap(waitBillListForEmail);
            for (Long merchantId : merchantMap.keySet()) {
                List<Map<String, Object>> mapList = merchantMap.get(merchantId);
                if(CollectionUtils.isNotEmpty(mapList)){
                    String email = (String)mapList.get(0).get("email");
                    if(StringUtils.isBlank(email)){
                        continue;
                    }
                    String tenantId = (String)mapList.get(0).get("tenantId");
                    String receiveDate = (String)mapList.get(0).get("receiveDate");
                    String manager = (String)mapList.get(0).get("manager");
                    String managerPhone = (String)mapList.get(0).get("managerPhone");

                    String billListStr = "";
                    BigDecimal sumNeedPay = new BigDecimal(0);
                    for (Map<String, Object> bill : mapList) {
                        String billType = bill.get("billType").toString();
                        BigDecimal needPay = (BigDecimal) bill.get("needPay");
                        BigDecimal price = needPay.divide(new BigDecimal(100)).setScale(2, RoundingMode.HALF_EVEN);

                        sumNeedPay = sumNeedPay.add(price);
                        billListStr += "<div style=\"margin: 0 5%;width:90%;box-sizing: content-box; border: 1px solid #DEDEDE;background: #FFFFFF;\"><div style=\"overflow: hidden;height: auto;width: 100%;\">";
                        billListStr += "<div style=\"width: 33.3%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\">" + billType + "</div>";
                        billListStr += "<div style=\"width: 33.3%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\">" + price + "</div>";
                        billListStr += "<div style=\"width: 33.3%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\">" + receiveDate + "</div>";
                        billListStr += "</div></div>";
                    }
                    //发邮件
                    Map<String, String> map = new HashedMap();
                    map.put("price", sumNeedPay.toString());
                    map.put("date", receiveDate);
                    map.put("billList", billListStr);
                    map.put("linkName",manager==null?"":manager);
                    map.put("linkPhone",managerPhone==null?"":managerPhone);
                    MailMsg mailMsg = new MailMsg();
                    mailMsg.setSubject("待缴账单通知");
                    mailMsg.setHtml(true);
                    mailMsg.setMsgType(EnumMsgRecordType.EMAIL.getCode());
                    mailMsg.setModelId(EnumMailMsgModel.MAIL_BILL_WAIT_PAY.getCode());
                    mailMsg.setTo(new String[]{email});
                    mailMsg.setTenantId(tenantId);
                    mailMsg.setDynamicContentMap(map);
                    mqBaseProducer.sendMessage(mailMsg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
                }
            }
        }
    }

    @Override
    public void sendOweBillForEmail() {
        List<Map<String, Object>> oweBillForEmail = wxBillAllMapper.getOweBillForEmail();

        if(CollectionUtils.isNotEmpty(oweBillForEmail)) {
            Map<Long, List<Map<String, Object>>> merchantMap = toMap(oweBillForEmail);
            for (Long merchantId : merchantMap.keySet()) {
                List<Map<String, Object>> mapList = merchantMap.get(merchantId);
                if(CollectionUtils.isNotEmpty(mapList)){
                    String email = (String)mapList.get(0).get("email");
                    if(StringUtils.isBlank(email)){
                        continue;
                    }
                    String tenantId = (String)mapList.get(0).get("tenantId");
                    String receiveDate = (String)mapList.get(0).get("receiveDate");
                    String manager = (String)mapList.get(0).get("manager");
                    String managerPhone = (String)mapList.get(0).get("managerPhone");
                    Integer expiredDay = (Integer)mapList.get(0).get("expiredDay");

                    String billListStr = "";
                    BigDecimal sumNeedPay = new BigDecimal(0);
                    for (Map<String, Object> bill : mapList) {
                        String billType = bill.get("billType").toString();
                        BigDecimal needPay = (BigDecimal) bill.get("owe");
                        BigDecimal price = needPay.divide(new BigDecimal(100)).setScale(2, RoundingMode.HALF_EVEN);

                        sumNeedPay = sumNeedPay.add(price);
                        billListStr += "<div style=\"margin: 0 5%;width:90%;box-sizing: content-box; border: 1px solid #DEDEDE;background: #FFFFFF;\">";
                        billListStr += "<div style=\"overflow: hidden;height: auto;width: 100%;font-size:14px;\">";
                        billListStr += "<div style=\"width: 25%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\">" + billType + "</div>";
                        billListStr += "<div style=\"width: 25%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\">" + price + "</div>";
                        billListStr += "<div style=\"width: 25%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\">" + receiveDate + "</div>";
                        billListStr += "<div style=\"width: 25%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\">" + expiredDay + "</div>";
                        billListStr += "</div></div>";
                    }
                    //发邮件
                    Map<String, String> map = new HashedMap();
                    map.put("price", sumNeedPay.toString());
                    map.put("date", receiveDate);
                    map.put("billList", billListStr);
                    map.put("linkName",manager==null?"":manager);
                    map.put("linkPhone",managerPhone==null?"":managerPhone);
                    MailMsg mailMsg = new MailMsg();
                    mailMsg.setSubject("欠缴账单通知");
                    mailMsg.setHtml(true);
                    mailMsg.setMsgType(EnumMsgRecordType.EMAIL.getCode());
                    mailMsg.setModelId(EnumMailMsgModel.MAIL_BILL_OWE.getCode());
                    mailMsg.setTo(new String[]{email});
                    mailMsg.setTenantId(tenantId);
                    mailMsg.setDynamicContentMap(map);
                    mqBaseProducer.sendMessage(mailMsg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
                }
            }
        }

    }
}
