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

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.interfaces.Func;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fjhx.account.controller.utils.DateUtils;
import com.fjhx.account.entity.account.po.AccountDeptRunningWater;
import com.fjhx.account.entity.account.vo.AccountRequestFundsVo;
import com.fjhx.account.entity.account.vo.AccountRunningWaterVo;
import com.fjhx.account.mapper.account.AccountDeptRunningWaterMapper;
import com.fjhx.account.service.account.AccountDeptRunningWaterService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.common.constant.SourceConstant;
import com.obs.services.internal.ServiceException;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysDeptService;
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.AccountDeptRunningWaterVo;
import com.fjhx.account.entity.account.dto.AccountDeptRunningWaterSelectDto;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.fjhx.account.entity.account.dto.AccountDeptRunningWaterDto;
import cn.hutool.core.bean.BeanUtil;

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


/**
 * <p>
 * 部门-资金流水关联表 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-13
 */
@Service
public class AccountDeptRunningWaterServiceImpl extends ServiceImpl<AccountDeptRunningWaterMapper, AccountDeptRunningWater> implements AccountDeptRunningWaterService {

    @Autowired
    private ISysDeptService sysDeptService;

    @Override
    public Page<AccountRunningWaterVo> getPage(AccountDeptRunningWaterSelectDto dto) {
        QueryWrapper<Object> wrapper = Wrappers.query();
        //收支类型
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getStatus()), "arw.status", dto.getStatus());
        //币种
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getCurrency()), "arw.currency", dto.getCurrency());
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getType()),"adrw.type",dto.getType());
        //归属公司id
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getCorporationId()),"am.corporation_id",dto.getCorporationId());
        //摘要
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getRemarks()),"arw.remarks",dto.getRemarks());
        //起始金额
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getBeginAmount()),"arw.amount",dto.getBeginAmount());
        //结束金额
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getEndAmount()),"arw.amount",dto.getEndAmount());
        //开始时间
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getBeginTime()),"arw.create_time",dto.getBeginTime());
        //结束时间
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getEndTime()),"arw.create_time",dto.getEndTime());
//        if (StringUtils.isNotEmpty(dto.getKeyword())) {
//            wrapper.and(wrapper1 -> wrapper1.like("arw.remarks", dto.getKeyword()).or().like("arw.name", dto.getKeyword()));
//        }

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

        List<AccountRunningWaterVo> records = page.getRecords();
        for (AccountRunningWaterVo record : records) {
            List<SysDept> sysDepts = sysDeptMap.get(record.getDeptId());
            if (ObjectUtil.isNotEmpty(sysDepts)) {
                record.setDeptName(sysDepts.get(0).getDeptName());
            }
        }
        return page;
    }

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

    /**
     * 部门-资金流水关联表新增
     */
    @Override
    public void add(AccountDeptRunningWaterDto accountDeptRunningWaterDto) {
        if (ObjectUtil.isNotEmpty(accountDeptRunningWaterDto.getId())){
            this.updateById(accountDeptRunningWaterDto);
        }else {
            this.save(accountDeptRunningWaterDto);
        }

    }

    @Override
    public void edit(AccountDeptRunningWaterDto accountDeptRunningWaterDto) {
        this.updateById(accountDeptRunningWaterDto);
    }

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

    /**
     * 部门-资金流水报表
     * @param dto
     * @return
     */
    @Override
    public  List<Map<String,Object>> DeptRunningWaterReport(AccountDeptRunningWaterSelectDto dto) {
        if (ObjectUtil.isEmpty(dto.getBeginTime())&&ObjectUtil.isEmpty(dto.getEndTime())) {
            throw new ServiceException("查询的时间范围不能为空！");
        }
        //获取月份集合
        List<String> months = DateUtils.getMonthBetweenDate(dto.getBeginTime(), dto.getEndTime());
        //存放部门信息
        List<SysDept> sysDeptList = new ArrayList<>();
        //查询部门信息
        if (ObjectUtil.isNotEmpty(dto.getDeptId())){
            //切换数据源
            DynamicDataSourceContextHolder.push(SourceConstant.BASE);
            //判断是否存在子集的部门信息
            sysDeptList =  sysDeptService.list(Wrappers.<SysDept>lambdaQuery().like(SysDept::getAncestors,dto.getDeptId())
                    .orderByDesc(SysDept::getParentId));
            SysDept sysDept = sysDeptService.getById(dto.getDeptId());
            sysDeptList.add(sysDept);
        }else {
            //切换数据源
            DynamicDataSourceContextHolder.push(SourceConstant.BASE);
            sysDeptList =  sysDeptService.list(Wrappers.<SysDept>lambdaQuery().orderByDesc(SysDept::getParentId));
        }
        //获取到部门ID
        List<Long> deptIds = sysDeptList.stream().map(sysDept -> sysDept.getDeptId()).collect(Collectors.toList());

        //查询资金流水表的信息
        QueryWrapper<Object> query = Wrappers.query();
        query.ge("DATE_FORMAT(ar.create_time,'%Y-%m')", DateUtil.format(dto.getBeginTime(),"yyyy-MM"));
        query.le("DATE_FORMAT(ar.create_time,'%Y-%m')", DateUtil.format(dto.getEndTime(),"yyyy-MM"));
        query.in("wd.dept_id",deptIds);
        query.groupBy("wd.dept_id","time");
        //切换数据源
        DynamicDataSourceContextHolder.push(SourceConstant.ACCOUNT);
        List<AccountRunningWaterVo> accountRunningWaterVos = baseMapper.DeptRunningWaterReport(query);
        Map<Long, List<AccountRunningWaterVo>> accountRunningWaterMap = accountRunningWaterVos.stream()
                .collect(Collectors.groupingBy(AccountRunningWaterVo::getDeptId));

        //存放部门费用统计的数据
       List<Map<String,Object>> mapList = new ArrayList<>();
        for (SysDept sysDept : sysDeptList) {
            Map<String,Object> map = new HashMap<>();
            map.put("deptName",sysDept.getDeptName());
            //获取到这个部门的费用统计报表
            List<AccountRunningWaterVo> accountRunningWaterVoList = accountRunningWaterMap.get(sysDept.getDeptId());
            //如果这个部门没有费用统计表的数据则将统计相关数据表设计为0
            if (ObjectUtil.isEmpty(accountRunningWaterVoList)){
                accountRunningWaterVoList = new ArrayList<>();
                for (String month : months) {
                   AccountRunningWaterVo accountRunningWaterVo = new AccountRunningWaterVo();
                   accountRunningWaterVo.setIncomeAmount(new BigDecimal(0));
                   accountRunningWaterVo.setExpenditureAmount(new BigDecimal(0));
                   accountRunningWaterVo.setBalanceAmount(new BigDecimal(0));
                   accountRunningWaterVo.setTime(month);
                   accountRunningWaterVoList.add(accountRunningWaterVo);
                }
            }else {
                Map<String, List<AccountRunningWaterVo>> waterMap = accountRunningWaterVoList.stream()
                        .collect(Collectors.groupingBy(AccountRunningWaterVo::getTime));

                for (String month : months) {//判断这个月份中是否有这个数据，如果没有则赋值为0
                    List<AccountRunningWaterVo> accountRunningWaterVos1 = waterMap.get(month);
                    if (ObjectUtil.isEmpty(accountRunningWaterVos1)){
                        AccountRunningWaterVo accountRunningWaterVo = new AccountRunningWaterVo();
                        accountRunningWaterVo.setIncomeAmount(new BigDecimal(0));
                        accountRunningWaterVo.setExpenditureAmount(new BigDecimal(0));
                        accountRunningWaterVo.setBalanceAmount(new BigDecimal(0));
                        accountRunningWaterVo.setTime(month);
                        accountRunningWaterVoList.add(accountRunningWaterVo);
                    }
                }
            }
           map.put("accountRunningWaterVoList",accountRunningWaterVoList);
            mapList.add(map);
        }
        return mapList;
    }

    /**
     * 部门-资金流水统计（ 部门-资金流水列表）
     * @param dto
     * @return
     */
    @Override
    public Map<String, Object> deptRunningWaterStatistics(AccountDeptRunningWaterSelectDto dto) {
        //存放流水统计数据
        Map<String, Object> map = new HashMap<>();

        QueryWrapper<Object> query = Wrappers.query();
        query.groupBy("rwd.dept_id");
        //查询部门-资金流水统计信息
        List<AccountRunningWaterVo> accountRunningWaterVoList =  baseMapper.deptRunningWaterStatistics(query);

        //计算收入合计数据
        BigDecimal incomeAmount = accountRunningWaterVoList.stream().map(accountRunningWaterVo ->
                accountRunningWaterVo.getIncomeAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);

        //计算支出合计数据
        BigDecimal expenditureAmount = accountRunningWaterVoList.stream().map(accountRunningWaterVo ->
                accountRunningWaterVo.getExpenditureAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("incomeAmount",incomeAmount);
        map.put("expenditureAmount",expenditureAmount);

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

        //赋值部门信息
        for (AccountRunningWaterVo accountRunningWaterVo : accountRunningWaterVoList) {
            List<SysDept> sysDepts = sysDeptMap.get(accountRunningWaterVo.getDeptId());
            if (CollectionUtils.isNotEmpty(sysDepts)){
                accountRunningWaterVo.setDeptName(sysDepts.get(0).getDeptName());
            }
        }
        map.put("accountRunningWaterVoList",accountRunningWaterVoList);
        return map;
    }

}
