package com.dayou.service.impl;

import com.dayou.brokerage.BrokerageCalculateSupport;
import com.dayou.brokerage.MarketerBrokerageCalculator;
import com.dayou.brokerage.annotation.DoBrokerage;
import com.dayou.brokerage.constants.BrokerageBusiness;
import com.dayou.brokerage.constants.BrokerageRule;
import com.dayou.common.BaseEntity;
import com.dayou.dto.PaymentDetailDTO;
import com.dayou.dto.PaymentExportDTO;
import com.dayou.entity.*;
import com.dayou.enums.OperationTypeEnum;
import com.dayou.exception.ErrorCode;
import com.dayou.mapper.PaymentCollectionMapper;
import com.dayou.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dayou.utils.DateUtils;
import com.dayou.utils.LoginContext;
import com.dayou.vo.ItemPaymentVO;
import com.dayou.vo.PaymentCollectionVO;
import com.sun.org.apache.xpath.internal.operations.Bool;
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.time.LocalDate;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;

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

import static com.dayou.enums.MainBusinessEnum.ITEM_BUSINESS;

/**
 * <p>
 * 回款记录 服务实现类
 * </p>
 *
 * @author wucl
 * @since 2023-01-10
 */
@Service
public class PaymentCollectionServiceImpl extends ServiceImpl<PaymentCollectionMapper, PaymentCollection> implements IPaymentCollectionService {

    @Autowired
    private PaymentCollectionMapper paymentCollectionMapper;

    @Autowired
    private IItemService iItemService;

    @Autowired
    private IFinanceRealFundService financeRealFundService;

    @Autowired
    private IOrderFundService orderFundService;

    @Autowired
    private IFinanceClaimService financeClaimService;

    @Override
    @SuppressWarnings("unchecked")
    public Page<PaymentCollectionVO> selectPage(Page page, PaymentCollectionVO paymentCollection){
        if (paymentCollection.getIsCurMonth()){
            paymentCollection.setLastMonth23(DateUtils.getLastMonth23(LocalDate.now().getYear(), LocalDate.now().getMonthValue() - 1));
        }
        return paymentCollectionMapper.page(page, paymentCollection);
    }

    /**
     * 回款记录导出
     */
    @Override
    public List<PaymentCollectionVO> exportPaymentCollection(PaymentCollectionVO paymentCollection) {
        if (paymentCollection.getIsCurMonth()){
            paymentCollection.setLastMonth23(DateUtils.getLastMonth23(LocalDate.now().getYear(), LocalDate.now().getMonthValue() - 1));
        }
        return paymentCollectionMapper.exportPaymentCollection(paymentCollection);
    }


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

    @DoBrokerage(operation = OperationTypeEnum.SETTLE,rule = BrokerageRule.LAND_MARKETER_RULE)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(PaymentCollection paymentCollection){
        Double amount = paymentCollection.getAmount();
        //检查实收款余额
        Long realAmountId = paymentCollection.getRealAmountId();
        BigDecimal notClaimAmount = financeRealFundService.getNotClaimAmount(realAmountId);
        if (notClaimAmount.compareTo(BigDecimal.valueOf(amount)) < 0){
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"抱歉！实收款金额小于认领金额");
        }
        //检查是否有订单收款记录
        Item item = iItemService.getById(paymentCollection.getItemId());
        Long orderFundId = paymentCollection.getOrderFundId();
        if (orderFundId ==null){
            //创建订单收款记录
            OrderFund orderFund = new OrderFund();
            orderFund.setShouldAmount(item.getAmount());
            orderFund.setOrderName(item.getName());
            orderFund.setOrderId(item.getBusinessNo());
            orderFund.setBusinessId(item.getId());
            orderFund.setBusinessType(ITEM_BUSINESS.name());
            orderFundService.add(orderFund);
            orderFundId = orderFund.getId();
        }
        if (amount==null || amount<0){
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"抱歉！回款金额不能小于0");
        }
        BigDecimal totalAmount = item.getAmount();
        if (totalAmount==null){
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"抱歉！该项目合同金额未填写，请先完善合同金额再操作。");
        }
        //创建认领记录流水表
        FinanceClaim financeClaim = new FinanceClaim();
        financeClaim.setRealFundId(realAmountId);
        financeClaim.setClaimUserId(LoginContext.getCurrentUserId());
        financeClaim.setOrderFundId(orderFundId);
        financeClaim.setClaimAmount(BigDecimal.valueOf(amount));
        financeClaim.setClaimDatetime(DateUtils.localDateToDate(paymentCollection.getPaymentDate()));
        financeClaimService.save(financeClaim);

        //更新订单收款表实收款信息
        BigDecimal totalClaimAmountByOrderFundId = financeClaimService.getTotalClaimAmountByOrderFundId(orderFundId);
        orderFundService.update(new LambdaUpdateWrapper<OrderFund>()
                .eq(OrderFund::getId, orderFundId).set(OrderFund::getRealAmount,totalClaimAmountByOrderFundId));
        return this.save(paymentCollection);
    }

    @Override
    public Boolean update(PaymentCollection paymentCollection){
        return  this.updateById(paymentCollection);
    }
    @DoBrokerage(operation = OperationTypeEnum.SETTLE,rule = BrokerageRule.LAND_MARKETER_RULE)
    @Override
    public Boolean delete(Long id){
        //逻辑删除
        return this.removeById(id);
    }

    @Override
    public IPage<ItemPaymentVO> getItemPayment(Page page,PaymentCollectionVO paymentCollectionVO) {
        IPage<ItemPaymentVO> result = paymentCollectionMapper.getItemPayment(page,paymentCollectionVO);
        return result;
    }

    @Override
    public List<PaymentDetailDTO> getPaymentDetailListByItemId(Long id,Long userId) {
        List<PaymentDetailDTO> list = paymentCollectionMapper.getPaymentDetailListByItemId(id,userId);
        return list;
    }

    @Override
    public List<PaymentExportDTO> getList(PaymentCollectionVO paymentCollectionVO) {
        List<PaymentExportDTO> list = paymentCollectionMapper.getList(paymentCollectionVO);
        return list;
    }
}
