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

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fjhx.account.entity.account.bo.AccountRunningWaterBo;
import com.fjhx.account.entity.account.po.AccountRemainder;
import com.fjhx.account.entity.account.po.AccountRunningWater;
import com.fjhx.account.mapper.account.AccountRunningWaterMapper;
import com.fjhx.account.service.account.AccountRemainderService;
import com.fjhx.account.service.account.AccountRunningWaterService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.common.constant.SourceConstant;
import com.fjhx.item.util.excel.util.ExcelUtil;
import com.fjhx.tenant.entity.dict.dto.DictTenantDataSelectDto;
import com.fjhx.tenant.entity.dict.vo.DictTenantDataVo;
import com.fjhx.tenant.service.dict.DictTenantDataService;
import com.obs.services.internal.ServiceException;
import com.ruoyi.common.annotation.TenantIgnore;
import com.ruoyi.common.core.domain.BaseSelectDto;
import com.ruoyi.common.utils.StringUtils;
import org.apache.commons.collections4.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fjhx.account.entity.account.vo.AccountRunningWaterVo;
import com.fjhx.account.entity.account.dto.AccountRunningWaterSelectDto;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.fjhx.account.entity.account.dto.AccountRunningWaterDto;
import cn.hutool.core.bean.BeanUtil;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 账户资金流水表 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-06
 */
@Service
public class AccountRunningWaterServiceImpl extends ServiceImpl<AccountRunningWaterMapper, AccountRunningWater> implements AccountRunningWaterService {
    @Autowired
    private AccountRemainderService accountRemainderService;

    @Autowired
    private DictTenantDataService dictTenantDataService;



    @Override
    public Page<AccountRunningWaterVo> getPage(AccountRunningWaterSelectDto dto) {
        QueryWrapper<Object> wrapper = Wrappers.query();
        //资金账户
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getAccountManagementId()), "arw.account_management_id", dto.getAccountManagementId());
        //交易类型
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getStatus()), "arw.status", dto.getStatus());
        //是否合同到账
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getReceived()), "arw.received", dto.getReceived());
        //币种
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getCurrency()), "arw.currency", dto.getCurrency());
        //是否认领
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getIsClaim()), "arw.is_claim", dto.getIsClaim());
        //交易开始金额
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getBeginAmount()),"arw.amount",dto.getBeginAmount());
        //交易结束金额
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getEndAmount()),"arw.amount",dto.getEndAmount());
        //交易开始时间
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getBeginTime()),"arw.create_time",dto.getBeginTime());
        //交易结束金额
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getEndTime()),"arw.create_time",dto.getEndTime());
        //对方账户名称
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getName()),"arw.name",dto.getName());
        //摘要
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getRemarks()),"arw.name",dto.getRemarks());
        if (StringUtils.isNotEmpty(dto.getKeyword())) {
            wrapper.and(wrapper1 -> wrapper1.like("arw.remarks", dto.getKeyword()).or().like("arw.name", dto.getKeyword()));
        }
        if(ObjectUtil.isNotEmpty(dto.getDataType())&&dto.getDataType()==1){//到账认领数据
            wrapper.eq("arw.received",10);
            wrapper.orderByAsc("arw.is_claim","arw.create_time");
        }
        Page<AccountRunningWaterVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        return page;
    }

    @Override
    public AccountRunningWaterVo detail(Long id) {
        AccountRunningWaterVo result = baseMapper.getDetail(id);
        return result;
    }
    /**
     * 账户资金流水表新增
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void add(AccountRunningWaterDto accountRunningWaterDto) {

        //修改账户余额表的余额
        AccountRemainder accountRemainder = accountRemainderService.getOne(Wrappers.<AccountRemainder>lambdaQuery()
                .eq(AccountRemainder::getAccountManagementId,accountRunningWaterDto.getAccountManagementId())
                .eq(AccountRemainder::getCurrency,accountRunningWaterDto.getCurrency())
        );
        if (ObjectUtil.isEmpty(accountRemainder)){
            throw new ServiceException("账户余额不足");
        }
        accountRemainder.setStatus(accountRunningWaterDto.getStatus());
        //修改变更余额
        accountRemainder.setChangeRemainder(accountRunningWaterDto.getAmount());
        if (accountRunningWaterDto.getStatus().equals("10")){
            accountRemainder.setRemainder(accountRemainder.getRemainder().add(accountRunningWaterDto.getAmount()));
        }else if (accountRunningWaterDto.getStatus().equals("20")){
           if (accountRemainder.getRemainder().compareTo(accountRunningWaterDto.getAmount()) ==-1){
               throw new ServiceException("账户余额不足");
           }else {
               accountRemainder.setRemainder(accountRemainder.getRemainder().subtract(accountRunningWaterDto.getAmount()));
           }
        }
        accountRemainderService.updateById(accountRemainder);
        this.save(accountRunningWaterDto);
    }


    /**
     * 账户资金流水表编辑
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void edit(AccountRunningWater accountRunningWaterDto) {
//        //查询资金流水表的数据
//        AccountRunningWater accountRunningWater = this.getById(accountRunningWaterDto.getId());
//
//        //修改账户余额表的余额
//        AccountRemainder accountRemainder = accountRemainderService.getOne(Wrappers.<AccountRemainder>lambdaQuery()
//                .eq(AccountRemainder::getAccountManagementId,accountRunningWater.getAccountManagementId())
//                .eq(AccountRemainder::getCurrency,accountRunningWater.getCurrency())
//        );
//        if (accountRemainder.getStatus().equals("10")){
//            if (accountRemainder.getRemainder().compareTo(accountRunningWater.getAmount())==1)
//        }

        this.updateById(accountRunningWaterDto);
    }

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

    /**
     * 到账任领统计
     */
    @Override
    public List<AccountRunningWater> claimStatistics(BaseSelectDto dto) {
        QueryWrapper<AccountRunningWater> query = Wrappers.query();
        query.groupBy("is_claim");
        query.select("is_claim,count(*) count");
       //到账认领统计
       return baseMapper.selectList(query);

    }

    @Override
    public void exportExcel(AccountRunningWaterSelectDto dto, HttpServletResponse httpServletResponse) {
        QueryWrapper<Object> wrapper = Wrappers.query();
        //资金账户
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getAccountManagementId()), "arw.account_management_id", dto.getAccountManagementId());
        //交易类型
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getStatus()), "arw.status", dto.getStatus());
        //是否合同到账
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getReceived()), "arw.received", dto.getReceived());
        //币种
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getCurrency()), "arw.currency", dto.getCurrency());
        //是否认领
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getIsClaim()), "arw.is_claim", dto.getIsClaim());
        //交易开始金额
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getBeginAmount()),"arw.amount",dto.getBeginAmount());
        //交易结束金额
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getEndAmount()),"arw.amount",dto.getEndAmount());
        //交易开始时间
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getBeginTime()),"arw.create_time",dto.getBeginTime());
        //交易结束金额
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getEndTime()),"arw.create_time",dto.getEndTime());
        //对方账户名称
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getName()),"arw.name",dto.getName());
        //摘要
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getRemarks()),"arw.name",dto.getRemarks());
        if (StringUtils.isNotEmpty(dto.getKeyword())) {
            wrapper.and(wrapper1 -> wrapper1.like("arw.remarks", dto.getKeyword()).or().like("arw.name", dto.getKeyword()));
        }
        if(ObjectUtil.isNotEmpty(dto.getDataType())&&dto.getDataType()==1){//到账认领数据
            wrapper.eq("arw.received",10);
            wrapper.orderByAsc("arw.is_claim","arw.create_time");
        }
        List<AccountRunningWaterVo> records = this.baseMapper.getList(wrapper);

        //赋值字典数据
        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
        List<DictTenantDataVo> dictTenantDataVos = getDict("account_currency");
        if (dictTenantDataVos.size() == 0){
            throw new ServiceException("数据有误：没有配置币种字典，请先配置");
        }
        Map<String, List<DictTenantDataVo>> dictTenantDataVoMap = dictTenantDataVos.stream()
                .collect(Collectors.groupingBy(DictTenantDataVo::getDictKey));
        DynamicDataSourceContextHolder.poll();
        for (AccountRunningWaterVo accountRunningWaterVo : records) {
            List<DictTenantDataVo> dictTenantDataVoList = dictTenantDataVoMap.get(accountRunningWaterVo.getCurrency());
            if (ObjectUtil.isNotEmpty(dictTenantDataVoList)){
                accountRunningWaterVo.setCurrency(dictTenantDataVoList.get(0).getDictValue());
            }
        }

        //导出Excel
        List<AccountRunningWaterBo> accountRunningWaterBos = BeanUtil.copyToList(records, AccountRunningWaterBo.class);
        ExcelUtil.export(httpServletResponse, accountRunningWaterBos, AccountRunningWaterBo.class);
    }

    // 根据字典编码获取字典的数据
    private List<DictTenantDataVo> getDict(String code) {
        DictTenantDataSelectDto dto = new DictTenantDataSelectDto();
        dto.setDictCode(code);
        List<DictTenantDataVo> dictTenantDataServiceList = dictTenantDataService.getList(dto);
        return dictTenantDataServiceList;
    }

}
