package com.cf.imes.module.system.dal.mysql.funds.purchase;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceAmountAndAvailablePageReqVO;
import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceAmountRespVO;
import com.cf.imes.module.system.controller.admin.funds.organamount.vo.TotalSalesAmountRespVO;
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.PurchaseRecordPageReqVO;
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.SalesDetailsPageReqVO;
import com.cf.imes.module.system.dal.dataobject.funds.purchase.PurchaseRecordDO;
import com.cf.imes.module.system.enums.pay.InvoiceStatusEnum;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 购买记录 Mapper
 */
@Mapper
public interface PurchaseRecordMapper extends BaseMapperX<PurchaseRecordDO> {
    /**
     * 查询机构下可开票的金额
     *
     * @param organId
     * @return
     */
    BigDecimal getInvoicingAmount(Long organId);

    /**
     * 分页查询
     *
     * @param pageReqVO
     * @return
     */
    default PageResult<PurchaseRecordDO> selectPage(PurchaseRecordPageReqVO pageReqVO) {
        LocalDateTime[] endTimeSection = pageReqVO.getEndTimeSection();
        return selectPage(pageReqVO, new LambdaQueryWrapperX<PurchaseRecordDO>()
                .eq(PurchaseRecordDO::getDeleted, false)
                .eqIfPresent(PurchaseRecordDO::getOrganId, pageReqVO.getOrganId())
                .likeIfPresent(PurchaseRecordDO::getProductName, pageReqVO.getProductName())
                .likeIfPresent(PurchaseRecordDO::getId, pageReqVO.getId())
                .eqIfPresent(PurchaseRecordDO::getPurchaseDuration, pageReqVO.getPurchaseDuration())
                .eqIfPresent(PurchaseRecordDO::getPurchaseDurationUnit, pageReqVO.getPurchaseDurationUnit())
                .eqIfPresent(PurchaseRecordDO::getGiftDuration, pageReqVO.getGiftDuration())
                .eqIfPresent(PurchaseRecordDO::getGiftDurationUnit, pageReqVO.getGiftDurationUnit())
                .betweenIfPresent(PurchaseRecordDO::getCreateTime, pageReqVO.getCreateTime())
                .likeIfPresent(PurchaseRecordDO::getCreator, pageReqVO.getCreator())
                .eqIfPresent(PurchaseRecordDO::getTotalAmount, pageReqVO.getProductPrice())
                .geIfPresent(PurchaseRecordDO::getEndTime, ObjectUtil.isNotNull(endTimeSection) ? endTimeSection[0] : null)
                .ltIfPresent(PurchaseRecordDO::getEndTime, ObjectUtil.isNotNull(endTimeSection) ? endTimeSection[1] : null)
                .ne(PurchaseRecordDO::getInitial, true)
                .orderByDesc(PurchaseRecordDO::getCreateTime));
    }

    /**
     * 分页查询可开票记录
     *
     * @param pageReqVO
     * @return
     */
    default PageResult<PurchaseRecordDO> selectPage(InvoiceAmountAndAvailablePageReqVO pageReqVO) {
        LambdaQueryWrapper<PurchaseRecordDO> queryWrapper = new LambdaQueryWrapperX<PurchaseRecordDO>()
                .betweenIfPresent(PurchaseRecordDO::getCreateTime, pageReqVO.getCreateTime())
                .eq(PurchaseRecordDO::getOrganId, SecurityFrameworkUtils.getUserOrganId())
                .eq(PurchaseRecordDO::getDeleted, false)
                .in(PurchaseRecordDO::getIsInvocing, InvoiceStatusEnum.INVOICABLE.getCode(), InvoiceStatusEnum.INVOICINGFAILED.getCode())
                .ne(PurchaseRecordDO::getInitial, true)
                .orderByDesc(PurchaseRecordDO::getCreateTime);

        BigDecimal start = pageReqVO.getInvoiceAmountStart();
        BigDecimal end = pageReqVO.getInvoiceAmountEnd();
        if (ObjectUtil.isNotNull(start) && ObjectUtil.isNotNull(end)) {
            queryWrapper.apply("account_balance_spent + external_spent BETWEEN {0} AND {1}", start, end);
        } else if (ObjectUtil.isNotNull(start)) {
            queryWrapper.apply("account_balance_spent + external_spent >= {0}", start);
        } else if (ObjectUtil.isNotNull(end)) {
            queryWrapper.apply("account_balance_spent + external_spent <= {0}", end);
        }
        return selectPage(pageReqVO, queryWrapper);

    }

    /**
     * 查询机构下开票金额统计：可开票、开票中、已开票
     *
     * @param organId
     * @return
     */
    InvoiceAmountRespVO getOrgInvoiceAmountStatistics(Long organId);

    /**
     * 查询可开票的金额
     *
     * @param organId
     */
    BigDecimal getInvoicableAmount(Long organId, @Param("ids") List<Long> ids);

    /**
     * 查询销售总额
     *
     * @return
     */
    TotalSalesAmountRespVO getTotalSales();

    /**
     * 查询当日销售总额
     * @return
     */
    BigDecimal getTodaySales(@Param("endTime") LocalDateTime endTime);

    /**
     * 分页查询销售记录
     *
     * @return
     */
    default PageResult<PurchaseRecordDO> getSaleDetailsPage(SalesDetailsPageReqVO pageReqVO) {
        return selectPage(pageReqVO, new LambdaQueryWrapperX<PurchaseRecordDO>()
                .eqIfPresent(PurchaseRecordDO::getId, pageReqVO.getId())
                .betweenIfPresent(PurchaseRecordDO::getCreateTime, pageReqVO.getCreateTime())
                .eqIfPresent(PurchaseRecordDO::getTotalAmount, pageReqVO.getProductPrice())
                .eqIfPresent(PurchaseRecordDO::getOrganId, pageReqVO.getOrganId())
                .eqIfPresent(PurchaseRecordDO::getCreator, pageReqVO.getOperator())
                .eqIfPresent(PurchaseRecordDO::getPaymentMethod, pageReqVO.getPaymentMethod())
                .eq(PurchaseRecordDO::getDeleted, false)
                .ne(PurchaseRecordDO::getInitial, true)
                .orderByDesc(PurchaseRecordDO::getCreateTime)
                .select(PurchaseRecordDO::getId, PurchaseRecordDO::getOrganId, PurchaseRecordDO::getTotalAmount, PurchaseRecordDO::getExternalSpent,
                         PurchaseRecordDO::getCreator, PurchaseRecordDO::getCreateTime, PurchaseRecordDO::getPaymentMethod)
        );
    }

    /**
     * 根据id列表物理删除
     *
     * @param ids
     * @return 改动数量
     */
    int physicalDeleteByIds(@Param("ids") List<Long> ids, @Param("organId") Long organId);
}
