package cn.com.ty.lift.business.contract.service;

import cn.com.ty.lift.business.contract.dao.entity.Contracts;
import cn.com.ty.lift.business.contract.dao.entity.Payment;
import cn.com.ty.lift.business.contract.dao.entity.model.request.PaymentRequest;
import cn.com.ty.lift.business.contract.dao.entity.model.response.PaymentDetailResponse;
import cn.com.ty.lift.business.contract.dao.entity.model.response.PaymentListResponse;
import cn.com.ty.lift.business.contract.dao.entity.model.response.PaymentResponse;
import cn.com.ty.lift.business.contract.dao.mapper.PaymentMapper;
import cn.com.ty.lift.business.framework.util.MessageUtils;
import cn.com.ty.lift.common.utils.DateUtils;
import cn.com.xwy.boot.web.dto.RestResponse;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author bieao
 * @date 2019/12/11
 * @description 收款业务层
 */
@Service
public class PaymentService extends ServiceImpl<PaymentMapper, Payment> {

    /**
     * @param request 付款列表查询条件
     * @return RestResponse 付款分页列表结果
     * @description 查询付款列表
     * @date 2020/2/20 3:10 下午
     */
    public IPage<PaymentListResponse> maintenanceList(PaymentRequest request) {
        request.addDesc("work_date");
        return baseMapper.findProjectByCondition(request.getPage(), request);
    }

    /**
     * @param request 付款列表查询条件
     * @return RestResponse 付款分页列表结果
     * @description 查询大修付款列表
     * @date 2020/4/27 11:15 上午
     */
    public IPage<PaymentListResponse> capitalList(PaymentRequest request) {
        request.addDesc("work_date");
        return baseMapper.findCapitalByCondition(request.getPage(), request);
    }

    /**
     * @param request 付款详情查询条件
     * @return RestResponse 付款详情
     * @description 查询维保付款详情
     * @date 2020/4/28 2:16 下午
     */
    public PaymentResponse maintenanceDetail(PaymentRequest request) {
        PaymentResponse response = new PaymentResponse();
        PaymentDetailResponse detail = baseMapper.queryProjectDetailById(request);
        List<Payment> paymentList = paymentList(request.getId());
        response.setDetail(detail);
        response.setPaymentList(paymentList);
        return response;
    }

    /**
     * @param request 付款详情查询条件
     * @return RestResponse 付款详情
     * @description 查询大修付款详情
     * @date 2020/2/24 10:47 上午
     */
    public PaymentResponse capitalDetail(PaymentRequest request) {
        PaymentResponse response = new PaymentResponse();
        PaymentDetailResponse detail = baseMapper.queryCapitalDetailById(request);
        List<Payment> paymentList = paymentList(request.getId());
        response.setPaymentList(paymentList);
        response.setDetail(detail);
        return response;
    }

    /**
     * @param payments  付款信息
     * @param contracts 合同信息
     * @return 是否成功
     * @description 批量插入收款信息
     * @date 2019/12/11 4:34 PM
     */
    public boolean insertBatch(List<Payment> payments, Contracts contracts) {
        //设置合同付款的合同id
        payments.forEach(entry -> {
            entry.setContractsId(contracts.getId());
            entry.setCode("PA" + DateUtils.generateCode());
            entry.setType(contracts.getType());
        });
        //批量插入付款信息
        return saveBatch(payments);
    }

    /**
     * @param oldPaymentList 原有付款列表
     * @param paymentList    修改的付款列表
     * @return 操作是否成功
     * @description 新增、删除、修改付款列表
     * @date 2020/4/29 2:11 下午
     */
    public RestResponse modifyPayment(Collection<Payment> oldPaymentList, List<Payment> paymentList) {
        List<Payment> updateList = new ArrayList<>();
        List<Payment> deleteList = new ArrayList<>();
        //新增付款项
        List<Payment> insertList = paymentList.stream().filter(entry -> Objects.isNull(entry.getId())).collect(Collectors.toList());
        //比较原有收款项
        for (Payment payment : oldPaymentList) {
            Optional<Payment> optional = paymentList.stream().filter(entry -> payment.getId().equals(entry.getId())).findFirst();
            if (optional.isPresent()) {
                updateList.add(payment);
            } else {
                deleteList.add(payment);
            }
        }
        if (CollUtil.isNotEmpty(deleteList)) {
            boolean deleteResult = removeByIds(deleteList.stream().map(Payment::getId).collect(Collectors.toList()));
            if (!deleteResult) return RestResponse.fail(MessageUtils.get("msg.delete.batch.fail"));
        }
        if (CollUtil.isNotEmpty(updateList)) {
            boolean updateResult = updateBatchById(updateList, updateList.size());
            if (!updateResult) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return RestResponse.fail(MessageUtils.get("msg.modify.batch.fail"));
            }
        }
        if (CollUtil.isNotEmpty(insertList)) {
            boolean save = saveBatch(insertList, insertList.size());
            if (!save) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return RestResponse.fail(MessageUtils.get("msg.add.batch.fail"));
            }
        }
        return RestResponse.success(MessageUtils.get("msg.modify.success"));
    }

    /**
     * @param request 收款信息列表
     * @return 1.成功, 0.失败, 消息描述
     * @description 批量修改收款信息
     * @date 2019/12/11 3:50 PM
     */
    @Transactional(rollbackFor = Exception.class)
    public RestResponse modifyBatchById(PaymentRequest request) {
        List<Payment> paymentList = request.getPaymentList();
        List<Long> paymentIdList = paymentList.stream().map(Payment::getId).collect(Collectors.toList());
        //查询原有付款列表
        Collection<Payment> oldPaymentList = paymentList(paymentIdList);
        //设置合同付款的合同id
        paymentList.forEach(entry -> {
            entry.setContractsId(request.getContractId());
            entry.setCode("PA" + DateUtils.generateCode());
            entry.setType(request.getContractType());
        });
        return modifyPayment(oldPaymentList, paymentList);
    }


    /**
     * @param paymentIdList 付款id列表
     * @return Collection<Payment> 付款列表
     * @description 根据付款id列表查询付款列表
     * @date 2020/4/30 1:55 下午
     */
    public Collection<Payment> paymentList(List<Long> paymentIdList) {
        QueryWrapper<Payment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", paymentIdList);
        return listByIds(paymentIdList);
    }

    /**
     * @param contractId 合同id
     * @return paymentList 付款列表
     * @description 查询付款列表
     * @date 2020/1/17 2:57 下午
     */
    public List<Payment> paymentList(Long contractId) {
        QueryWrapper<Payment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("contracts_id", contractId);
        return list(queryWrapper);
    }
}
