package cn.superdesk.uniorder.service.fund.impl;

import cn.hutool.core.date.DateUtil;
import cn.superdesk.uniorder.common.exception.UnifiedOrderRuntimeException;
import cn.superdesk.uniorder.common.exception.constants.ExceptionMsg;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.security.JwtUtil;
import cn.superdesk.uniorder.common.security.PushUtil;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.fund.SysFundActivated;
import cn.superdesk.uniorder.dao.entity.fund.SysFundGrant;
import cn.superdesk.uniorder.dao.entity.fund.SysFundUser;
import cn.superdesk.uniorder.dao.mapper.fund.SysFundActivatedMapper;
import cn.superdesk.uniorder.dao.mapper.fund.SysFundActivatedMapperEx;
import cn.superdesk.uniorder.dao.mapper.fund.SysFundUserMapper;
import cn.superdesk.uniorder.dto.vo.fund.SysFundActivatedVoEx;
import cn.superdesk.uniorder.dto.vo.fund.SysFundUserVoEx;
import cn.superdesk.uniorder.service.fund.SysFundActivatedService;
import cn.superdesk.uniorder.service.fund.SysFundGrantService;
import cn.superdesk.uniorder.service.fund.SysFundUserService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@Transactional
public class SysFundActivatedServiceImpl implements SysFundActivatedService {


    @Value("${h5.url}")
    private String h5url;
    @Value("${pushMessage.orgId}")
    private String orgId;
    @Value("${pushMessage.url}")
    private String pushMessageUrl;


    @Autowired
    private SysFundActivatedMapper   sysFundActivatedMapper;
    @Autowired
    private SysFundActivatedMapperEx sysFundActivatedMapperEx;

    @Autowired
    private SysFundGrantService sysFundGrantService;

    @Autowired
    private SysFundUserMapper  sysFundUserMapper;
    @Autowired
    private SysFundUserService sysFundUserService;


    @Override
    public int insertSelective(SysFundActivated sysFundActivated) {
        sysFundActivated.setCreateTime(DateUtil.date());
        return sysFundActivatedMapper.insertSelective(sysFundActivated);
    }

    @Override
    public int updateByPrimaryKeySelective(SysFundActivated sysFundActivated) {
        sysFundActivated.setCheckTime(DateUtil.date());
        return sysFundActivatedMapper.updateByPrimaryKeySelective(sysFundActivated);
    }

    @Override
    public void deleteObj(Long id) {
        sysFundActivatedMapper.deleteByPrimaryKey(id);
    }


    @Override
    public SysFundActivated findById(Long id) {
        return sysFundActivatedMapper.selectByPrimaryKey(id);
    }


    @Override
    public List<SysFundActivated> findAll(Map<String, Object> queryMap) {
        return null;
    }

    @Override
    public PageInfo<SysFundActivated> findByPaging(Map<String, Object> params, Integer pageNo, Integer pageSize) {
        return null;
    }

    @Override
    public void create(SysFundActivated sysFundActivated, String token) throws UnifiedOrderRuntimeException {

        LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(token);

        if (StringUtils.isBlank(sysFundActivated.getInvoiceNumber())) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "发票号不能为空");
        }
        if (sysFundActivated.getCheckCount() == null) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "核销金额不能为空");
        }
        if (sysFundActivated.getFundCount() == null) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "激活基金金额不能为空");
        }

        SysFundGrant sysFundGrant = sysFundGrantService.findByInvoiceNumber(sysFundActivated.getInvoiceNumber());
        if (sysFundGrant == null) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "发票号不存在");
        }

        if (sysFundActivated.getFundUserId() == null) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "基金用户Id不能为空");
        }
        SysFundUser sysFundUser = sysFundUserService.findById(sysFundActivated.getFundUserId());

        // 检测核销金额是否大于发票金额
//		sysFundGrant.getInvoiceCount().compareTo(sysFundActivated.getCheckCount()) == -1
        if (sysFundGrant.getInvoiceCount().compareTo(sysFundActivated.getCheckCount()) < 0) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "核销金额过大");
        }
        // 检测激活基金金额是否大于待激活基金金额
        int flag = sysFundGrant.getNoActivatedFund().compareTo(sysFundActivated.getFundCount());
        if (flag == -1) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "激活基金金额过大");
        } else if (flag == 0) {
            sysFundGrant.setActivatedStatus(2);
        } else {
            sysFundGrant.setActivatedStatus(1);
        }
        // 未核销金额-核销金额
        sysFundGrant.setNoCheckCount(sysFundGrant.getNoCheckCount().subtract(sysFundActivated.getCheckCount()));
        // 待激活基金-激活基金
        sysFundGrant.setNoActivatedFund(sysFundGrant.getNoActivatedFund().subtract(sysFundActivated.getFundCount()));
        sysFundGrantService.updateByPrimaryKeySelective(sysFundGrant);

        // 待激活基金-激活基金
        sysFundUser.setNoActivatedFund(sysFundUser.getNoActivatedFund().subtract(sysFundActivated.getFundCount()));
        // 发放基金余额+激活基金
        sysFundUser.setActivatedFundCount(sysFundUser.getActivatedFundCount().add(sysFundActivated.getFundCount()));
        sysFundUser.setUpdateUserId(loginSysUser.getSysUserId());
        sysFundUserService.updateByPrimaryKeySelective(sysFundUser);

        // 添加记录
        sysFundActivated.setCreateUserId(loginSysUser.getSysUserId());
        sysFundActivated.setCreateTime(DateUtil.date());
        sysFundActivatedMapper.insertSelective(sysFundActivated);

        Map<String, Object> params = new HashMap<>();
        params.put("userId", sysFundUser.getUserId());
        List<SysFundUserVoEx> sysFundUserVOList = sysFundUserMapper.selectByCondition(params);
        SysFundUserVoEx       sysFundUserVO     = sysFundUserVOList.get(0);
        String res = PushUtil.pushActivatedMessage(
                orgId,
                pushMessageUrl,
                h5url,
                sysFundUserVO.getUserId().toString(),
                sysFundUserVO.getRealname(),
                sysFundUserVO.getMobile(),
                sysFundUserVO.getOrganizationName(),
                sysFundActivated.getFundCount().toString(),
                sysFundUserVO.getGrantFundBalance().toString());
        log.info("电话:" + sysFundUserVO.getMobile() + "到账短信推送========>" + res);
    }

    @Override
    public void update(SysFundActivated sysFundActivated, String token) throws UnifiedOrderRuntimeException {
        LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(token);

        if (sysFundActivated.getId() == null) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "Id不能为空");
        }

        sysFundActivated.setActivatedStatus(1);
        sysFundActivated.setCreateUserId(loginSysUser.getSysUserId());
        sysFundActivated.setCheckTime(DateUtil.date());
        sysFundActivatedMapper.updateByPrimaryKeySelective(sysFundActivated);
    }

    @Override
    public R<List<SysFundActivatedVoEx>> findAllViewPage(Map<String, Object> params, int pageNum, int pageSize) {

        PageHelper.startPage(pageNum, pageSize);
        List<SysFundActivatedVoEx>     resultList = sysFundActivatedMapperEx.selectByCondition(params);
        PageInfo<SysFundActivatedVoEx> page       = new PageInfo<SysFundActivatedVoEx>(resultList);
        PageHelper.clearPage();
        return new R<List<SysFundActivatedVoEx>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), resultList);

    }

    @Override
    public void importExcel(Map<String, List<Map<String, Object>>> map, String token) throws UnifiedOrderRuntimeException {

        LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(token);

        // 保存推送信息,避免回滚依旧发送短信
        List<Map<String, Object>> pushMessageList = new ArrayList<>();

        // 循环mobile分类
        for (Map.Entry<String, List<Map<String, Object>>> entry : map.entrySet()) {
            Map<String, Object> pushMessageParams = new HashMap<>();
            String              mobile            = entry.getKey();

            Map<String, Object> params = new HashMap<>();
            params.put("mobile", mobile);

            List<SysFundUserVoEx> sysFundUserVOList = sysFundUserMapper.selectByCondition(params);

            if (sysFundUserVOList == null || sysFundUserVOList.size() == 0) {
                throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "电话:" + mobile + "得基金用户不存在");
            }

            SysFundUserVoEx sysFundUserVO = sysFundUserVOList.get(0);

            List<Map<String, Object>> list = map.get(mobile);

            BigDecimal allActivatedFundCount = new BigDecimal("0");
            BigDecimal allFundCount          = new BigDecimal("0");

            for (Map<String, Object> map2 : list) {
                SysFundActivated sysFundActivated = new SysFundActivated();

                String invoiceNumber = map2.get("invoiceNumber").toString();
                if (StringUtils.isBlank(invoiceNumber)) {
                    throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "存在发票号为空");
                }
                BigDecimal checkCount = new BigDecimal(map2.get("checkCount").toString());
                if (checkCount == null) {
                    throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "存在核销金额为空");
                }
                BigDecimal fundCount = new BigDecimal(map2.get("fundCount").toString());
                if (fundCount == null) {
                    throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "存在基金金额为空");
                }
                sysFundActivated.setInvoiceNumber(invoiceNumber);
                sysFundActivated.setCheckCount(checkCount);
                sysFundActivated.setFundCount(fundCount);
                sysFundActivated.setFundUserId(sysFundUserVO.getId());

                SysFundGrant sysFundGrant = sysFundGrantService.findByInvoiceNumber(sysFundActivated.getInvoiceNumber());
                if (sysFundGrant == null) {
                    throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), invoiceNumber + "该发票号不存在");
                }
                // 检测核销金额是否大于发票金额
//				sysFundGrant.getInvoiceCount().compareTo(sysFundActivated.getCheckCount()) == -1
                if (sysFundGrant.getInvoiceCount().compareTo(sysFundActivated.getCheckCount()) < 0) {
                    throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "核销金额过大");
                }
                // 检测激活基金金额是否大于待激活基金金额
                int flag = sysFundGrant.getNoActivatedFund().compareTo(sysFundActivated.getFundCount());
//				flag == -1
                if (flag < 0) {
                    throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "激活基金过大");
                } else if (flag == 0) {
                    sysFundGrant.setActivatedStatus(2);
                } else {
                    sysFundGrant.setActivatedStatus(1);
                }
                // 未核销金额-核销金额
                sysFundGrant.setNoCheckCount(sysFundGrant.getNoCheckCount().subtract(sysFundActivated.getCheckCount()));
                // 待激活基金-激活基金
                sysFundGrant.setNoActivatedFund(sysFundGrant.getNoActivatedFund().subtract(sysFundActivated.getFundCount()));
                sysFundGrantService.updateByPrimaryKeySelective(sysFundGrant);

                SysFundUser sysFundUser = sysFundUserService.findById(sysFundActivated.getFundUserId());

                // 待激活基金-激活基金
                sysFundUser.setNoActivatedFund(sysFundUser.getNoActivatedFund().subtract(sysFundActivated.getFundCount()));
                // 发放基金余额+激活基金
                sysFundUser.setActivatedFundCount(sysFundUser.getActivatedFundCount().add(sysFundActivated.getFundCount()));
                sysFundUser.setUpdateUserId(loginSysUser.getSysUserId());
                sysFundUserService.updateByPrimaryKeySelective(sysFundUser);

                // 添加记录
                sysFundActivated.setCreateUserId(loginSysUser.getSysUserId());
                sysFundActivated.setCreateTime(DateUtil.date());
                sysFundActivatedMapper.insertSelective(sysFundActivated);

                // 把统一基金用户的开票金额和基金金额加起来
                allFundCount = allFundCount.add(sysFundGrant.getFundCount());
                allActivatedFundCount = sysFundUser.getActivatedFundCount();
            }

            pushMessageParams.put("id", sysFundUserVO.getUserId());
            pushMessageParams.put("mobile", mobile);
            pushMessageParams.put("realname", sysFundUserVO.getRealname());
            pushMessageParams.put("organizationName", sysFundUserVO.getOrganizationName());
            pushMessageParams.put("fundCount", allFundCount);
            pushMessageParams.put("grantFundBalance", allActivatedFundCount.subtract(sysFundUserVO.getConsumerFund()));

            pushMessageList.add(pushMessageParams);

        }
        for (Map<String, Object> pushMessageParams : pushMessageList) {

            String res = PushUtil.pushActivatedMessage(
                    orgId,
                    pushMessageUrl,
                    h5url,
                    pushMessageParams.get("id").toString(),
                    pushMessageParams.get("realname").toString(),
                    pushMessageParams.get("mobile").toString(),
                    pushMessageParams.get("organizationName").toString(),
                    pushMessageParams.get("fundCount").toString(),
                    pushMessageParams.get("grantFundBalance").toString()
            );

            log.info("电话:" + pushMessageParams.get("mobile").toString() + "到账短信推送========>" + res + "==内容======>" + pushMessageParams);
        }
    }
}
