package com.rf.psychological.wxpay.service.impl;

import com.rf.psychological.dao.model.CognitiveTaskEntity;
import com.rf.psychological.enums.OrderStatus;
import com.rf.psychological.enums.wxpay.WxTradeType;
import com.rf.psychological.scale.dao.model.SubjectEntity;
import com.rf.psychological.scale.service.CognitiveTaskService;
import com.rf.psychological.scale.service.SubjectService;
import com.rf.psychological.utils.DateUtil;
import com.rf.psychological.wxpay.model.OrderInfo;
import com.rf.psychological.wxpay.repository.OrderInfoRepository;
import com.rf.psychological.wxpay.service.OrderInfoService;
import com.rf.psychological.wxpay.service.WxPayService;
import com.rf.psychological.wxpay.utils.OrderNoUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @Description:订单信息接口
 * @Author: zsf
 * @Date: 2022/6/21
 */
@Service
@Slf4j
@ConditionalOnProperty(prefix="wx.pay",name = "is_lan", havingValue = "false")
public class OrderInfoServiceImpl implements OrderInfoService {

    @Autowired
    private OrderInfoRepository orderInfoRepository;

    @Autowired
    private SubjectService subjectService;

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private CognitiveTaskService cognitiveTaskService;
    /**
     * 创建订单
     * @param productId 产品id
     * @return
     */
    @Override
    public OrderInfo createOrderByProductId(String productId, String userId, String resultId,Integer total, WxTradeType type) throws Exception {
        //根据产品id获取到和当前人id查询是否存在未支付订单
        OrderInfo orderInfo = orderInfoRepository.findByProductIdAndUserIdAndResultIdAndOrderStatus(productId,userId,resultId,OrderStatus.NOTPAY.getType());
        //如果存在，判断生成类型
        if (orderInfo != null){
            if (type.getType().equals(orderInfo.getTradeType())){
                return orderInfo;
            }else {
                //取消订单，生成新的订单
                wxPayService.cancelOrder(orderInfo.getOrderNo());
                this.cancelOrder(orderInfo.getOrderNo());
                orderInfo =  saveOrder(productId,userId,resultId,total,type);
            }
        }else {
            orderInfo =  saveOrder(productId,userId,resultId,total,type);
        }
        return orderInfo;
    }

    private OrderInfo saveOrder(String productId, String userId, String resultId, Integer total, WxTradeType type) {
        //TODO 获取产品信息，产品名称 价格
        OrderInfo orderInfo = new OrderInfo();

        SubjectEntity subject = subjectService.getSubjectEntityByFlag(productId);
        if (subject!=null){
            orderInfo.setTitle(subject.getName());
            orderInfo.setDesc(subject.getName());
        }else {
            CognitiveTaskEntity cognitiveTask =  cognitiveTaskService.getCognizeListByTaskCode(productId);
            if (cognitiveTask!=null){
                orderInfo.setTitle(cognitiveTask.getName());
                orderInfo.setDesc(cognitiveTask.getName());
            }
        }
        //生成订单
        orderInfo.setOrderNo(OrderNoUtils.getOrderNo());
        orderInfo.setProductId(productId);
        orderInfo.setUserId(userId);
        orderInfo.setTotalFee(total);
        orderInfo.setOrderStatus(OrderStatus.NOTPAY.getType());
        orderInfo.setCreateTime(DateUtil.getNowTime());
        orderInfo.setUpdateTime(DateUtil.getNowTime());
        orderInfo.setResultId(resultId);
        orderInfo.setTradeType(type.getType());
        orderInfoRepository.save(orderInfo);
        return orderInfo;
    }

    /**
     * 保存二维码地址
     * @param info
     */
    @Override
    public void saveCodeUrl(OrderInfo info) {
        info.setUpdateTime(DateUtil.getNowTime());
        orderInfoRepository.save(info);
    }

    /**
     * 查询订单列表
     * @param pageNum 页码
     * @param pageSize 数量
     * @param productId 产品id
     * @param userId 用户id
     * @param orderStatus 订单状态
     * @return
     */
    @Override
    public Page<OrderInfo> findOrderInfoList(int pageNum, int pageSize, String productId, String userId, String orderStatus) {
        if (pageNum <=0){pageNum=0;}else {pageNum = pageNum-1;}
        Specification<OrderInfo> specification = (root, query, criteriaBuilder)->{
            List<Predicate> list =new ArrayList<>();
            if (!StringUtils.isEmpty(productId)){
                list.add(criteriaBuilder.equal(root.get("productId"),productId));
            }
            if (!StringUtils.isEmpty(userId)){
                list.add(criteriaBuilder.equal(root.get("userId"),userId));
            }
            if (!StringUtils.isEmpty(orderStatus)){
                list.add(criteriaBuilder.equal(root.get("orderStatus"),orderStatus));
            }
            query.where(criteriaBuilder.and(list.toArray(new Predicate[list.size()])));
            query.orderBy(criteriaBuilder.asc(root.get("createTime")));
            return query.getRestriction();
        };
        Page<OrderInfo> orderInfos = orderInfoRepository.findAll(specification, PageRequest.of(pageNum,pageSize));
        return orderInfos;
    }

    /**
     * 获取订单状态
     * @param orderNo 订单号
     * @return
     */
    @Override
    public OrderInfo  getOrderStatus(String orderNo) {
        OrderInfo info = orderInfoRepository.findByOrderNo(orderNo);
        return info;
    }

    @Override
    public OrderInfo getOrderDetail(String orderNo) {
        return orderInfoRepository.findByOrderNoAndOrderStatus(orderNo,OrderStatus.SUCCESS.getType());
    }

    /**
     * 查询订单是否支付成功
     * @param proId 量表id
     * @param userId 用户id
     * @param resultId 报告id
     * @return
     */
    @Override
    public OrderInfo queryOrderByResultIdAndUserIdAndProId(String proId, String userId, String resultId) {
        try {
            OrderInfo info = orderInfoRepository.findByProductIdAndUserIdAndResultIdAndOrderStatus(proId,userId,resultId,OrderStatus.SUCCESS.getType());
            return info;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }

    }

    /**
     * 关闭订单
     * @param orderNo 订单编号
     */
    @Override
    public void cancelOrder(String orderNo) {
        this.updateOrderStatus(orderNo,OrderStatus.CANCEL);
    }


    /**
     * 更新状态
     * @param info 订单
     * @param success 状态值
     */
    @Override
    public void updateOrderStatus(OrderInfo info, OrderStatus success) {
        info.setOrderStatus(success.getType());
        info.setUpdateTime(DateUtil.getNowTime());
        orderInfoRepository.save(info);
    }

    /**
     * 更新状态
     * @param orderNo 订单
     * @param success 状态值
     */
    @Override
    public void updateOrderStatus(String orderNo, OrderStatus success) {
        OrderInfo info = this.orderInfoRepository.findByOrderNo(orderNo);
        info.setOrderStatus(success.getType());
        info.setUpdateTime(DateUtil.getNowTime());
        orderInfoRepository.save(info);
    }

    /**
     * 查询该状态下的所有订单
     * @param status 订单状态
     * @return
     */
    @Override
    public List<OrderInfo>  queryOrderInfoList(OrderStatus status){
        return orderInfoRepository.findByOrderStatus(status.getType());
    }

    /**
     * 校验是否支付
     * @param resultId 记录id
     * @return
     */
    @Override
    public boolean checkPayOrder(String resultId) {
        try {
            OrderInfo orderInfo = orderInfoRepository.findByResultIdAndOrderStatus(resultId,OrderStatus.SUCCESS.getType());
            if ( orderInfo == null){
                return false;
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 通过手机号查询订单列表
     * @param pageNum 页码
     * @param pageSize 数量
     * @param modelPhone 用户手机号
     * @param orderStatus 订单状态
     * @return
     */
    @Override
    public Page<OrderInfo> getOrderByUserId(int pageNum, int pageSize, String modelPhone, String orderStatus) {
        return orderInfoRepository.getOrderByUserId(modelPhone, orderStatus, PageRequest.of(pageNum - 1, pageSize));
    }

    @Override
    public OrderInfo getOrderByUserIdAndResultId(String userId, String resultId) {
        OrderInfo info = orderInfoRepository.findOrderInfoByUserIdAndResultId(userId,resultId);
        return info;
    }

    @Override
    public int countNum(String flag, String format) {
        return orderInfoRepository.countNum(flag,format);
    }


}
