package com.dayou.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.dayou.common.BaseEntity;
import com.dayou.dto.FinanceRealFundExportDTO;
import com.dayou.dto.FinanceRealNotClaimDTO;
import com.dayou.entity.FinanceClaim;
import com.dayou.entity.FinanceRealFund;
import com.dayou.entity.User;
import com.dayou.exception.ErrorCode;
import com.dayou.mapper.FinanceRealFundMapper;
import com.dayou.mapper.UserMapper;
import com.dayou.service.IFinanceClaimService;
import com.dayou.service.IFinanceRealFundService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dayou.utils.LoginContext;
import com.dayou.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dayou.utils.ExcelUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;

import org.springframework.transaction.annotation.Transactional;
import com.dayou.enums.BatchTaskTypeEnum;

/**
 * <p>
 * 财务实收款 服务实现类
 * </p>
 *
 * @author wucl
 * @since 2023-12-08
 */
@DS("mbs")
@Service
public class FinanceRealFundServiceImpl extends ServiceImpl<FinanceRealFundMapper, FinanceRealFund> implements IFinanceRealFundService {

    @Autowired
    private FinanceRealFundMapper financeRealFundMapper;

    @Autowired
    private IFinanceClaimService financeClaimService;
    @Autowired
    private UserMapper userMapper;

    @Override
    @SuppressWarnings("unchecked")
    public Page<FinanceRealFundVO> selectPage(Page page, FinanceRealFund financeRealFund,String keyword){
        Page<FinanceRealFundVO> ret = financeRealFundMapper.getPage(page,financeRealFund,keyword);
        return ret;
    }


    @Override
    public Page<FinanceRealFundVO> claimPage(Page page, FinanceRealFund financeRealFund, String keyword) {
        Long currentUserId = LoginContext.getCurrentUserId();
        Page<FinanceRealFundVO> ret = financeRealFundMapper.claimPage(page,financeRealFund,keyword,currentUserId);
        return ret;
    }

    @Override
    public Page<FinanceRealFundVO> realClaimed(Page page, FinanceRealFundVO vo, String keyword) {
        Page<FinanceRealFundVO> financeRealFundVOPage = financeRealFundMapper.realAmountClaimed(page, vo, keyword);
        return financeRealFundVOPage;
    }

    @Override
    public List<FinanceRealFundExportDTO> realClaimedExport(FinanceRealFundVO vo, String keyword) {
        return financeRealFundMapper.realClaimedExport(vo, keyword);
    }

    @Override
    public List<FinanceRealNotClaimDTO> financeRealFundNotClaimExport(FinanceRealFundVO vo, String keyword) {
        return financeRealFundMapper.financeRealFundNotClaimExport(vo,keyword);
    }


    @Override
    public FinanceRealFund detail(Long id){
        return this.getById(id);
    }

    @Override
    public Boolean add(FinanceRealFund financeRealFund){
        financeRealFund.setCreatorId(LoginContext.getCurrentUserId());
        return  this.save(financeRealFund);
    }

    @Override
    public Boolean update(FinanceRealFund financeRealFund){
        List<FinanceClaim> list = financeClaimService.list(new LambdaQueryWrapper<FinanceClaim>().eq(FinanceClaim::getRealFundId, financeRealFund.getId()).eq(BaseEntity::getDeleted, Boolean.FALSE));
        if (CollectionUtil.isNotEmpty(list)){
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"此笔实收款，已有订单认领金额，无法修改。");
            return Boolean.FALSE;
        }
        return  this.updateById(financeRealFund);
    }

    @Override
    public Boolean delete(Long id){
        List<FinanceClaim> list = financeClaimService.list(new LambdaQueryWrapper<FinanceClaim>().eq(FinanceClaim::getRealFundId, id).eq(BaseEntity::getDeleted, Boolean.FALSE));
        if (CollectionUtil.isNotEmpty(list)){
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"此笔实收款，已有订单认领金额，无法删除。");
            return Boolean.FALSE;
        }
        //逻辑删除
        return this.removeById(id);
    }

    @Override
    public BigDecimal getNotClaimAmount(Long realFundId) {
        BigDecimal claimAmount = financeRealFundMapper.getNotClaimAmount(realFundId);
        return claimAmount;
    }

    @Override
    public Page<MajorProdOverdueVO> overdueMajor(MajorProdOverdueVO overdueVO, Page page) {
        Page<MajorProdOverdueVO> result = financeRealFundMapper.overdueMajor(page,overdueVO);
        return result;
    }

    @Override
    public List<MajorProdOverdueVO> overdueMajorExport(MajorProdOverdueVO overdueVO) {
        return financeRealFundMapper.overdueMajorExport(overdueVO);
    }

    @Override
    public Page<SettleMajorProductionVO> majorEvaluatorSettleProd(SettleMajorProductionVO settleVO, Page page,String keyword) {
        Page<SettleMajorProductionVO> result = financeRealFundMapper.majorEvaluatorSettleProd(page,settleVO,keyword);
        List<SettleMajorProductionVO> records = result.getRecords();
        for (SettleMajorProductionVO record : records) {
            List<Long> userIdS = JSON.parseArray(record.getMembers(), Long.class);
            if (CollectionUtil.isNotEmpty(userIdS)){
                List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().in(BaseEntity::getId, userIdS).select(User::getName).ne(BaseEntity::getId,1L));
                List<String> names = users.stream().map(User::getName).collect(Collectors.toList());
                record.setJoiner(String.join(",",names));
            }
        }
        return result;
    }

    @Override
    public Page<SettleMajorProductionVO> majorMarketSettleProd(SettleMajorProductionVO settleVO, Page page,String keyword) {
        Page<SettleMajorProductionVO> result = financeRealFundMapper.majorMarketerSettleProd(page,settleVO,keyword);
        List<SettleMajorProductionVO> records = result.getRecords();
        for (SettleMajorProductionVO record : records) {
            List<Long> userIdS = JSON.parseArray(record.getMembers(), Long.class);
            if (CollectionUtil.isNotEmpty(userIdS)){
                List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().in(BaseEntity::getId, userIdS).select(User::getName).ne(BaseEntity::getId,1L));
                List<String> names = users.stream().map(User::getName).collect(Collectors.toList());
                record.setJoiner(String.join(",",names));
            }
        }
        return result;
    }

    @Override
    public List<SettleMajorProductionVO> majorMarketSettleExport(SettleMajorProductionVO production,Page page,String keyword) {
        List<SettleMajorProductionVO> settleMajorProductionVOS = financeRealFundMapper.majorMarketSettleExport(page, production, keyword);
        for (SettleMajorProductionVO record : settleMajorProductionVOS) {
            List<Long> userIdS = JSON.parseArray(record.getMembers(), Long.class);
            if (CollectionUtil.isNotEmpty(userIdS)){
                List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().in(BaseEntity::getId, userIdS).select(User::getName).ne(BaseEntity::getId,1L));
                List<String> names = users.stream().map(User::getName).collect(Collectors.toList());
                record.setJoiner(String.join(",",names));
            }
        }
        return settleMajorProductionVOS;
    }

    @Override
    public List<SettleMajorProductionVO> majorEvaluatorSettleExport(SettleMajorProductionVO production,Page page,String keyword) {
        List<SettleMajorProductionVO> settleMajorProductionVOS = financeRealFundMapper.majorEvaluatorSettleExport(page, production, keyword);
        for (SettleMajorProductionVO record : settleMajorProductionVOS) {
            List<Long> userIdS = JSON.parseArray(record.getMembers(), Long.class);
            if (CollectionUtil.isNotEmpty(userIdS)){
                List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().in(BaseEntity::getId, userIdS).select(User::getName).ne(BaseEntity::getId,1L));
                List<String> names = users.stream().map(User::getName).collect(Collectors.toList());
                record.setJoiner(String.join(",",names));
            }
        }
        return settleMajorProductionVOS;
    }

    @Override
    public List<UserCommissionTotalAmountVO> majorEvaluatorCommission(UserCommissionTotalAmountVO vo) {
        return financeRealFundMapper.majorEvaluatorCommission(vo);
    }

    @Override
    public List<UserCommissionProdVO> majorEvaluatorCommissionDetail(UserCommissionProdVO vo) {
        return financeRealFundMapper.majorEvaluatorCommissionDetail(vo);
    }

    @Override
    public List<UserCommissionTotalAmountVO> majorEvaluatorTotalAmountExport(UserCommissionTotalAmountVO vo) {
        return financeRealFundMapper.majorEvaluatorTotalAmountExport(vo);
    }

    @Override
    public List<UserCommissionProdVO> evaluatorCurUserDetailExport(UserCommissionProdVO vo) {
        return financeRealFundMapper.evaluatorUserDetailExport(vo);
    }

    @Override
    public List<UserCommissionProdVO> evaluatorAllUserDetailExport(UserCommissionProdVO vo) {
        vo.setUserId(null);
        return financeRealFundMapper.evaluatorUserDetailExport(vo);
    }

    @Override
    public List<UserCommissionTotalAmountVO> majorMarketCommission(UserCommissionTotalAmountVO vo) {
        return financeRealFundMapper.majorMarketCommission(vo);
    }

    @Override
    public List<UserCommissionProdVO> majorMarketCommissionDetail(UserCommissionProdVO vo) {
        return financeRealFundMapper.majorMarketCommissionDetail(vo);
    }

    @Override
    public List<UserCommissionTotalAmountVO> majorMarketTotalAmountExport(UserCommissionTotalAmountVO vo) {
        return financeRealFundMapper.majorMarketTotalAmountExport(vo);
    }

    @Override
    public List<UserCommissionProdVO> marketCurUserDetailExport(UserCommissionProdVO vo) {
        return financeRealFundMapper.marketUserDetailExport(vo);
    }

    @Override
    public List<UserCommissionProdVO> marketAllUserDetailExport(UserCommissionProdVO vo) {
        vo.setUserId(null);
        return financeRealFundMapper.marketUserDetailExport(vo);
    }

    @Override
    public Page<PersonalOverdueVO> overduePersonal(PersonalOverdueVO overdueVO, Page page) {
        Page<PersonalOverdueVO> result = financeRealFundMapper.overduePersonal(page,overdueVO);
        return result;
    }

    /**
     * 资产评估人员提成计算
     * @param vo vo
     * @return List<UserCommissionTotalAmountVO>
     */
    @Override
    public List<UserCommissionTotalAmountVO> assetsEvaluatorCommission(UserCommissionTotalAmountVO vo) {
        return financeRealFundMapper.assetsEvaluatorCommission(vo);
    }

    /**
     * 资产评估人员提成计算详情
     * @param vo vo
     * @return List<UserCommissionTotalAmountVO>
     */
    @Override
    public List<UserCommissionProdAssetsVO> assetsEvaluatorCommissionDetail(UserCommissionProdVO vo) {
        return financeRealFundMapper.assetsEvaluatorCommissionDetail(vo);
    }

    /**
     * 资产评估人员合计导出
     * @param vo vo
     * @return List<UserCommissionTotalAmountVO>
     */
    @Override
    public List<UserCommissionTotalAmountVO> assetsEvaluatorTotalAmountExport(UserCommissionTotalAmountVO vo) {
        return financeRealFundMapper.assetsEvaluatorTotalAmountExport(vo);
    }

    /**
     * 资产单个评估人员提成信息导出
     * @param vo vo
     * @return List<UserCommissionProdVO>
     */
    @Override
    public List<UserCommissionProdAssetsVO> assetsEvaluatorCurUserDetailExport(UserCommissionProdVO vo) {
        return financeRealFundMapper.assetsEvaluatorUserDetailExport(vo);
    }

    /**
     * 资产所有评估人员提成信息导出
     * @param vo vo
     * @return List<UserCommissionProdVO>
     */
    @Override
    public List<UserCommissionProdAssetsVO> assetsEvaluatorAllUserDetailExport(UserCommissionProdVO vo) {
        vo.setUserId(null);
        return financeRealFundMapper.assetsEvaluatorUserDetailExport(vo);
    }

    /**
     * 资产市场人员提成计算
     * @param vo vo
     * @return List<UserCommissionTotalAmountVO>
     */
    @Override
    public List<UserCommissionTotalAmountVO> assetsMarketCommission(UserCommissionTotalAmountVO vo) {
        return financeRealFundMapper.assetsMarketCommission(vo);
    }

    /**
     * 资产市场人员提成计算详情
     * @param vo vo
     * @return List<UserCommissionProdVO>
     */
    @Override
    public List<UserCommissionProdVO> assetsMarketCommissionDetail(UserCommissionProdVO vo) {
        return financeRealFundMapper.assetsMarketCommissionDetail(vo);
    }

    /**
     * 资产市场人员提成合计导出
     * @param vo vo
     * @return List<UserCommissionTotalAmountVO>
     */
    @Override
    public List<UserCommissionTotalAmountVO> assetsMarketTotalAmountExport(UserCommissionTotalAmountVO vo) {
        return financeRealFundMapper.assetsMarketTotalAmountExport(vo);
    }

    /**
     * 资产单个市场人员提成信息导出
     * @param vo vo
     * @return List<UserCommissionProdVO>
     */
    @Override
    public List<UserCommissionProdVO> assetsMarketCurUserDetailExport(UserCommissionProdVO vo) {
        return financeRealFundMapper.assetsMarketUserDetailExport(vo);
    }

    /**
     * 资产所有市场人员提成信息导出
     * @param vo vo
     * @return List<UserCommissionProdVO>
     */
    @Override
    public List<UserCommissionProdVO> assetsMarketAllUserDetailExport(UserCommissionProdVO vo) {
        vo.setUserId(null);
        return financeRealFundMapper.assetsMarketUserDetailExport(vo);
    }

    /**
     * 资产收款逾期列表
     * @param overdueVO vo
     * @param page 分页参数
     * @return Page<MajorProdOverdueVO>
     */
    @Override
    public Page<AssetsProdOverdueVO> overdueAssets(AssetsProdOverdueVO overdueVO, Page page) {
        return financeRealFundMapper.overdueAssets(page, overdueVO);
    }

    /**
     * 资产收款逾期列表导出
     * @param overdueVO vo
     * @return Page<MajorProdOverdueVO>
     */
    @Override
    public List<AssetsProdOverdueVO> overdueAssetsExport(AssetsProdOverdueVO overdueVO) {
        return financeRealFundMapper.overdueAssetsExport(overdueVO);
    }

    /**
     * 资产市场人员结算项目查询
     * @param settleVO vo
     * @param page 分页参数
     * @return Page<SettleAssetsProductionVO>
     */
    @Override
    public Page<SettleAssetsProductionVO> assetsMarketSettleProd(SettleAssetsProductionVO settleVO, Page page,String keyword) {
        Page<SettleAssetsProductionVO> settleAssetsProductionVOPage = financeRealFundMapper.assetsMarketSettleProd(settleVO, page, keyword);
        List<SettleAssetsProductionVO> records = settleAssetsProductionVOPage.getRecords();
        for (SettleAssetsProductionVO record : records) {
            List<Long> userIdS = JSON.parseArray(record.getMembers(), Long.class);
            if (CollectionUtil.isNotEmpty(userIdS)){
                List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().in(BaseEntity::getId, userIdS).select(User::getName).ne(BaseEntity::getId,1L));
                List<String> names = users.stream().map(User::getName).collect(Collectors.toList());
                record.setJoiner(String.join(",",names));
            }
        }
        return settleAssetsProductionVOPage;
    }

    /**
     * 资产市场人员结算项目导出
     * @param settleVO vo
     * @return List<SettleAssetsProductionVO>
     */
    @Override
    public List<SettleAssetsProductionVO> assetsMarketSettleExport(SettleAssetsProductionVO settleVO,Page page,String keyword) {
        List<SettleAssetsProductionVO> settleAssetsProductionVOS = financeRealFundMapper.assetsMarketSettleExport(page, settleVO, keyword);
        for (SettleAssetsProductionVO record : settleAssetsProductionVOS) {
            List<Long> userIdS = JSON.parseArray(record.getMembers(), Long.class);
            if (CollectionUtil.isNotEmpty(userIdS)){
                List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().in(BaseEntity::getId, userIdS).select(User::getName).ne(BaseEntity::getId,1L));
                List<String> names = users.stream().map(User::getName).collect(Collectors.toList());
                record.setJoiner(String.join(",",names));
            }
        }
        return settleAssetsProductionVOS;
    }

    /**
     * 资产评估人员结算项目查询
     * @param settleVO vo
     * @param page 分页参数
     * @return Page<SettleAssetsProductionVO>
     */
    @Override
    public Page<SettleAssetsProductionVO> assetsEvaluatorSettleProd(SettleAssetsProductionVO settleVO, Page page,String keyword) {
        Page<SettleAssetsProductionVO> settleAssetsProductionVOPage = financeRealFundMapper.assetsEvaluatorSettleProd(settleVO, page, keyword);
        List<SettleAssetsProductionVO> records = settleAssetsProductionVOPage.getRecords();
        for (SettleAssetsProductionVO record : records) {
            List<Long> userIdS = JSON.parseArray(record.getMembers(), Long.class);
            if (CollectionUtil.isNotEmpty(userIdS)){
                List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().in(BaseEntity::getId, userIdS).select(User::getName).ne(BaseEntity::getId,1L));
                List<String> names = users.stream().map(User::getName).collect(Collectors.toList());
                record.setJoiner(String.join(",",names));
            }
        }
        return settleAssetsProductionVOPage;
    }

    /**
     * 资产评估人员结算项目导出
     * @param settleVO vo
     * @return List<SettleAssetsProductionVO>
     */
    @Override
    public List<SettleAssetsProductionVO> assetsEvaluatorSettleExport(SettleAssetsProductionVO settleVO,Page page,String keyword) {
        List<SettleAssetsProductionVO> settleAssetsProductionVOS = financeRealFundMapper.assetsEvaluatorSettleExport(page, settleVO, keyword);
        for (SettleAssetsProductionVO record : settleAssetsProductionVOS) {
            List<Long> userIdS = JSON.parseArray(record.getMembers(), Long.class);
            if (CollectionUtil.isNotEmpty(userIdS)){
                List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().in(BaseEntity::getId, userIdS).select(User::getName).ne(BaseEntity::getId,1L));
                List<String> names = users.stream().map(User::getName).collect(Collectors.toList());
                record.setJoiner(String.join(",",names));
            }
        }
        return settleAssetsProductionVOS;
    }

    @Override
    public List<PersonalOverdueVO> overduePersonalList(PersonalOverdueVO overdueVO) {
        List<PersonalOverdueVO> list = financeRealFundMapper.overduePersonalList(overdueVO);
        return list;
    }

    @Override
    public List<FinanceRealFundExportDTO> exportList(FinanceRealFund financeRealFund, String keyword,Page page) {
        return financeRealFundMapper.exportList(page,financeRealFund,keyword);
    }

}
