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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.dto.AccountPaymentDto;
import com.fjhx.account.entity.account.dto.AccountRequestFundsSelectDto;
import com.fjhx.account.entity.account.enums.PaymentStatusEnum;
import com.fjhx.account.entity.account.po.AccountManagement;
import com.fjhx.account.entity.account.po.AccountPayment;
import com.fjhx.account.entity.account.po.AccountRemainder;
import com.fjhx.account.entity.account.po.AccountRunningWater;
import com.fjhx.account.entity.account.vo.AccountPaymentVo;
import com.fjhx.account.mapper.account.AccountPaymentMapper;
import com.fjhx.account.service.account.AccountManagementService;
import com.fjhx.account.service.account.AccountPaymentService;
import com.fjhx.account.service.account.AccountRemainderService;
import com.fjhx.account.service.account.AccountRunningWaterService;
import com.fjhx.common.constant.SourceConstant;
import com.fjhx.common.entity.corporation.po.Corporation;
import com.fjhx.common.service.corporation.CorporationService;
import com.fjhx.file.utils.ObsFileUtil;
import com.obs.services.internal.ServiceException;
import com.ruoyi.common.core.domain.BasePo;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.utils.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 打款表 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-11
 */
@Service
public class AccountPaymentServiceImpl extends ServiceImpl<AccountPaymentMapper, AccountPayment> implements AccountPaymentService {
    @Autowired
    private CorporationService corporationService;

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private AccountRemainderService accountRemainderService;

    @Autowired
    private AccountRunningWaterService accountRunningWaterService;

    @Autowired
    private AccountManagementService accountManagementService;

    @Override
    public Page<AccountPaymentVo> getPage(AccountRequestFundsSelectDto dto) {
        QueryWrapper<Object> wrapper = Wrappers.query();
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getPaymentStatus()),"ap.status",dto.getPaymentStatus());
        wrapper.like(ObjectUtil.isNotEmpty(dto.getKeyword()),"ap.payment_remark",dto.getKeyword());
        wrapper.orderByDesc("ap.status","ap.payment_time","ap.create_time");
        Page<AccountPaymentVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);

        //切换数据源
        DynamicDataSourceContextHolder.push(SourceConstant.COMMON);
        //查询公司名称信息
        List<Corporation> corporationList = corporationService.list();
        Map<Long, List<Corporation>> corporationMap = corporationList.stream().collect(Collectors.groupingBy(Corporation::getId));
        DynamicDataSourceContextHolder.poll();


        //切换数据源
        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
        //查询部门信息
        List<SysDept> sysDeptList = sysDeptService.list();
        Map<Long, List<SysDept>> sysDeptMap = sysDeptList.stream().collect(Collectors.groupingBy(SysDept::getDeptId));


        //赋值部门名称、归属公司名称
        List<AccountPaymentVo> records = page.getRecords();
        for (AccountPaymentVo record : records) {
            List<SysDept> sysDepts = sysDeptMap.get(record.getDepartmentId());
            if (ObjectUtil.isNotEmpty(sysDepts)){
                record.setDeptName(sysDepts.get(0).getDeptName());
            }
            List<Corporation> corporations = corporationMap.get(record.getCorporationId());
            if (ObjectUtil.isNotEmpty(corporations)){
                record.setCorporationName(corporations.get(0).getName());
            }

        }

        // 赋值用户名称
        UserUtil.assignmentNickName(records, BasePo::getCreateUser,AccountPaymentVo::setUserName);

        return page;
    }

    /**
     * 打款表明细
     */
    @Override
    public AccountPaymentVo detail(Long id) {
        AccountPayment AccountPayment = baseMapper.detail(id);
        AccountPaymentVo result = BeanUtil.toBean(AccountPayment, AccountPaymentVo.class);

        if (ObjectUtil.isNotEmpty(result.getAccountManagementId())){
            //查询实际打款的付款账户名称；
            AccountManagement accountManagement = accountManagementService.getById(result.getAccountManagementId());
            if (ObjectUtil.isNotEmpty(accountManagement)){
                result.setAccountManagementName(accountManagement.getName());
            }

        }

        if (ObjectUtil.isNotEmpty(result.getBusinessManagementId())){
            //查询业务中选中的付款账户名称；
            AccountManagement accountManagement = accountManagementService.getById(result.getBusinessManagementId());
            if (ObjectUtil.isNotEmpty(accountManagement)){
                result.setBusinessManagementName(accountManagement.getName());
            }

        }
        return result;
    }

    /**
     * 打款功能
     * @param accountPaymentDto
     */
    @Override
    @DSTransactional
    public void add(AccountPaymentDto accountPaymentDto) {
        AccountRemainder accountRemainder = accountRemainderService.getOne(Wrappers.<AccountRemainder>lambdaQuery()
                .eq(AccountRemainder::getAccountManagementId, accountPaymentDto.getAccountManagementId())
                .eq(AccountRemainder::getCurrency, accountPaymentDto.getCurrency()));
        //如果不存在这条数据则返回账户余额不足
        if (ObjectUtil.isEmpty(accountRemainder)){
            throw new ServiceException("账户余额不足");
        }
        //如果余额小于付款金额则返回账户余额不足
        if (accountRemainder.getRemainder().compareTo(accountPaymentDto.getAmount()) == -1){
            throw new ServiceException("账户余额不足");
        }
        //TODO 只要发起就是已打款（后期可能要修改）
        accountRemainder.setStatus(PaymentStatusEnum.REJECT.getKey());
        if (ObjectUtil.isEmpty(accountPaymentDto.getId())){
            this.save(accountPaymentDto);
        }else {
            this.updateById(accountPaymentDto);
        }

        //添加附件信息
        ObsFileUtil.saveFile(accountPaymentDto.getFileList(),accountPaymentDto.getId());
        accountRemainder.setChangeRemainder(accountPaymentDto.getAmount());
        //修改账户-余额表的中余额
        accountRemainder.setRemainder( accountRemainder.getRemainder().subtract(accountPaymentDto.getAmount()));
        //打款的交易状态都是支出
        accountRemainder.setStatus("20");
        accountRemainderService.add(accountRemainder);

        //添加资金流水表的数据
        addAccountRunningWater(accountPaymentDto);
    }

    @Override
    public void edit(AccountPaymentDto accountPaymentDto) {
        this.updateById(accountPaymentDto);
    }

    @Override
    public void delete(Long id) {
        this.removeById(id);
    }

    /**
     * 添加资金流水表的数据
     */
    private void  addAccountRunningWater(AccountPaymentDto accountPaymentDto){

        AccountRunningWater accountRunningWater = new AccountRunningWater();
        accountRunningWater.setAccountManagementId(accountPaymentDto.getAccountManagementId());
        //打款的状态都是支出
        accountRunningWater.setStatus("20");
        accountRunningWater.setAmount(accountPaymentDto.getAmount());
        accountRunningWater.setCurrency(accountPaymentDto.getCurrency());
        accountRunningWater.setOpeningBank(accountPaymentDto.getOpeningBank());
        accountRunningWater.setAccountOpening(accountPaymentDto.getAccountOpening());
        accountRunningWater.setName(accountPaymentDto.getName());
        accountRunningWater.setTransactionTime(accountPaymentDto.getExpensesTime());
        accountRunningWater.setRemarks(accountPaymentDto.getRemark());
        accountRunningWater.setBusinessId(accountPaymentDto.getId());
        //添加流水类型
        accountRunningWater.setType("10");
        accountRunningWaterService.save(accountRunningWater);

    }


}
