package com.ywt.mg.services;

import com.ywt.mg.core.utils.Checker;
import com.ywt.mg.domain.entities.*;
import com.ywt.mg.domain.mealEntities.UserMealOrderView;
import com.ywt.mg.domain.models.enums.PaymentStatusEnum;
import com.ywt.mg.domain.models.nutrimeal.MealOrderInfo;
import com.ywt.mg.domain.ywtDrugEntities.PrescriptionInfo;
import com.ywt.mg.params.deposit.DepositOrderInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

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

@Service
public class OrderPaymentService extends ServiceBase {

    private static final Logger logger = LoggerFactory.getLogger(OrderPaymentService.class);

    @Autowired
    private OrderPaymentRepository orderPaymentRepository;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 根据订单流水号得到最新的商户流水号对象
     *
     * @param orderno 订单号
     * @return {@link OrderPayment}
     */
    public OrderPayment getOrderPaymentByOrderNo(String orderno) {
        return orderPaymentRepository.getOrderPaymentByOrderNo(orderno);
    }


    /**
     * 根据订单IDs得到对应的支付流水号
     *
     * @param orderIds 订单IDs
     * @return {@link List<OrderPayment>}
     */
    public List<OrderPayment> getOrderPaymentListByOrderIds(List<Integer> orderIds) {
        orderIds = orderIds.stream().filter(p-> !Checker.isNone(p) && Checker.getIntegerValue(p) > 0).collect(Collectors.toList());
        int size = orderIds.size();
        if (!Checker.isNone(orderIds)) {
            // payment_status:2 表示支付成功
            StringBuilder sqlBuilder = new StringBuilder("select * from  order_payment where payment_status = 2 and ( ");
            for (int i = 0, j = orderIds.size(); i < j; i++) {
                if (i == 0) {
                    sqlBuilder.append(" order_id = ");
                } else {
                    sqlBuilder.append(" or order_id =  ");
                }
                sqlBuilder.append(orderIds.get(i));
            }
            sqlBuilder.append(" ) limit ").append(size);
            return jdbcTemplate.query(sqlBuilder.toString(), new BeanPropertyRowMapper<>(OrderPayment.class));
        }
        return null;
    }

    public List<OrderPayment> getOrderPaymentListByRegisteredOrderList(List<RegisteredOrder> registeredOrderList) {
        if (Checker.isNone(registeredOrderList)) {
            return new ArrayList<>();
        }
        registeredOrderList = registeredOrderList.stream().filter(p -> Checker.getIntegerValue(p.getPaymentStatus()) == PaymentStatusEnum.Success.getValue()).collect(Collectors.toList());
        ;
        List<Integer> orderIds = registeredOrderList.stream().map(RegisteredOrder::getOrderId).collect(Collectors.toList());
        return getOrderPaymentListByOrderIds(orderIds);
    }

    public List<OrderPayment> getOrderPaymentListByMealOrderList(List<UserMealOrderView> list) {
        if (Checker.isNone(list)) {
            return new ArrayList<>();
        }
        list = list.stream().filter(p -> Checker.getIntegerValue(p.getPaymentStatus()) == PaymentStatusEnum.Success.getValue() && Checker.getIntegerValue(p.getWechatPayAmount()) > 0 && !Checker.isNone(p.getPaymentNo())).collect(Collectors.toList());
        List<String> paymentNos = list.stream().map(UserMealOrderView::getPaymentNo).collect(Collectors.toList());
        return getOrderPaymentListByPaymentNos(paymentNos);
    }


    private List<OrderPayment> getOrderPaymentListByPaymentNos(List<String> paymentNos) {
        paymentNos = paymentNos.stream().filter(p -> !Checker.isNone(p)).collect(Collectors.toList());
        int size = paymentNos.size();
        if (!Checker.isNone(paymentNos)) {
            // payment_status:2 表示支付成功
            StringBuilder sqlBuilder = new StringBuilder("select * from  order_payment where payment_status = 2 and ( ");
            for (int i = 0, j = paymentNos.size(); i < j; i++) {
                if (i == 0) {
                    sqlBuilder.append(" payment_no = ");
                } else {
                    sqlBuilder.append(" or payment_no =  ");
                }
                sqlBuilder.append("'" + paymentNos.get(i).trim() + "'");
            }
            sqlBuilder.append(" ) limit ").append(size);
            return jdbcTemplate.query(sqlBuilder.toString(), new BeanPropertyRowMapper<>(OrderPayment.class));
        }
        return null;
    }


    public List<OrderPayment> getOrderPaymentListByCheckResultOrderList(List<CheckResultOrder> list) {
        if (Checker.isNone(list)) {
            return new ArrayList<>();
        }
        list = list.stream().filter(p -> PaymentStatusEnum.Success.getValue() == Checker.getIntegerValue(p.getPaymentStatus()) && !Checker.isNone(p.getPaymentNo())).collect(Collectors.toList());
        List<String> paymentNos = list.stream().map(CheckResultOrder::getPaymentNo).collect(Collectors.toList());
        return getOrderPaymentListByPaymentNos(paymentNos);
    }

    public List<OrderPayment> getOrderPaymentListByOfflineConsultationList(List<OfflineConsultation> list) {
        if (Checker.isNone(list)) {
            return new ArrayList<>();
        }
        list = list.stream().filter(p -> !Checker.isNone(p.getPaymentNo())).collect(Collectors.toList());
        List<String> paymentNos = list.stream().map(OfflineConsultation::getPaymentNo).collect(Collectors.toList());
        return getOrderPaymentListByPaymentNos(paymentNos);
    }


    /**
     * 根据商户流水号得到支付记录
     *
     * @param transactionId 交易流水号
     * @return {@link OrderPayment}
     */
    public OrderPayment getOrderPaymentByTransactionId(String transactionId) {
        return orderPaymentRepository.getOrderPaymentByTransactionId(transactionId);
    }


    public List<OrderPayment> getOrderPaymentListByOutPatientOrderList(List<OutpatientOrder> list) {
        if (Checker.isNone(list)) {
            return new ArrayList<>();
        }
        list = list.stream().filter(p -> !Checker.isNone(p.getPaymentNo())).collect(Collectors.toList());
        List<String> paymentNos = list.stream().map(OutpatientOrder::getPaymentNo).collect(Collectors.toList());
        return getOrderPaymentListByPaymentNos(paymentNos);
    }

    public List<OrderPayment> getOrderPaymentListByCheckUpOrderList(List<CheckUpOrder> list) {
        if (Checker.isNone(list)) {
            return new ArrayList<>();
        }
        list = list.stream().filter(p -> !Checker.isNone(p.getPaymentNo())).collect(Collectors.toList());
        List<String> paymentNos = list.stream().map(CheckUpOrder::getPaymentNo).collect(Collectors.toList());
        return getOrderPaymentListByPaymentNos(paymentNos);
    }

    public List<OrderPayment> getOrderPaymentListByNatOrderList(List<NatOrder> list) {
        if (Checker.isNone(list)) {
            return new ArrayList<>();
        }
        list = list.stream().filter(p -> !Checker.isNone(p.getPaymentNo())).collect(Collectors.toList());
        List<String> paymentNos = list.stream().map(NatOrder::getPaymentNo).collect(Collectors.toList());
        return getOrderPaymentListByPaymentNos(paymentNos);
    }

    public String getTransactionIdByOrderId(List<OrderPayment> orderPaymentList, int orderId) {
        if (!Checker.isNone(orderPaymentList) && orderId > 0) {
            OrderPayment orderPayment = orderPaymentList.stream().filter(o -> Checker.getIntegerValue(o.getOrderId()) == orderId).findFirst().orElse(null);
            if (orderPayment != null && !Checker.isNone(orderPayment.getTransactionId())) {
                return orderPayment.getTransactionId();
            }
        }
        return "";
    }

    public List<OrderPayment> getOrderPaymentListByDepositList(List<DepositOrderInfo> list) {
        if (Checker.isNone(list)) {
            return new ArrayList<>();
        }
        list = list.stream().filter(p -> !Checker.isNone(p.getPaymentNo())).collect(Collectors.toList());
        List<String> paymentNos = list.stream().map(DepositOrderInfo::getPaymentNo).collect(Collectors.toList());
        return getOrderPaymentListByPaymentNos(paymentNos);
    }

    public List<OrderPayment> getOrderPaymentListByDepositOrderInfoList(List<DepositOrderInfo> list) {
        if (Checker.isNone(list)) {
            return new ArrayList<>();
        }
        list = list.stream().filter(p -> !Checker.isNone(p.getPaymentNo())).collect(Collectors.toList());
        List<String> paymentNos = list.stream().map(DepositOrderInfo::getPaymentNo).collect(Collectors.toList());
        return getOrderPaymentListByPaymentNos(paymentNos);
    }

    public String getTransactionIdByOrderNo(List<OrderPayment> orderPaymentList, String orderNo) {
        if (!Checker.isNone(orderPaymentList) && !Checker.isNull(orderNo)) {
            OrderPayment orderPayment = orderPaymentList.stream().filter(o -> Checker.getStringValue(o.getOrderNo()).equals(orderNo)).findFirst().orElse(null);
            if (orderPayment != null && !Checker.isNone(orderPayment.getTransactionId())) {
                return orderPayment.getTransactionId();
            }
        }
        return "";
    }

    public List<OrderPayment> getOrderPaymentListByMealOrderListB(List<MealOrderInfo> list) {
        if (Checker.isNone(list)) {
            return new ArrayList<>();
        }
        list = list.stream().filter(p -> PaymentStatusEnum.Success.getDisplayName().equals(p.getPayStatus()) && Checker.getIntegerValue(p.getWechatInt()) > 0 && !Checker.isNone(p.getPaymentNo())).collect(Collectors.toList());
        List<String> paymentNos = list.stream().map(MealOrderInfo::getPaymentNo).collect(Collectors.toList());
        return getOrderPaymentListByPaymentNos(paymentNos);
    }

    public List<OrderPayment> getOrderPaymentListByPrescriptionInfoList(List<PrescriptionInfo> prescriptionInfoList) {
        if (Checker.isNone(prescriptionInfoList)) {
            return new ArrayList<>();
        }
        prescriptionInfoList = prescriptionInfoList.stream().filter(p -> Checker.getIntegerValue(p.getPaymentStatus()) == PaymentStatusEnum.Success.getValue()).collect(Collectors.toList());
        List<Integer> orderIds = prescriptionInfoList.stream().map(PrescriptionInfo::getOrderId).collect(Collectors.toList());
        return getOrderPaymentListByOrderIds(orderIds);
    }
}
