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

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fjhx.account.entity.account.po.AccountManagement;
import com.fjhx.account.entity.account.po.AccountRemainder;
import com.fjhx.account.entity.account.po.AccountRunningWater;
import com.fjhx.account.mapper.account.AccountManagementMapper;
import com.fjhx.account.service.account.AccountManagementService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.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.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysUserService;
import org.apache.poi.util.StringUtil;
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.AccountManagementVo;
import com.fjhx.account.entity.account.dto.AccountManagementSelectDto;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.fjhx.account.entity.account.dto.AccountManagementDto;
import cn.hutool.core.bean.BeanUtil;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 账户-管理表 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-06
 */
@Service
public class AccountManagementServiceImpl extends ServiceImpl<AccountManagementMapper, AccountManagement> implements AccountManagementService {
    @Autowired
    private AccountRemainderService accountRemainderService;

    @Autowired
    private AccountRunningWaterService accountRunningWaterService;

    @Autowired
    private DictTenantDataService dictTenantDataService;


    /**
     * 账户-管理表分页
     */
    @Override
    public Page<AccountManagementVo> getPage(AccountManagementSelectDto dto) {
        LambdaQueryWrapper<AccountManagement> wrapper = Wrappers.<AccountManagement>lambdaQuery();
        //根据关键字查询（查询的字段有账户别名、账户名称、账号）
        if (StringUtils.isNotEmpty(dto.getKeyword())){
            wrapper.and(wrapper1 ->{
                wrapper1.like(AccountManagement::getName,dto.getKeyword()).or()
                .like(AccountManagement::getAlias,dto.getKeyword()).or()
                .like(AccountManagement::getAccountOpening,dto.getKeyword()).or()
                        .like(AccountManagement::getOpeningBank,dto.getKeyword());
            } );
        }
        Page<AccountManagementVo> page = baseMapper.getPage(dto.getPage(), wrapper);
        return page;
    }

    /**
     * 账户-管理表明细
     */
    @Override
    public AccountManagementDto detail(Long id) {
        //查询账户管理表的明细
        AccountManagement AccountManagement = this.getById(id);
        AccountManagementDto result = BeanUtil.toBean(AccountManagement, AccountManagementDto.class);
        //查询账户余额表的信息
        List<AccountRemainder> accountRemainderList = accountRemainderService.list(Wrappers.<AccountRemainder>lambdaQuery()
                .eq(AccountRemainder::getAccountManagementId, id));
        result.setAccountRemainderList(accountRemainderList);
        return result;
    }

    /**
     * 账户-管理表新增
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void add(AccountManagementDto accountManagementDto) {
        //判断账户的别名是否已存在
        List<AccountManagement> accountManagements = this.list(Wrappers.<AccountManagement>lambdaQuery()
                .eq(AccountManagement::getAlias, accountManagementDto.getAlias()));
        if (accountManagements.size()>0){
            throw new ServiceException("数据错误：账户别名已存在请重新创建");
        }
        //添加账户管理表的信息
        this.save(accountManagementDto);
        //添加账户-余额表的信息
        saveAccountRemainder(accountManagementDto);
    }

    /**
     * 账户-管理表编辑
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void edit(AccountManagementDto accountManagementDto) {
        this.updateById(accountManagementDto);
        //判断账户的别名是否已存在
        List<AccountManagement> accountManagements = this.list(Wrappers.<AccountManagement>lambdaQuery()
                .eq(AccountManagement::getAlias, accountManagementDto.getAlias()));
        if (accountManagements.size()>1){
            throw new ServiceException("数据错误：账户别名已存在请重新创建");
        }
        //删除账户-余额表的信息
        List<AccountRemainder> accountRemainderList = accountManagementDto.getAccountRemainderList();
        List<Long> ids = accountRemainderList.stream().map(accountRemainder -> accountRemainder.getId()).collect(Collectors.toList());
        accountRemainderService.remove(Wrappers.<AccountRemainder>lambdaQuery()
                .eq(AccountRemainder::getAccountManagementId,accountManagementDto.getId())
                .notIn(AccountRemainder::getId,ids)
        );
        //添加账户余额表的信息
        saveAccountRemainder(accountManagementDto);
    }

    /**
     * 账户-管理表删除
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void delete(Long id) {
        //查询流水表的信息
        List<AccountRunningWater> accountRunningWaterList = accountRunningWaterService.list(Wrappers.<AccountRunningWater>lambdaQuery()
                .eq(AccountRunningWater::getAccountManagementId, id));
        //如果存在流水表的数据则不能删除账户表的信息
        if (accountRunningWaterList.size()>0){
            throw new ServiceException("无法删除，该账户已存在流水数据");
        }
        //删除账户-管理表的信息
        this.removeById(id);
        //删除账户-余额表的信息
        accountRemainderService.remove(Wrappers.<AccountRemainder>lambdaQuery()
                .eq(AccountRemainder::getAccountManagementId,id));
    }

    /**
     * 账户统计(账户列表)
     */
    @Override
    public  List<Map<String, Object>> managementStatistics(AccountManagementSelectDto dto) {
        //存放账户统计数据
        List<Map<String, Object>> list = new ArrayList<>();

        QueryWrapper<AccountRemainder> query = Wrappers.query();
        query.groupBy("currency");
        query.select("currency,sum(remainder) remainder");
        List<AccountRemainder> accountRemainderList = accountRemainderService.list(query);

        //切换数据源
        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
        //获取来源的字典数据
        List<DictTenantDataVo> dictTenantDataVos = getDict("customer_source");
        DynamicDataSourceContextHolder.poll();

        if (dictTenantDataVos.size()==0){
            throw new ServiceException("数据有误：没有配置币种字典，请先配置");
        }

        //赋值
        for (DictTenantDataVo dictTenantDataVo : dictTenantDataVos) {
            //赋初始值信息
            Map<String,Object> map = new HashMap<>();
            map.put("currencyKey",dictTenantDataVo.getDictKey());
            map.put("currencyValue",dictTenantDataVo.getDictValue());
            map.put("remainder",new BigDecimal(0));
            //赋值余额信息
            if (accountRemainderList.size()>0){
                Map<String, List<AccountRemainder>> accountRemainderMap = accountRemainderList.stream()
                        .collect(Collectors.groupingBy(AccountRemainder::getCurrency));
                List<AccountRemainder> accountRemainderList1 = accountRemainderMap.get(dictTenantDataVo.getDictKey());
                if (ObjectUtil.isNotEmpty(accountRemainderList1)){
                    map.put("remainder",accountRemainderList1.get(0).getRemainder());
                }
            }
            list.add(map);
        }

        return list;
    }

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


//    /**
//     * 导入账户表的数据
//     */
//    @Override
//    @Transactional(rollbackFor = {Exception.class})
//    @TenantIgnore
//    public void importsAmount(AccountManagementDto dto) {
//        //查询云帆账户表的数据
////        List<FundAccount> fundAccounts = baseMapper.importsAmount(dto);
////        for (FundAccount fundAccount : fundAccounts) {
////            //添加资金账户表的数据
////            AccountManagement accountManagement = new AccountManagement();
////            //查询多公司表
////            if (ObjectUtil.isNotEmpty(fundAccount.getCompanyId())){
////                DynamicDataSourceContextHolder.push(SourceConstant.COMMON);
////
////                Corporation corporation = corporationService.getOne(Wrappers.<Corporation>lambdaQuery().eq(Corporation::getYfId,fundAccount.getCompanyId()));
////                if(ObjectUtil.isNotEmpty(corporation)){
////                    accountManagement.setCorporationId(corporation.getId());
////                }
////
////                DynamicDataSourceContextHolder.poll();
////            }
////            accountManagement.setTenantId(fundAccount.getTenantId());
////            accountManagement.setYfId(fundAccount.getId());
////            accountManagement.setAlias(fundAccount.getName());
////            accountManagement.setAccountOpening(fundAccount.getAccountNumber());
////            accountManagement.setCreateTime(fundAccount.getCreateTime());
////            accountManagement.setUpdateTime(fundAccount.getUpdateTime());
////            accountManagement.setAccountOpening(fundAccount.getAccountNumber());
////            //查询用户
////            if (ObjectUtil.isNotEmpty(fundAccount.getCreateUser())){
////                DynamicDataSourceContextHolder.push(SourceConstant.BASE);
////                SysUser sysUser = sysUserService.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getYfUserId, fundAccount.getCreateUser()));
////                accountManagement.setCreateUser(sysUser.getUserId());
////                DynamicDataSourceContextHolder.poll();
////            }
////
////            if (ObjectUtil.isNotEmpty(fundAccount.getUpdateUser())){
////                DynamicDataSourceContextHolder.push(SourceConstant.BASE);
////                SysUser sysUser = sysUserService.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getYfUserId, fundAccount.getUpdateUser()));
////                accountManagement.setCreateUser(sysUser.getUserId());
////                DynamicDataSourceContextHolder.poll();
////            }
////            accountManagement.setCreateTime(fundAccount.getCreateTime());
////            accountManagement.setUpdateTime(fundAccount.getUpdateTime());
////            baseMapper.insert(accountManagement);
////
////            //添加资金账户余额表的信息
////            AccountRemainder accountRemainder = new AccountRemainder();
////            accountRemainder.setTenantId(fundAccount.getTenantId());
////            accountRemainder.setAccountManagementId(accountManagement.getId());
////            //查询用户
////            if (ObjectUtil.isNotEmpty(fundAccount.getCreateUser())){
////                DynamicDataSourceContextHolder.push(SourceConstant.BASE);
////                SysUser sysUser = sysUserService.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getYfUserId, fundAccount.getCreateUser()));
////                accountRemainder.setCreateUser(sysUser.getUserId());
////                DynamicDataSourceContextHolder.poll();
////            }
////
////            if (ObjectUtil.isNotEmpty(fundAccount.getUpdateUser())){
////
////                DynamicDataSourceContextHolder.push(SourceConstant.BASE);
////                SysUser sysUser = sysUserService.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getYfUserId, fundAccount.getUpdateUser()));
////                accountRemainder.setCreateUser(sysUser.getUserId());
////                DynamicDataSourceContextHolder.poll();
////            }
////            if (ObjectUtil.isNotEmpty(fundAccount.getRmbAmount())){
////                accountRemainder.setId(IdWorker.getId());
////                accountRemainder.setRemainder(fundAccount.getRmbAmount());
////                accountRemainder.setCurrency("RMB");
////                accountRemainderService.save(accountRemainder);
////            }
////            if (ObjectUtil.isNotEmpty(fundAccount.getDollarAmount())){
////                accountRemainder.setId(IdWorker.getId());
////                accountRemainder.setRemainder(fundAccount.getDollarAmount());
////                accountRemainder.setCurrency("USD");
////                accountRemainderService.save(accountRemainder);
////            }
////            if (ObjectUtil.isNotEmpty(fundAccount.getEuroAmount())){
////                accountRemainder.setId(IdWorker.getId());
////                accountRemainder.setRemainder(fundAccount.getEuroAmount());
////                accountRemainder.setCurrency("EUR");
////                accountRemainderService.save(accountRemainder);
////            }
////
////            if (ObjectUtil.isNotEmpty(fundAccount.getSterlingAmount())){
////                accountRemainder.setId(IdWorker.getId());
////                accountRemainder.setRemainder(fundAccount.getSterlingAmount());
////                accountRemainder.setCurrency("GBP");
////                accountRemainderService.save(accountRemainder);
////            }
////        }
//
//    }


    /**
     * 添加账户-余额表的信息
     */
    private void saveAccountRemainder(AccountManagementDto accountManagementDto){
        List<AccountRemainder> accountRemainderList = accountManagementDto.getAccountRemainderList();
        accountRemainderList.forEach(accountRemainder -> {
            accountRemainder.setAccountManagementId(accountManagementDto.getId());
            accountRemainderService.add(accountRemainder);
        });

    }
}
