package com.goafanti.ambSystem.service.Impl;

import com.goafanti.ambSystem.bo.InputAmbInvest;
import com.goafanti.ambSystem.bo.InputInvestList;
import com.goafanti.ambSystem.bo.OutInvestList;
import com.goafanti.ambSystem.bo.OutInvestLog;
import com.goafanti.ambSystem.service.AmbInvestService;
import com.goafanti.common.constant.AFTConstants;
import com.goafanti.common.dao.AmbInvestLogMapper;
import com.goafanti.common.dao.AmbInvestMapper;
import com.goafanti.common.dao.AmbSystemMapper;
import com.goafanti.common.enums.NoticeStatus;
import com.goafanti.common.error.BusinessException;
import com.goafanti.common.model.AmbInvest;
import com.goafanti.common.model.AmbInvestLog;
import com.goafanti.common.model.AmbSystem;
import com.goafanti.common.utils.AsyncUtils;
import com.goafanti.common.utils.StringUtils;
import com.goafanti.core.mybatis.BaseMybatisDao;
import com.goafanti.core.mybatis.page.Pagination;
import com.goafanti.core.shiro.token.TokenManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.print.attribute.standard.MediaSize;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class AmbInvestServiceImpl extends BaseMybatisDao<AmbInvestMapper> implements AmbInvestService {
    @Autowired
    private AmbSystemMapper ambSystemMapper;
    @Autowired
    private AmbInvestMapper ambInvestMapper;
    @Autowired
    private AmbInvestLogMapper ambInvestLogMapper;
    @Autowired
    private AsyncUtils asyncUtils;



    @Override
    @Transactional
    public int pushInvestTransfer(InputAmbInvest in) {
        AmbSystem myAmb =null;
        AmbInvest ambInvest=new AmbInvest();

        if (in.getRoleType()==1){
            myAmb= ambSystemMapper.selectByPrimaryKey(1l);
        }else {
            myAmb=ambSystemMapper.selectByPrimaryKey(in.getMyAmbId());
            chekAmount(in, myAmb);
        }
        ambInvest.setInitiateAmbId(myAmb.getId());
        ambInvest.setAcceptAmbId(in.getOtherAmbId());
        ambInvest.setAmount(in.getAmount());
        ambInvest.setStatus(in.getStatus());
        ambInvest.setOperator(TokenManager.getAdminId());
        ambInvest.setComment(in.getComment());
        AmbSystem other=ambSystemMapper.selectByPrimaryKey(in.getOtherAmbId());
        //计算累计金额
        ambInvest.setCountAmount(sumCountAmount( ambInvest));
        ambInvestMapper.insertSelective(ambInvest);
        addAmbInvestLog(in, ambInvest);
        if (in.getStatus()==1)addNoticAndEmail(1,myAmb,other);
        return 1;
    }

    /**
     *
     * @param in 当前数据
     * @param myAmb 发起方
     */
    private void chekAmount(InputAmbInvest in, AmbSystem myAmb) {
            BigDecimal count = new BigDecimal(0);
            List<OutInvestList> outInvestLists = ambInvestMapper.selectAmbInvestDtailsList(in.getMyAmbId(), 0);
            for (OutInvestList out : outInvestLists) {
                if (in.getId()!=null&&!in.getId().equals(out.getId())){
                    count=count.add(out.getAmount());
                }
            }
            count=count.add(in.getAmount());
        if (myAmb.getLvl()!=1){
            if (count.compareTo(myAmb.getSurplus())>0){
                throw new BusinessException("发起投资金额不可大于剩余投资金额！（注意：包含审核中投资金额）");
            }
        }
    }



    private BigDecimal sumCountAmount( AmbInvest ambInvest) {
        BigDecimal count=ambInvestMapper.selectCountAmountById(ambInvest.getInitiateAmbId(),ambInvest.getAcceptAmbId());
        return count!=null?count:new BigDecimal(0);
    }

    private void addNoticAndEmail(Integer i,AmbSystem myAmb,AmbSystem other) {
        StringBuffer str=new StringBuffer();
        Integer notceType=0;
        String aid="";
        if (i==1){
            aid=myAmb.getAccountant();
            str=str.append("[").append(myAmb.getName()).append("]负责人发起了对[").append(other.getName()).append("]的金额投资，请及时确认！");
            notceType=NoticeStatus.AMB_INVEST_START.getCode();
        }else if (i==2){
            str=str.append("发起的对[").append(other.getName()).append("]"+"的金额投资，已通过审核！");
            notceType=NoticeStatus.AMB_INVEST_YES.getCode();
            aid=myAmb.getLeader();
            if(StringUtils.isNotBlank(other.getLeader())){
                StringBuffer str2=new StringBuffer()
                        .append("[").append(myAmb.getName()).append("]负责人对[").append(other.getName()).append("]的金额投资已完成，请及时确认！");
                asyncUtils.addNoticAndEmail(other.getLeader(),notceType ,str2.toString());
            }
        }else if (i==3){
            str=str.append("发起的对[").append(other.getName()).append("]"+"的金额投资，已拒绝，请及时修改！");
            notceType=NoticeStatus.AMB_INVEST_NO.getCode();
            aid=myAmb.getLeader();
        }
           if(aid!=null) asyncUtils.addNoticAndEmail(aid,notceType ,str.toString());
    }

    @Override
    public boolean checkMyAmb(Long myAmbId) {
        AmbSystem myAmb = ambSystemMapper.selectByPrimaryKey(myAmbId);
        if (!myAmb.getLeader().equals(TokenManager.getAdminId())){
            return true;
        }
        return false;
    }

    @Override
    public Pagination<?> InvestList(InputInvestList in) {
        Map<String,Object> params=new HashMap<>();
        if (in.getRoleType()!=null){
            params.put("roleType",in.getRoleType());
            params.put("aid",TokenManager.getAdminId());
        }
        if (in.getOperator()!=null)params.put("operator",in.getOperator());
        params.put("startTime",in.getStartTime());
        params.put("endTime",in.getEndTime()+" 23:59:59");
        params.put("status",in.getStatus());
        params.put("initiateAmbId",in.getInitiateAmbId());
        params.put("acceptAmbId",in.getAcceptAmbId());


        return findPage("selectInvestList","selectInvestCount",params,in.getPageNo(),in.getPageSize());
    }

    @Override
    public List<OutInvestLog> InvestLog(String id) {
        return ambInvestLogMapper.selectByAmbInvestId(id);
    }

    @Override
    public int updateInvestTransfer(InputAmbInvest in) {
        AmbSystem myAmb = ambSystemMapper.selectByPrimaryKey(in.getMyAmbId());
        if(in.getRoleType()==0){
            chekAmount(in, myAmb);
        }
        AmbSystem other=ambSystemMapper.selectByPrimaryKey(in.getOtherAmbId());
        AmbInvest ambInvest=new AmbInvest();
        ambInvest.setId(in.getId());
        if (in.getOtherAmbId()!=null)ambInvest.setAcceptAmbId(in.getOtherAmbId());
        if (in.getAmount()!=null)ambInvest.setAmount(in.getAmount());
        if (in.getStatus()!=null)ambInvest.setStatus(in.getStatus());
        if (in.getComment()!=null)ambInvest.setComment(in.getComment());
        ambInvest.setOperator(TokenManager.getAdminId());
        ambInvestMapper.updateByPrimaryKeySelective(ambInvest);
        addAmbInvestLog(in, ambInvest);
        if (in.getStatus()==1)addNoticAndEmail(1,myAmb,other);
        return 1;
    }

    @Override
    @Transactional
    public int updateExamineTransfer(InputAmbInvest in) {
        AmbInvest ambInvest = ambInvestMapper.selectByPrimaryKey(in.getId());
        if (ambInvest.getStatus()==2){
            throw new BusinessException("重复通过。");
        }
        AmbSystem myAmb = ambSystemMapper.selectByPrimaryKey(ambInvest.getInitiateAmbId());
        AmbSystem other=ambSystemMapper.selectByPrimaryKey(ambInvest.getAcceptAmbId());
        AmbInvest newAmbInvest=new AmbInvest();
        newAmbInvest.setId(in.getId());
        newAmbInvest.setStatus(in.getStatus());
        newAmbInvest.setAmount(ambInvest.getAmount());
        if (in.getStatus()==2){
                AmbSystem newMy=new AmbSystem();
                newMy.setId(myAmb.getId());
            if (myAmb.getId()==1L){
                newMy.setForeign(myAmb.getForeign().add(ambInvest.getAmount()));
            }else {
                newMy.setForeign(myAmb.getForeign().add(ambInvest.getAmount()));
                newMy.setTotalAmount(myAmb.getTotalAmount().subtract(ambInvest.getAmount()));
                newMy.setSurplus(myAmb.getSurplus().subtract(ambInvest.getAmount()));
            }
            ambSystemMapper.updateByPrimaryKeySelective(newMy);
            AmbSystem newOther=new AmbSystem();
            newOther.setId(other.getId());
            newOther.setReceived(other.getReceived().add(ambInvest.getAmount()));
            newOther.setSurplus(other.getSurplus().add(ambInvest.getAmount()));
            newOther.setTotalAmount(other.getTotalAmount().add(ambInvest.getAmount()));
            ambSystemMapper.updateByPrimaryKeySelective(newOther);
            //计算累计金额
            newAmbInvest.setCountAmount(sumCountAmount(ambInvest).add(ambInvest.getAmount()));
        }
        ambInvestMapper.updateByPrimaryKeySelective(newAmbInvest);
        addAmbInvestLog(in, ambInvest);
        addNoticAndEmail(in.getStatus(),myAmb,other);
        return 1;
    }


    private void addAmbInvestLog(InputAmbInvest in, AmbInvest ambInvest) {
        AmbInvestLog log = new AmbInvestLog();
        log.setAmbInvestId(ambInvest.getId());
        log.setComment(in.getComment());
        log.setOperator(TokenManager.getAdminId());
        log.setStatus(in.getStatus());
        ambInvestLogMapper.insertSelective(log);
    }

    @Override
    public List<AmbSystem> getInvestAmbList(Long id) {
        AmbSystem ambSystem = ambSystemMapper.selectByPrimaryKey(id);
        return ambSystemMapper.selectBySuperId(ambSystem);
    }




}
