package com.yuchen.saas.park.service.service.property.impl;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuchen.saas.park.api.dto.property.ChaiFenTimeDto;
import com.yuchen.saas.park.api.dto.property.SaasParkPropertyFeeStandardsDto;
import com.yuchen.saas.park.api.dto.property.SaasParkPropertyReceivableManageDto;
import com.yuchen.saas.park.api.entity.park.PmgLogPeopleCount;
import com.yuchen.saas.park.api.entity.property.SaasParkPropertyFeeStandards;
import com.yuchen.saas.park.api.entity.property.SaasParkPropertyReceivableManage;
import com.yuchen.saas.park.api.vo.property.SaasParkPropertyFeeStandardsVo;
import com.yuchen.saas.park.api.vo.property.SaasParkPropertyReceivableManageTotalVo;
import com.yuchen.saas.park.api.vo.property.SaasParkPropertyReceivableManageVo;
import com.yuchen.saas.park.service.mapper.property.SaasParkPropertyReceivableManageMapper;
import com.yuchen.saas.park.service.service.property.ISaasParkPropertyReceivableManageService;
import lombok.val;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.mp.support.Condition;
import org.nest.springwrap.core.mp.support.Query;
import org.nest.springwrap.core.tool.api.R;
import org.nest.springwrap.core.tool.utils.BeanUtil;
import org.nest.springwrap.core.tool.utils.Func;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 物业-收费-应收管理-应收账单 服务实现类
 * </p>
 *
 * @author baichaojie
 * @since 2024-09-12
 */
@Service
public class SaasParkPropertyReceivableManageServiceImpl extends BaseServiceImpl<SaasParkPropertyReceivableManageMapper, SaasParkPropertyReceivableManage> implements ISaasParkPropertyReceivableManageService {

    @Override
    public R<IPage<SaasParkPropertyReceivableManageVo>> getWeiChuZhangList(SaasParkPropertyReceivableManageDto saasParkPropertyReceivableManageDto, Query query) {

        Page<SaasParkPropertyReceivableManage> page = new Page<>(query.getCurrent(), query.getSize());
        //分页查询
        LambdaQueryWrapper<SaasParkPropertyReceivableManage> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //账单状态(0未出账、1已出账、2已冻结、3已作废)
        //lambdaQueryWrapper.eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getBillStatus()), SaasParkPropertyReceivableManage::getBillStatus, saasParkPropertyReceivableManageDto.getBillStatus())
        lambdaQueryWrapper.eq(true, SaasParkPropertyReceivableManage::getBillStatus, 0)
                //应收日期
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getAccountsReceivableDate()), SaasParkPropertyReceivableManage::getAccountsReceivableDate, saasParkPropertyReceivableManageDto.getAccountsReceivableDate())
                //收费状态
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getFeeStatus()), SaasParkPropertyReceivableManage::getFeeStatus, saasParkPropertyReceivableManageDto.getFeeStatus())
                //合同状态(预留字段)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getContractStatus()), SaasParkPropertyReceivableManage::getContractStatus, saasParkPropertyReceivableManageDto.getContractStatus())
                //账单来源(0临时收费、1账单拆分、2租赁合同、3自动生成)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getBillSource()), SaasParkPropertyReceivableManage::getBillSource, saasParkPropertyReceivableManageDto.getBillSource())
                //费用类型Id
                .like(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getFeeItemId()), SaasParkPropertyReceivableManage::getFeeItemId, saasParkPropertyReceivableManageDto.getFeeItemId())
                //逾期状态(0未逾期、eq)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getOverdueStatus()), SaasParkPropertyReceivableManage::getOverdueStatus, saasParkPropertyReceivableManageDto.getOverdueStatus())
                //滞纳金状态(0无、1有)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getLatePaymentFeeStatus()), SaasParkPropertyReceivableManage::getLatePaymentFeeStatus, saasParkPropertyReceivableManageDto.getLatePaymentFeeStatus())
                //开始时间
                .ge(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getStartTime()), SaasParkPropertyReceivableManage::getStartTime, saasParkPropertyReceivableManageDto.getStartTime())
                //结束时间
                .le(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getEndTime()), SaasParkPropertyReceivableManage::getEndTime, saasParkPropertyReceivableManageDto.getEndTime())
                //创建开始时间
                .ge(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getCreateStartTime()), SaasParkPropertyReceivableManage::getCreateStartTime, saasParkPropertyReceivableManageDto.getCreateStartTime())
                //创建结束时间
                .le(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getCreateEndTime()), SaasParkPropertyReceivableManage::getCreateEndTime, saasParkPropertyReceivableManageDto.getCreateEndTime())
                //最新入账开始时间
                .ge(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getLatestEntryStartTime()), SaasParkPropertyReceivableManage::getLatestEntryStartTime, saasParkPropertyReceivableManageDto.getLatestEntryStartTime())
                //最新入账结束时间
                .le(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getLatestEntryEndTime()), SaasParkPropertyReceivableManage::getLatestEntryEndTime, saasParkPropertyReceivableManageDto.getLatestEntryEndTime())
                //开具收据状态(0未开、1已开)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getLssuanceReceiptsStatus()), SaasParkPropertyReceivableManage::getLssuanceReceiptsStatus, saasParkPropertyReceivableManageDto.getLssuanceReceiptsStatus())
                //开具状态(0未开、1已开)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getLssuanceStatus()), SaasParkPropertyReceivableManage::getLssuanceStatus, saasParkPropertyReceivableManageDto.getLssuanceStatus())
                //开票记录状态(0未开、1已开)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getLnvoiceRecordStatus()), SaasParkPropertyReceivableManage::getLnvoiceRecordStatus, saasParkPropertyReceivableManageDto.getLnvoiceRecordStatus())
                //项目
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getParkId()), SaasParkPropertyReceivableManage::getParkId, saasParkPropertyReceivableManageDto.getParkId())
                //楼栋
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getBuildingId()), SaasParkPropertyReceivableManage::getBuildingId, saasParkPropertyReceivableManageDto.getBuildingId())


                //降序排列
                .orderByDesc(SaasParkPropertyReceivableManage::getCreateTime);
        IPage<SaasParkPropertyReceivableManage> pages = this.page(page, lambdaQueryWrapper);

        List<SaasParkPropertyReceivableManage> saasParkPropertyReceivableManageList = pages.getRecords();

        if (saasParkPropertyReceivableManageList.isEmpty()) {
            return R.data(Condition.getPage(query));
        }
        //组装返回response
        IPage<SaasParkPropertyReceivableManageVo> pageVo = new Page(pages.getCurrent(), pages.getSize(), pages.getTotal());
        List<SaasParkPropertyReceivableManageVo> records = this.listVO(pages.getRecords());

        pageVo.setRecords(records);
        return R.data(pageVo);
    }


    @Override
    public R<IPage<SaasParkPropertyReceivableManageVo>> getYiChuZhangList(SaasParkPropertyReceivableManageDto saasParkPropertyReceivableManageDto, Query query) {

        Page<SaasParkPropertyReceivableManage> page = new Page<>(query.getCurrent(), query.getSize());
        //分页查询
        LambdaQueryWrapper<SaasParkPropertyReceivableManage> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //账单状态(0未出账、1已出账、2已冻结、3已作废)
        //lambdaQueryWrapper.eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getBillStatus()), SaasParkPropertyReceivableManage::getBillStatus, saasParkPropertyReceivableManageDto.getBillStatus())
        lambdaQueryWrapper.ne(true, SaasParkPropertyReceivableManage::getBillStatus, 0)
                //应收日期
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getAccountsReceivableDate()), SaasParkPropertyReceivableManage::getAccountsReceivableDate, saasParkPropertyReceivableManageDto.getAccountsReceivableDate())
                //收费状态
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getFeeStatus()), SaasParkPropertyReceivableManage::getFeeStatus, saasParkPropertyReceivableManageDto.getFeeStatus())
                //合同状态(预留字段)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getContractStatus()), SaasParkPropertyReceivableManage::getContractStatus, saasParkPropertyReceivableManageDto.getContractStatus())
                //账单来源(0临时收费、1账单拆分、2租赁合同、3自动生成)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getBillSource()), SaasParkPropertyReceivableManage::getBillSource, saasParkPropertyReceivableManageDto.getBillSource())
                //费用类型Id
                .like(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getFeeItemId()), SaasParkPropertyReceivableManage::getFeeItemId, saasParkPropertyReceivableManageDto.getFeeItemId())
                //逾期状态(0未逾期、eq)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getOverdueStatus()), SaasParkPropertyReceivableManage::getOverdueStatus, saasParkPropertyReceivableManageDto.getOverdueStatus())
                //滞纳金状态(0无、1有)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getLatePaymentFeeStatus()), SaasParkPropertyReceivableManage::getLatePaymentFeeStatus, saasParkPropertyReceivableManageDto.getLatePaymentFeeStatus())
                //开始时间
                .ge(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getStartTime()), SaasParkPropertyReceivableManage::getStartTime, saasParkPropertyReceivableManageDto.getStartTime())
                //结束时间
                .le(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getEndTime()), SaasParkPropertyReceivableManage::getEndTime, saasParkPropertyReceivableManageDto.getEndTime())
                //创建开始时间
                .ge(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getCreateStartTime()), SaasParkPropertyReceivableManage::getCreateStartTime, saasParkPropertyReceivableManageDto.getCreateStartTime())
                //创建结束时间
                .le(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getCreateEndTime()), SaasParkPropertyReceivableManage::getCreateEndTime, saasParkPropertyReceivableManageDto.getCreateEndTime())
                //最新入账开始时间
                .ge(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getLatestEntryStartTime()), SaasParkPropertyReceivableManage::getLatestEntryStartTime, saasParkPropertyReceivableManageDto.getLatestEntryStartTime())
                //最新入账结束时间
                .le(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getLatestEntryEndTime()), SaasParkPropertyReceivableManage::getLatestEntryEndTime, saasParkPropertyReceivableManageDto.getLatestEntryEndTime())
                //开具收据状态(0未开、1已开)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getLssuanceReceiptsStatus()), SaasParkPropertyReceivableManage::getLssuanceReceiptsStatus, saasParkPropertyReceivableManageDto.getLssuanceReceiptsStatus())
                //开具状态(0未开、1已开)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getLssuanceStatus()), SaasParkPropertyReceivableManage::getLssuanceStatus, saasParkPropertyReceivableManageDto.getLssuanceStatus())
                //开票记录状态(0未开、1已开)
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getLnvoiceRecordStatus()), SaasParkPropertyReceivableManage::getLnvoiceRecordStatus, saasParkPropertyReceivableManageDto.getLnvoiceRecordStatus())
                //项目
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getParkId()), SaasParkPropertyReceivableManage::getParkId, saasParkPropertyReceivableManageDto.getParkId())
                //楼栋
                .eq(Func.isNotEmpty(saasParkPropertyReceivableManageDto.getBuildingId()), SaasParkPropertyReceivableManage::getBuildingId, saasParkPropertyReceivableManageDto.getBuildingId())


                //降序排列
                .orderByDesc(SaasParkPropertyReceivableManage::getCreateTime);
        IPage<SaasParkPropertyReceivableManage> pages = this.page(page, lambdaQueryWrapper);

        List<SaasParkPropertyReceivableManage> saasParkPropertyReceivableManageList = pages.getRecords();

        if (saasParkPropertyReceivableManageList.isEmpty()) {
            return R.data(Condition.getPage(query));
        }
        //组装返回response
        IPage<SaasParkPropertyReceivableManageVo> pageVo = new Page(pages.getCurrent(), pages.getSize(), pages.getTotal());
        List<SaasParkPropertyReceivableManageVo> records = this.listVO(pages.getRecords());

        pageVo.setRecords(records);
        return R.data(pageVo);
    }


    private List<SaasParkPropertyReceivableManageVo> listVO(List<SaasParkPropertyReceivableManage> listRecords) {
        return (List) listRecords.stream().map(entity -> {
            SaasParkPropertyReceivableManageVo saasParkPropertyReceivableManageVo = detail(entity.getId(), entity).getData();
            return saasParkPropertyReceivableManageVo;
        }).collect(Collectors.toList());

    }

    public R<SaasParkPropertyReceivableManageVo> detail(Long id, SaasParkPropertyReceivableManage saasParkPropertyReceivableManage) {
        SaasParkPropertyReceivableManageVo saasParkPropertyReceivableManageVo = new SaasParkPropertyReceivableManageVo();
        BeanUtils.copyProperties(saasParkPropertyReceivableManage, saasParkPropertyReceivableManageVo);
        return R.data(saasParkPropertyReceivableManageVo);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveOrUpdateByParam(SaasParkPropertyReceivableManageDto saasParkPropertyReceivableManageDto) {
        SaasParkPropertyReceivableManage saasParkPropertyReceivableManage = new SaasParkPropertyReceivableManage();
        BeanUtil.copyProperties(saasParkPropertyReceivableManageDto, saasParkPropertyReceivableManage);
        //保存
        boolean result = saveOrUpdate(saasParkPropertyReceivableManage);
        return result;
    }


    @Override
    public SaasParkPropertyReceivableManageTotalVo getTotal() {
        //统计出所有的记录,计算出应收笔数、钱数、滞纳金 实收 调整 转入 需收笔数 需收金额

        List<SaasParkPropertyReceivableManage> saasParkPropertyReceivableManageList = baseMapper.selectList(
                Wrappers.<SaasParkPropertyReceivableManage>query().lambda()
                //.eq(PmgLogPeopleCount::getCode, peopleConfig.getCode10001())
        );

        Float accountsReceivableAmount = 0f;
        int countReceivableAmount = 0;
        Float lateFee = 0f;
        Float adjustMoney = 0f;
        Float netReceipts = 0f;
        Float needMoney = 0f;
        Float transferMoney = 0f;
        int needCount = 0;

        for (SaasParkPropertyReceivableManage saasParkPropertyReceivableManage : saasParkPropertyReceivableManageList) {
            //应收金额
            if (saasParkPropertyReceivableManage.getAccountsReceivableAmount() != 0) {
                accountsReceivableAmount += saasParkPropertyReceivableManage.getAccountsReceivableAmount();
                countReceivableAmount += 1;
            }
            if (saasParkPropertyReceivableManage.getLateFee() != 0) {
                lateFee += saasParkPropertyReceivableManage.getLateFee();
            }
            if (saasParkPropertyReceivableManage.getAdjustTheAmount() != 0) {
                adjustMoney += saasParkPropertyReceivableManage.getAdjustTheAmount();
            }
            if (saasParkPropertyReceivableManage.getActualReceivedAmount() != 0) {
                netReceipts += saasParkPropertyReceivableManage.getActualReceivedAmount();
            }
            if (saasParkPropertyReceivableManage.getAmountToBeCollected() != 0) {
                needMoney += saasParkPropertyReceivableManage.getAmountToBeCollected();
                needCount += 1;
            }
            if (saasParkPropertyReceivableManage.getTransferMoney() != 0) {
                transferMoney += saasParkPropertyReceivableManage.getTransferMoney();
            }


        }

        SaasParkPropertyReceivableManageTotalVo saasParkPropertyReceivableManageTotalVo = new SaasParkPropertyReceivableManageTotalVo();
        //应收总钱数
        saasParkPropertyReceivableManageTotalVo.setReceivableTotal(accountsReceivableAmount);
        //应收笔数
        saasParkPropertyReceivableManageTotalVo.setReceivableCount(countReceivableAmount);
        //滞纳金
        saasParkPropertyReceivableManageTotalVo.setLateFee(lateFee);
        //调整金额
        saasParkPropertyReceivableManageTotalVo.setAdjustMoney(adjustMoney);
        //实收
        saasParkPropertyReceivableManageTotalVo.setNetReceipts(netReceipts);
        //需收金额
        saasParkPropertyReceivableManageTotalVo.setNeedMoney(needMoney);
        //需收笔数
        saasParkPropertyReceivableManageTotalVo.setNeedCount(needCount);
        //转入金额
        saasParkPropertyReceivableManageTotalVo.setTransferMoney(transferMoney);


        return saasParkPropertyReceivableManageTotalVo;
    }

    @Override
    public boolean splitOrder(SaasParkPropertyReceivableManageDto req) {
        //获取父账单的id
        Long relativeReceivableManageId = req.getRelativeReceivableManageId();

        //读取想拆分的细节
        List<ChaiFenTimeDto> listTime = req.getListTime();
        for (ChaiFenTimeDto chaiFenTimeDto : listTime) {
            //获取拆分的开始时间
            DateTime timeBegin = chaiFenTimeDto.getTimeBegin();
            //获取拆分的结束时间
            DateTime timeEnd = chaiFenTimeDto.getTimeEnd();
            //拆分到的金额
            Float account = chaiFenTimeDto.getAccount();

            //进行子账单的新增,关联关系的修改



        }
        //父账单的状态修改,关联关系的修改




        return true;
    }


}
