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.numerical.AnDateHelper;
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.SysFundGrant;
import cn.superdesk.uniorder.dao.entity.fund.SysFundGrantExample;
import cn.superdesk.uniorder.dao.entity.fund.SysFundUser;
import cn.superdesk.uniorder.dao.mapper.fund.SysFundGrantMapper;
import cn.superdesk.uniorder.dao.mapper.fund.SysFundGrantMapperEx;
import cn.superdesk.uniorder.dao.mapper.fund.SysFundUserMapper;
import cn.superdesk.uniorder.dao.mapper.sys.SysOderUserMapperEx;
import cn.superdesk.uniorder.dto.vo.fund.SysFundGrantVoEx;
import cn.superdesk.uniorder.dto.vo.fund.SysFundUserVoEx;
import cn.superdesk.uniorder.service.fund.SysFundGrantService;
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.dao.support.DataAccessUtils;
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 SysFundGrantServiceImpl implements SysFundGrantService {


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

    @Autowired
    private SysFundGrantMapper   sysFundGrantMapper;
    @Autowired
    private SysFundGrantMapperEx sysFundGrantMapperEx;
    @Autowired
    private SysFundUserMapper    sysFundUserMapper;
    @Autowired
    private SysOderUserMapperEx  sysOderUserMapperEx;


    @Override
    public int insertSelective(SysFundGrant sysFundGrant) {
        sysFundGrant.setCreateTime(DateUtil.date());
        return sysFundGrantMapper.insertSelective(sysFundGrant);
    }

    @Override
    public int updateByPrimaryKeySelective(SysFundGrant sysFundGrant) {
        return sysFundGrantMapper.updateByPrimaryKeySelective(sysFundGrant);
    }

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

    @Override
    public SysFundGrant findById(Long id) {
        return sysFundGrantMapper.selectByPrimaryKey(id);
    }


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

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

    @Override
    public SysFundGrant findByInvoiceNumber(String invoiceNumber) {

        SysFundGrantExample example = new SysFundGrantExample();
        example.or().andInvoiceNumberEqualTo(invoiceNumber);

        List<SysFundGrant> sysFundGrantList = sysFundGrantMapper.selectByExample(example);

        return DataAccessUtils.uniqueResult(sysFundGrantList);
    }

    @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 allInvoiceCount = new BigDecimal("0");
            BigDecimal allFundCount    = new BigDecimal("0");

            for (Map<String, Object> map2 : list) {

                String invoiceNumber = map2.get("invoiceNumber").toString();

                if (StringUtils.isBlank(invoiceNumber)) {
                    throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "存在发票号为空");
                }

                BigDecimal invoiceCount = new BigDecimal(map2.get("invoiceCount").toString());
                if (invoiceCount == 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(), "存在基金金额为空");
                }

                SysFundGrantExample example = new SysFundGrantExample();
                example.or().andInvoiceNumberEqualTo(invoiceNumber);
                if (sysFundGrantMapper.countByExample(example) > 0) {
                    throw new UnifiedOrderRuntimeException(ExceptionMsg.INVOICENO_EXIST);
                }

                // 添加发放记录
                SysFundGrant sysFundGrant = new SysFundGrant();
                sysFundGrant.setInvoiceNumber(invoiceNumber);
                sysFundGrant.setInvoiceCount(invoiceCount);
                sysFundGrant.setFundCount(fundCount);
                sysFundGrant.setNoCheckCount(sysFundGrant.getInvoiceCount());
                sysFundGrant.setFundUserId(sysFundUserVO.getId());
                sysFundGrant.setNoActivatedFund(fundCount);
                sysFundGrant.setCreateUserId(loginSysUser.getSysUserId());
                sysFundGrant.setCreateTime(AnDateHelper.getNow());
                sysFundGrantMapper.insertSelective(sysFundGrant);

                // 修改基金用户信息
                SysFundUser sysFundUser = sysFundUserMapper.selectByPrimaryKey(sysFundGrant.getFundUserId());
                if (sysFundUser == null) {
                    throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "基金用户Id不能为空");
                }
                sysFundUser.setInvoiceCount(sysFundUser.getInvoiceCount().add(sysFundGrant.getInvoiceCount()));
                sysFundUser.setNoActivatedFund(sysFundUser.getNoActivatedFund().add(sysFundGrant.getFundCount()));
                sysFundUser.setUpdateUserId(loginSysUser.getSysUserId());
                sysFundUser.setUpdateTime(AnDateHelper.getNow());
                sysFundUserMapper.updateByPrimaryKeySelective(sysFundUser);

                //把统一基金用户的开票金额和基金金额加起来
                allInvoiceCount = allInvoiceCount.add(sysFundGrant.getInvoiceCount());
                allFundCount = allFundCount.add(sysFundGrant.getFundCount());
            }
            pushMessageParams.put("id", sysFundUserVO.getUserId());
            pushMessageParams.put("mobile", mobile);
            pushMessageParams.put("realname", sysFundUserVO.getRealname());
            pushMessageParams.put("organizationName", sysFundUserVO.getOrganizationName());
            pushMessageParams.put("invoiceCount", allInvoiceCount);
            pushMessageParams.put("fundCount", allFundCount);
            pushMessageList.add(pushMessageParams);
        }
        for (Map<String, Object> pushMessageParams : pushMessageList) {
            String res = PushUtil.pushGrantMessage(
                    orgId,
                    pushMessageUrl,
                    h5url,
                    pushMessageParams.get("id").toString(),
                    pushMessageParams.get("realname").toString(),
                    pushMessageParams.get("mobile").toString(),
                    pushMessageParams.get("organizationName").toString(),
                    pushMessageParams.get("invoiceCount").toString(),
                    pushMessageParams.get("fundCount").toString());
            log.info("电话:" + pushMessageParams.get("mobile").toString() + "到账短信推送========>" + res);
        }
    }

    @Override
    public void create(SysFundGrant sysFundGrant, String token) throws UnifiedOrderRuntimeException {

        LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(token);

        if (StringUtils.isBlank(sysFundGrant.getInvoiceNumber())) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "发票号不能为空");
        }
        if (sysFundGrant.getInvoiceCount() == null) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "发票金额不能为空");
        }
        if (sysFundGrant.getFundCount() == null) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "基金金额不能为空");
        }

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

        SysFundGrantExample example = new SysFundGrantExample();
        example.or().andInvoiceNumberEqualTo(sysFundGrant.getInvoiceNumber());
        if (sysFundGrantMapper.countByExample(example) > 0) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.INVOICENO_EXIST);
        }

        sysFundGrant.setNoActivatedFund(sysFundGrant.getFundCount());
        sysFundGrant.setCreateUserId(loginSysUser.getSysUserId());
        sysFundGrant.setCreateTime(AnDateHelper.getNow());
        sysFundGrant.setNoCheckCount(sysFundGrant.getInvoiceCount());
        sysFundGrantMapper.insertSelective(sysFundGrant);

        sysFundUser.setInvoiceCount(sysFundUser.getInvoiceCount().add(sysFundGrant.getInvoiceCount()));
        sysFundUser.setNoActivatedFund(sysFundUser.getNoActivatedFund().add(sysFundGrant.getFundCount()));
        sysFundUser.setUpdateUserId(loginSysUser.getSysUserId());
        sysFundUser.setUpdateTime(AnDateHelper.getNow());
        sysFundUserMapper.updateByPrimaryKeySelective(sysFundUser);

        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.pushGrantMessage(
                orgId,
                pushMessageUrl,
                h5url,
                sysFundUserVO.getUserId().toString(),
                sysFundUserVO.getRealname(),
                sysFundUserVO.getMobile(),
                sysFundUserVO.getOrganizationName(),
                sysFundGrant.getInvoiceCount().toString(),
                sysFundGrant.getFundCount().toString());
        log.info("电话:" + sysFundUserVO.getMobile() + "到账短信推送========>" + res);
    }

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

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

    }
}
