package com.fjhx.sale.service.claim.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.account.entity.account.po.AccountRunningWater;
import com.fjhx.account.service.account.AccountRunningWaterService;
import com.fjhx.file.utils.ObsFileUtil;
import com.fjhx.sale.entity.claim.dto.ClaimDto;
import com.fjhx.sale.entity.claim.dto.ClaimSelectDto;
import com.fjhx.sale.entity.claim.po.Claim;
import com.fjhx.sale.entity.claim.po.ClaimContract;
import com.fjhx.sale.entity.claim.vo.ClaimContractVo;
import com.fjhx.sale.entity.claim.vo.ClaimVo;
import com.fjhx.sale.mapper.claim.ClaimMapper;
import com.fjhx.sale.service.claim.ClaimContractService;
import com.fjhx.sale.service.claim.ClaimService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.ruoyi.system.utils.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>
 * 到账认领 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-18
 */
@Service
public class ClaimServiceImpl extends ServiceImpl<ClaimMapper, Claim> implements ClaimService {

    @Autowired
    private ClaimContractService claimContractService;


    @Autowired
    private AccountRunningWaterService accountRunningWaterService;

    @Override
    public Page<ClaimVo> getPage(ClaimSelectDto dto) {
        IWrapper<Claim> wrapper = getWrapper();
        wrapper.orderByDesc("c", Claim::getId);
        Page<ClaimVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        return page;
    }

    @Override
    public ClaimVo detail(Long id) {
        Claim Claim = this.getById(id);
        ClaimVo result = BeanUtil.toBean(Claim, ClaimVo.class);
        return result;
    }

    /**
     * 添加
     * @param claim
     */
    @Override
    @DSTransactional
    public synchronized void add(Claim claim) {
//        Claim data = this.getOne(Wrappers.<Claim>query().lambda().eq(Claim::getBusinessId,claim.getBusinessId()));
        if(ObjectUtils.isEmpty(claim.getBusinessId())){
            throw new ServiceException("请选择认领数据");
        }
        if(ObjectUtils.isEmpty(claim.getAmount())){
            throw new ServiceException("认领金额不能为空");
        }
        AccountRunningWater water = accountRunningWaterService.getById(claim.getBusinessId());
        if(water.getClaimAmount().add(claim.getAmount()).compareTo(water.getAmount())>0){//如果认领金额>流水金额---驳回
            throw new ServiceException("认领金额不能大于流水金额");
        }
        claim.setClaimUserId(SecurityUtils.getUserId());
        claim.setClaimUserName(SecurityUtils.getUsername());
        this.save(claim);
        List<ClaimContract> claimContractList = claim.getClaimContractList();
        if(CollectionUtils.isNotEmpty(claim.getClaimContractList())){
            for(ClaimContract c:claimContractList){
                c.setRate(claim.getRate());
                c.setClaimId(claim.getId());
            }
            claimContractService.saveBatch(claimContractList);
        }
        //更新流水数据已认领金额
        if(water.getClaimAmount().add(claim.getAmount()).compareTo(water.getAmount())==0){//如果认领金额=流水金额
            water.setIsClaim(1);//已认领状态
        }else{
            water.setIsClaim(2);//部分认领
        }
        water.setClaimAmount(water.getClaimAmount().add(claim.getAmount()));
        accountRunningWaterService.updateById(water);
        ObsFileUtil.saveFile(claim.getFileList(),claim.getId());
    }

    @Override
    public void edit(ClaimDto claimDto) {
        this.updateById(claimDto);
    }

    /**
     * 删除
     * @param id 流水ID
     */
    @Override
    @DSTransactional
    public void delete(Long id) {
        //通过流水ID查找出到账认领的数据
        List<Claim> claimList = this.list(Wrappers.<Claim>query().lambda().eq(Claim::getBusinessId, id));
        if (CollectionUtils.isEmpty(claimList)) {
            throw new ServiceException("当前流水暂无认领合同,不能取消认领");
        }
        List<Long> claimIds = claimList.stream().map(Claim::getId).collect(Collectors.toList());
        this.removeBatchByIds(claimIds);
        claimContractService.remove(Wrappers.<ClaimContract>query().lambda().in(ClaimContract::getClaimId, claimIds));
        //更新流水数据为认领状态---已认领金额还原
        AccountRunningWater water = new AccountRunningWater();
        water.setId(id);
        water.setIsClaim(0);//未认领状态
        water.setClaimAmount(BigDecimal.ZERO);
        accountRunningWaterService.updateById(water);
    }

    /**
     * 查询已认领金额
     * @param businessId
     */
    @Override
    public BigDecimal sumClaimMoney(Long businessId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.select("IFNULL(SUM(amount),0) AS sumAmount");
        queryWrapper.eq("business_id",businessId);
        Claim claim = this.getOne(queryWrapper);
        return claim==null?BigDecimal.ZERO:claim.getSumAmount();
    }

    /**
     * 查询认领记录 businessId 流水表ID
     */
    @Override
    public List<ClaimContractVo>  claimRecord(Long businessId) {
        //查询认领合同表的信息
        List<ClaimContractVo> claimContractVoList = baseMapper.claimRecord(Wrappers.<Claim>lambdaQuery().eq(Claim::getBusinessId, businessId));

        // 赋值用户名称
        UserUtil.assignmentNickName(claimContractVoList,ClaimContractVo::getClaimUserId, ClaimContractVo::setClaimUserName);

        return claimContractVoList;
    }

}
