package com.zehong.system.service.impl;

import com.zehong.common.core.domain.entity.SysRole;
import com.zehong.common.core.domain.entity.SysUser;
import com.zehong.common.core.exception.BusinessException;
import com.zehong.common.utils.DateUtils;
import com.zehong.common.utils.SecurityUtils;
import com.zehong.system.domain.TAccount;
import com.zehong.system.domain.TTradeChangeInfo;
import com.zehong.system.domain.TTradeProject;
import com.zehong.system.mapper.TAccountMapper;
import com.zehong.system.mapper.TTradeChangeInfoMapper;
import com.zehong.system.mapper.TTradeProjectMapper;
import com.zehong.system.service.ITTradeProjectService;
import com.zehong.system.service.impl.tradeRoles.TradeRoles;
import com.zehong.system.service.impl.tradeRoles.roles.*;
import com.zehong.system.service.impl.tradeSettlement.SettlePendingPayment;
import com.zehong.system.service.impl.tradeSettlement.SettlementTrade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 交易项目Service业务层处理
 * 
 * @author zehong
 * @date 2023-06-08
 */
@Service
public class TTradeProjectServiceImpl implements ITTradeProjectService 
{
    @Autowired
    private TTradeProjectMapper tTradeProjectMapper;

    @Autowired
    private TTradeChangeInfoMapper tTradeChangeInfoMapper;

    @Resource
    private SettlementTrade settlementTrade;

    @Resource
    private TAccountMapper tAccountMapper;

    @Resource
    private SettlePendingPayment settlePendingPayment;

    /**
     * 查询交易项目
     * 
     * @param tradeId 交易项目ID
     * @return 交易项目
     */
    @Override
    public TTradeProject selectTTradeProjectById(Long tradeId)
    {
        return tTradeProjectMapper.selectTTradeProjectById(tradeId);
    }

    /**
     * 查询交易项目列表
     * 
     * @param tTradeProject 交易项目
     * @return 交易项目
     */
    @Override
    public List<TTradeProject> selectTTradeProjectList(TTradeProject tTradeProject)
    {
        return tTradeProjectMapper.selectTTradeProjectList(tTradeProject);
    }

    /**
     * 根据角色查询数据
     * @param tTradeProject 交易实体
     * @return
     */
    @Override
    public List<TTradeProject> selectTTradeProjectListByRoles(TTradeProject tTradeProject){
        judgeRole(tTradeProject).setQueryParams();
        List<TTradeProject> tradeProjectList = tTradeProjectMapper.selectTTradeProjectList(tTradeProject);
        for(TTradeProject project :tradeProjectList){
            judgeRole(project).setOperators();
            judgeTransferSwitch(project);
        }
        return tradeProjectList;
    }

    /**
     * 根据部门支付开关设置结算
     * @param project 交易信息
     */
    private void judgeTransferSwitch(TTradeProject project){
        Long deptId = SecurityUtils.getLoginUser().getUser().getDeptId();
        if(deptId.equals(project.getTradeDeptId()) && "3".equals(project.getTradeStatus())){
            TAccount account = new TAccount();
            account.setDeptId(project.getTradeDeptId());
            List<TAccount> accounts = tAccountMapper.selectTAccountList(account);
            if (!CollectionUtils.isEmpty(accounts)){
                String transferSwitch = accounts.get(0).getTransferSwitch();
                if("1".equals(transferSwitch) && null != project.getPendingPayment() && project.getPendingPayment().compareTo(BigDecimal.ZERO) == 1){
                    project.getOperators().add("settlePendingPayment");
                }
            }
        }
    }

    /**
     * 判断角色
     * @param tTradeProject
     * @return TradeRoles
     */
    private TradeRoles judgeRole(TTradeProject tTradeProject) {
        List<SysRole> roles = SecurityUtils.getLoginUser().getUser().getRoles();
        List<String> roleKeys = roles.stream().map(item -> item.getRoleKey()).collect(Collectors.toList());

        if(roleKeys.contains("admin")){
            return new TradeAdmin(tTradeProject);
        }
        //双权限
        if(roleKeys.contains("transactor") && roleKeys.contains("deptLeader")){
            return new DoubleRoles(tTradeProject);
        }
        //经办人
        if(roleKeys.contains("transactor")){
            return new Transactor(tTradeProject);
        }
        //部长
        if(roleKeys.contains("deptLeader")){
            return new DeptLeader(tTradeProject);
        }
        return new OtherRoles(tTradeProject);
    }

    /**
     * 新增交易项目
     * 
     * @param tTradeProject 交易项目
     * @return 结果
     */
    @Override
    public int insertTTradeProject(TTradeProject tTradeProject)
    {
        tTradeProject.setReceiptNum("ZEHONG" + DateUtils.dateTimeNow());
        SysUser user = SecurityUtils.getLoginUser().getUser();
        tTradeProject.setApplyId(user.getUserId());
        tTradeProject.setApplyDeptId(user.getDeptId());
        tTradeProject.setCreateTime(DateUtils.getNowDate());
        return tTradeProjectMapper.insertTTradeProject(tTradeProject);
    }


    /**
     * 修改交易项目
     * 
     * @param tTradeProject 交易项目
     * @return 结果
     */
    @Override
    public int updateTTradeProject(TTradeProject tTradeProject)
    {
        TTradeProject trade = tTradeProjectMapper.selectTTradeProjectById(tTradeProject.getTradeId());
        // 转移支付：新增交易转移信息，更新交易单
        if("0".equals(tTradeProject.getTradeStatus()) && tTradeProject.getTradeDeptId()!=null && tTradeProject.getTradeTransactor()!=null){
            TTradeChangeInfo tradeChangeInfo = new TTradeChangeInfo();
            tradeChangeInfo.setRelationTradeId(tTradeProject.getTradeId());
            tradeChangeInfo.setOriginalTradeDeptId(trade.getTradeDeptId());
            tradeChangeInfo.setOriginalTradeTransactorId(trade.getTradeTransactor());
            tradeChangeInfo.setNewTradeDeptId(tTradeProject.getTradeDeptId());
            tradeChangeInfo.setNewTradeTransactorId(tTradeProject.getTradeTransactor());
            tradeChangeInfo.setRemark(tTradeProject.getDealRemark());
            tradeChangeInfo.setChangeTime(tTradeProject.getEvaluateTime());

            int changeCount = trade.getChangeCount();
            if(changeCount == 0){
                tTradeProject.setChangeBy1st(trade.getTradeTransactor());
            } else if(changeCount == 1){
                tTradeProject.setChangeBy2nd(trade.getTradeTransactor());
            } else if(changeCount == 2){
                tTradeProject.setChangeBy3rd(trade.getTradeTransactor());
            } else if(changeCount == 3){
                return -1;
            }
            changeCount++;
            tTradeProject.setChangeCount(changeCount);
            tTradeProject.setTradeStatus(null);
            tTradeProject.setDealRemark(null);
            tTradeProject.setEvaluateTime(null);

            tTradeChangeInfoMapper.insertTTradeChangeInfo(tradeChangeInfo);

        } else if(tTradeProject.getTradeDeptId()==null && tTradeProject.getTradeTransactor()==null){
            tTradeProject.setChangeCount(trade.getChangeCount());
        }

        tTradeProject.setUpdateTime(DateUtils.getNowDate());
        return tTradeProjectMapper.updateTTradeProject(tTradeProject);
    }
    /**
     * 批量删除交易项目
     * 
     * @param tradeIds 需要删除的交易项目ID
     * @return 结果
     */
    @Override
    public int deleteTTradeProjectByIds(Long[] tradeIds)
    {
        return tTradeProjectMapper.deleteTTradeProjectByIds(tradeIds);
    }

    /**
     * 删除交易项目信息
     * 
     * @param tradeId 交易项目ID
     * @return 结果
     */
    @Override
    public int deleteTTradeProjectById(Long tradeId)
    {
        return tTradeProjectMapper.deleteTTradeProjectById(tradeId);
    }

    /**
     * 交易结算
     * @param tTradeProject
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int settlementTrade(TTradeProject tTradeProject){
        TTradeProject tradeInfo = tTradeProjectMapper.selectTTradeProjectById(tTradeProject.getTradeId());
        tradeInfo.setTradeStatus(tTradeProject.getTradeStatus());
        tradeInfo.setApprovalTime(tTradeProject.getApprovalTime());
        //审核成功结算
        settleByTradeStatus(tTradeProject,tradeInfo);
        if(!"5".equals(tTradeProject.getTradeStatus())){
            tradeInfo.setApplyDeptManagerId(tTradeProject.getApplyDeptManagerId());
        }
        tradeInfo.setSettlementTime(new Date());
        return tTradeProjectMapper.updateTTradeProject(tradeInfo);
    }

    /**
     * 根据交易状态结算
     * @param tTradeProject 交易入参
     * @param tradeInfo 交易信息
     */
    private void settleByTradeStatus(TTradeProject tTradeProject,TTradeProject tradeInfo){
        //审核后结算
        if("3".equals(tTradeProject.getTradeStatus())){
            if(settlementTrade.transferSwitchIsOn(tradeInfo)){
                //交易结算
                settlementTrade.settleAbleAmount(tradeInfo);
            }else{
                tradeInfo.setTradeStatus("5");
            }
            return;
        }
        //去支付
        if("5".equals(tTradeProject.getTradeStatus())){
            settlementTrade.settleAbleAmount(tradeInfo);
            tradeInfo.setTradeStatus("3");
        }

    }



    @Override
    public List<TTradeProject> getIncomeOrPayableList(TTradeProject tTradeProject) {
        return tTradeProjectMapper.getIncomeOrPayableList(tTradeProject);
    }

    @Override
    public int settlePendingPayment(TTradeProject project){
        TTradeProject tradeInfo = tTradeProjectMapper.selectTTradeProjectById(project.getTradeId());
        settlePendingPayment.settlePendingPayment(tradeInfo);
        return tTradeProjectMapper.updateTTradeProject(tradeInfo);
    }
}
