package com.fjhx.account.service.write.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
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.*;
import com.fjhx.account.entity.write.dto.WriteOffRecordsDto;
import com.fjhx.account.entity.write.dto.WriteOffRecordsSelectDto;
import com.fjhx.account.entity.write.po.WriteOffRecords;
import com.fjhx.account.entity.write.vo.WriteOffRecordsVo;
import com.fjhx.account.mapper.write.WriteOffRecordsMapper;
import com.fjhx.account.service.account.*;
import com.fjhx.account.service.write.WriteOffRecordsService;
import com.fjhx.common.service.corporation.CorporationService;
import com.fjhx.common.utils.Assert;
import com.fjhx.file.utils.ObsFileUtil;
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;


/**
 * <p>
 * 冲销记录表 服务实现类
 * </p>
 *
 * @author
 * @since 2023-07-12
 */
@Service
public class WriteOffRecordsServiceImpl extends ServiceImpl<WriteOffRecordsMapper, WriteOffRecords> implements WriteOffRecordsService {
    @Autowired
    private CorporationService corporationService;
    @Autowired
    private AccountPaymentService accountPaymentService;
    @Autowired
    private AccountRemainderService accountRemainderService;
    @Autowired
    private AccountRunningWaterService accountRunningWaterService;
    @Autowired
    private AccountPaymentRecordsService accountPaymentRecordsService;
    @Autowired
    private AccountManagementService accountManagementService;

    @Override
    public Page<WriteOffRecordsVo> getPage(WriteOffRecordsSelectDto dto) {
        IWrapper<WriteOffRecords> wrapper = getWrapper();
        wrapper.eq("ap.corporation_id", dto.getCorporationId());
        wrapper.eq("ap.type", dto.getType());

        //权限过滤：冲销记录
        wrapper.eq("wor.company_id", SecurityUtils.getCompanyId());

        wrapper.orderByDesc("wor", WriteOffRecords::getId);
        Page<WriteOffRecordsVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        List<WriteOffRecordsVo> records = page.getRecords();
        //赋值归属公司
        corporationService.attributeAssign(records, WriteOffRecordsVo::getCorporationId, (item, corporation) -> {
            item.setCorporationName(corporation.getName());
        });
        //赋值冲销人
        UserUtil.assignmentNickName(records, WriteOffRecordsVo::getCreateUser, WriteOffRecordsVo::setWriteOffUserName);
        return page;
    }

    @Override
    @DSTransactional
    public void add(WriteOffRecordsDto writeOffRecordsDto) {
        Assert.notEmpty(writeOffRecordsDto.getAccountPaymentId(), "打款id不能为空");
        AccountPayment accountPayment = accountPaymentService.getById(writeOffRecordsDto.getAccountPaymentId());
        Assert.notEmpty(accountPayment, "查询不到打款信息");
        //修改打款状态为未打款
        accountPayment.setStatus("20");
        //清空已打款金额
        accountPayment.setAmount(BigDecimal.ZERO);

        //赋值归属公司
        writeOffRecordsDto.setCompanyId(SecurityUtils.getCompanyId());

        accountPaymentService.updateById(accountPayment);

        //赋值最后一次打款时间
        writeOffRecordsDto.setAccountPaymentDate(accountPayment.getExpensesTime());
        this.save(writeOffRecordsDto);

        List<AccountPaymentRecords> accountPaymentRecordsList = accountPaymentRecordsService.list(
                q -> q.eq(AccountPaymentRecords::getAccountPaymentId, accountPayment.getId())
        );
        for (AccountPaymentRecords accountPaymentRecords : accountPaymentRecordsList) {
            //清理历史附件
            ObsFileUtil.removeFile(accountPaymentRecords.getId());
            AccountManagement accountManagement = accountManagementService.getById(accountPaymentRecords.getAccountManagementId());
            if (ObjectUtil.isEmpty(accountManagement)) {
                throw new ServiceException("资金账户不存在：" + accountPaymentRecords.getAccountManagementId());
            }
            //根据币种回滚余额
            AccountRemainder accountRemainder = accountRemainderService.getOne(Wrappers.<AccountRemainder>lambdaQuery()
                    .eq(AccountRemainder::getAccountManagementId, accountPaymentRecords.getAccountManagementId())
                    .eq(AccountRemainder::getCurrency, accountPaymentRecords.getCurrency()));
            // 如果不存在这条数据则返回币种不存在
            if (ObjectUtil.isEmpty(accountRemainder)) {
                String format = String.format("账户%s不存在币种(%s)，请前往资金账户添加", accountManagement.getName(), accountPaymentRecords.getCurrency());
                throw new ServiceException(format);
            }
            accountRemainderService.update(q -> q
                    .eq(AccountRemainder::getId, accountRemainder.getId())
                    .setSql("remainder = remainder + " + accountPaymentRecords.getAmount())
            );
        }
        //删除打款对应的流水
        List<AccountRunningWater> accountRunningWaterList = accountRunningWaterService.list(q -> q.eq(AccountRunningWater::getBusinessId, accountPayment.getId()));
        Assert.notEmpty(accountRunningWaterList, "查询不到打款流水信息");
    }

}
