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

import cn.hutool.core.bean.BeanUtil;
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.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.account.entity.account.dto.AccountRequestFundsDto;
import com.fjhx.account.entity.account.dto.AccountRequestFundsSelectDto;
import com.fjhx.account.entity.account.po.AccountManagement;
import com.fjhx.account.entity.account.po.AccountRequestFunds;
import com.fjhx.account.entity.account.vo.AccountRequestFundsDetailVo;
import com.fjhx.account.entity.account.vo.AccountRequestFundsVo;
import com.fjhx.account.mapper.account.AccountRequestFundsMapper;
import com.fjhx.account.service.account.AccountManagementService;
import com.fjhx.account.service.account.AccountRequestFundsDetailService;
import com.fjhx.account.service.account.AccountRequestFundsService;
import com.fjhx.common.constant.SourceConstant;
import com.fjhx.common.entity.corporation.po.Corporation;
import com.fjhx.common.service.corporation.CorporationService;
import com.fjhx.common.utils.Assert;
import com.fjhx.flow.entity.flow.po.FlowExample;
import com.fjhx.flow.service.flow.FlowExampleService;
import com.ruoyi.common.core.domain.BasePo;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
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.Objects;
import java.util.stream.Collectors;


/**
 * <p>
 * 请款表 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-10
 */
@Service
public class AccountRequestFundsServiceImpl extends ServiceImpl<AccountRequestFundsMapper, AccountRequestFunds> implements AccountRequestFundsService {

    @Autowired
    private CorporationService corporationService;

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private AccountRequestFundsDetailService accountRequestFundsDetailService;

    @Autowired
    private FlowExampleService flowExampleService;

    @Autowired
    private AccountManagementService accountManagementService;

    /**
     * 查询请款列表
     *
     * @param dto
     * @return
     */
    @Override
    public Page<AccountRequestFundsVo> getPage(AccountRequestFundsSelectDto dto) {
        QueryWrapper<Object> wrapper = Wrappers.query();
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getType()), "arf.type", dto.getType());
        if (ObjectUtil.isNotEmpty(dto.getStatus())) {
            wrapper.in("arf.status", dto.getStatus().split(","));
        }
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getPaymentStatus()), "ap.status", dto.getPaymentStatus());
        wrapper.like(ObjectUtil.isNotEmpty(dto.getKeyword()), "arf.payment_remarks", dto.getKeyword());
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getWriteOffStatus()), "arf.write_off_status", dto.getWriteOffStatus());
        // 请款审批状态 按 审批中、已通过、未通过 排序
        wrapper.orderByAsc("case arf.status when 10 then 1 when 30 then 2 else 3 END");
        // 同状态按发起时间倒序排序
        wrapper.orderByDesc("arf.create_time");
        // 添加权限自己看自己
        wrapper.eq("arf.create_user", SecurityUtils.getUserId());

        // 归属公司
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getCorporationId()), "arf.corporation_id", dto.getCorporationId());
        // 归属部门
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getDepartmentId()), "arf.department_id", dto.getDepartmentId());
        // 请款人
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getCreateUser()), "arf.create_user", dto.getCreateUser());
        // 币种
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getCurrency()), "arf.currency", dto.getCurrency());
        // 请款时间
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), "arf.create_time", dto.getBeginTime());
        wrapper.le(ObjectUtil.isNotEmpty(dto.getEndTime()), "arf.create_time", dto.getEndTime());
        // 请款金额
        wrapper.ge(ObjectUtil.isNotEmpty(dto.getMinAdvanceAmounts()), "arf.total", dto.getMinAdvanceAmounts());
        wrapper.le(ObjectUtil.isNotEmpty(dto.getMaxAdvanceAmounts()), "arf.total", dto.getMaxAdvanceAmounts());
        // 用款说明
        wrapper.like(ObjectUtil.isNotEmpty(dto.getPaymentRemarks()), "arf.payment_remarks", dto.getPaymentRemarks());
        // 付款方式
        wrapper.like(ObjectUtil.isNotEmpty(dto.getPaymentMethod()), "arf.payment_method", dto.getPaymentMethod());

        Page<AccountRequestFundsVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);

        List<AccountRequestFundsVo> records = page.getRecords();

        if (ObjectUtil.isEmpty(records)) {
            return page;
        }

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

        // 赋值公司名称信息
        corporationService.attributeAssign(records, AccountRequestFunds::getCorporationId, (item, corporation) -> {
            item.setCorporationName(corporation.getName());
        });

        // 切换数据源
        DynamicDataSourceContextHolder.push(SourceConstant.BASE);

        // 赋值流程实例id
        List<Long> accountRequestFundsIds = records.stream().map(AccountRequestFundsVo::getId).collect(Collectors.toList());
        if (ObjectUtil.isNotEmpty(accountRequestFundsIds)) {
            Map<Long, Long> arfMap = flowExampleService.mapKV(FlowExample::getBusinessId, FlowExample::getId,
                    q -> q.in(FlowExample::getBusinessId, accountRequestFundsIds));
            records.forEach(item -> item.setFlowInfoId(arfMap.get(item.getId())));
        }

        // 查询部门id列表
        List<Long> deptIdList = records.stream()
                .map(AccountRequestFunds::getDepartmentId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        List<SysDept> sysDeptList = sysDeptService.listByIds(deptIdList);
        Map<Long, String> deptMap = sysDeptList.stream().collect(Collectors.toMap(SysDept::getDeptId, SysDept::getDeptName));
        records.forEach(item -> item.setDeptName(deptMap.get(item.getDepartmentId())));

        DynamicDataSourceContextHolder.poll();

        return page;
    }

    /**
     * 查询请款详情
     */
    @Override
    public AccountRequestFundsVo detail(Long id) {
        AccountRequestFunds accountRequestFunds = this.getById(id);
        Assert.notEmpty(accountRequestFunds, "查询不到请款信息");
        AccountRequestFundsVo accountRequestFundsVo = BeanUtil.toBean(accountRequestFunds, AccountRequestFundsVo.class);

        // 获取到请款明细信息
        List<AccountRequestFundsDetailVo> accountRequestFundsDetailVos =
                accountRequestFundsDetailService.listByAccountRequestFundsId(accountRequestFunds.getId());

        accountRequestFundsVo.setAccountRequestFundsDetailList(accountRequestFundsDetailVos);

        // 赋值账户名称
        AccountManagement accountManagement = accountManagementService.getById(accountRequestFundsVo.getAccountManagementId());
        if (accountManagement != null) {
            accountRequestFundsVo.setAccountManagementName(accountManagement.getName());
        }

        // 查询归属公司的名称
        Corporation corporation = corporationService.getById(accountRequestFundsVo.getCorporationId());
        if (ObjectUtil.isEmpty(corporation)) {
            throw new ServiceException("没有找到归属公司信息");
        }
        accountRequestFundsVo.setCorporationName(corporation.getName());

        // 切换数据源
        DynamicDataSourceContextHolder.push(SourceConstant.BASE);

        // 查询部门名称信息
        SysDept sysDept = sysDeptService.getById(accountRequestFundsVo.getDepartmentId());
        if (ObjectUtil.isEmpty(sysDept)) {
            throw new ServiceException("没有找到归属部门信息");
        }
        accountRequestFundsVo.setDeptName(sysDept.getDeptName());

        // 赋值流程实例id
        FlowExample flowExample = flowExampleService.getOne(q -> q.eq(FlowExample::getBusinessId, accountRequestFunds.getId()));
        if (ObjectUtil.isNotEmpty(flowExample)) {
            accountRequestFundsVo.setFlowInfoId(flowExample.getId());
        }

        DynamicDataSourceContextHolder.poll();

        return accountRequestFundsVo;
    }

    @Override
    public void add(AccountRequestFundsDto accountRequestFundsDto) {
        this.save(accountRequestFundsDto);
    }

    @Override
    public void edit(AccountRequestFundsDto accountRequestFundsDto) {
        this.updateById(accountRequestFundsDto);
    }

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

    /**
     * 获取历史付款信息
     */
    @Override
    public List<AccountRequestFundsVo> getPayHistoricalInfo() {
        return baseMapper.getPayHistoricalInfo(SecurityUtils.getUserId());
    }

}
