package com.neusoft.smart.pos.order.service;

import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.dto.order.request.*;
import com.neusoft.smart.pos.dto.order.response.*;
import com.neusoft.smart.pos.dto.trade.request.PostRefundRequest;
import com.neusoft.smart.pos.dto.trade.response.PostRefundResponse;
import com.neusoft.smart.pos.framework.constants.ApplicationConstants;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.framework.utils.ListUtils;
import com.neusoft.smart.pos.order.constants.TradeErrorCode;
import com.neusoft.smart.pos.order.persistent.domain.OrderRefund;
import com.neusoft.smart.pos.order.persistent.domain.OrderRefundTransaction;
import com.neusoft.smart.pos.order.repository.OrderMasterRepository;
import com.neusoft.smart.pos.order.repository.OrderRefundRepository;
import com.neusoft.smart.pos.order.repository.OrderRefundTransactionRepository;
import com.neusoft.smart.pos.payorder.persistent.domain.PayRefundOrder;
import com.neusoft.smart.pos.payorder.repository.PayRefundOrderRepository;
import com.neusoft.smart.pos.utils.PosDeviceRedisUtils;
import com.neusoft.smart.pos.utils.SequenceUtils;
import lombok.val;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service("refundOrderService")
public class RefundOrderService {
    @Autowired
    private OrderRefundRepository orderRefundRepository;

    @Autowired
    private OrderRefundTransactionRepository orderRefundTransactionRepository;

    @Autowired
    private OrderMasterRepository orderMasterRepository;

    @Autowired
    private PayRefundOrderRepository payRefundOrderRepository;

    /**
     * 创建退款单方法
     * @param createRefundOrderRequest
     * @return
     */
    public PostRefundOrderResponse createRefundOrder(PostCreateRefundOrderRequest createRefundOrderRequest) {
        OrderRefund orderRefund = saveOrderRefund(createRefundOrderRequest, null);
        val refundOrderResponse = new com.neusoft.smart.pos.dto.order.response.PostRefundOrderResponse();
        BeanUtils.copyProperties(orderRefund, refundOrderResponse);
        return refundOrderResponse;
    }

    public PostRefundOrderResponse getRefundOrderInfo(String refundOrderNum){
        OrderRefund orderRefund = orderRefundRepository.getOrderRefund(refundOrderNum);
        val refundOrderResponse = new com.neusoft.smart.pos.dto.order.response.PostRefundOrderResponse();
        BeanUtils.copyProperties(orderRefund, refundOrderResponse);

        List<PayRefundOrder> payRefundOrderList = payRefundOrderRepository.queryPayRefundOrder(orderRefund.getRefundNumber());
        List<PostRefundOrderResponse.PayRefundOrderInfo> payRefundOrderInfos = ListUtils.convertListToList(payRefundOrderList, PostRefundOrderResponse.PayRefundOrderInfo.class);
        refundOrderResponse.setPayRefundOrderInfos(payRefundOrderInfos);
        return refundOrderResponse;
    }

    /**
     * 保存退款单方法
     * @param createRefundOrderRequest
     * @param refundNumber
     * @return
     */
    private OrderRefund saveOrderRefund(PostCreateRefundOrderRequest createRefundOrderRequest, String refundNumber) {
        //1.根据订单类型校验参数信息,并获取集团及门店ID
        validateCreateOrderParams(createRefundOrderRequest);

        //2.生成当前订单号
        if (StringUtils.isEmpty(refundNumber)) {
            refundNumber = orderRefundRepository.generateRefundOrderNumber();
        }

        //3.整理orderDetails数据,并保存
        if(null != createRefundOrderRequest.getOrderRefundDetails()){
            saveRefundOrderTransations(refundNumber, createRefundOrderRequest.getOrderRefundDetails(), createRefundOrderRequest.getCreatedBy());
        }

        OrderRefund orderRefund = new OrderRefund();
        Date refundTime = new Date();
        BeanUtils.copyProperties(createRefundOrderRequest, orderRefund);
        orderRefund.setRefundNumber(refundNumber);
        orderRefund.setCreatedAt(refundTime);
        orderRefund.setRefundStatus(DictionaryConstant.REFUND_STATUS_DTK.getCode());
        orderRefundRepository.saveOrderRefund(orderRefund);
        orderRefund = orderRefundRepository.getOrderRefund(refundNumber);
        return orderRefund;
    }

    /**
     * 存储退款订单商品信息
     * @param refundNumber
     * @param orderDetails
     * @param createdBy
     */
    private void saveRefundOrderTransations(String refundNumber, List<PostOrderDetailRequest> orderDetails, String createdBy){
        for (val temp:orderDetails) {
            val orderRefundTransaction = new OrderRefundTransaction();
            if(!StringUtils.isEmpty(temp.getItemName())){
                BeanUtils.copyProperties(temp,orderRefundTransaction);
                orderRefundTransaction.setRefundNumber(refundNumber);
                orderRefundTransaction.setCreatedBy(createdBy);
                orderRefundTransactionRepository.saveRefundOrderDetails(orderRefundTransaction);
            }
        }
    }

    /**
     * 更新退款单信息方法
     * @param saveRefundOrderRequest
     * @return
     */
    public PostRefundOrderResponse saveRefundOrder(PostSaveRefundOrderRequest saveRefundOrderRequest) {
        OrderRefund orderRefund = new OrderRefund();
        BeanUtils.copyProperties(saveRefundOrderRequest, orderRefund);

        orderRefundRepository.saveOrderRefund(orderRefund);
        val orderResponse = new com.neusoft.smart.pos.dto.order.response.PostRefundOrderResponse();
        BeanUtils.copyProperties(orderRefund, orderResponse);
        return orderResponse;
    }

    /**
     * 取消退款单方法
     * @param cancleRefundOrderRequest
     * @return
     */
    public PutCancelRefundOrderResponse cancleRefundOrder(PutCancelRefundOrderRequest cancleRefundOrderRequest) {
        boolean bResult = orderRefundRepository.updateOrderRefundStatus(cancleRefundOrderRequest.getRefundOrderNumber(), DictionaryConstant.REFUND_STATUS_TKQX.getCode());
        val cancelRefundOrderResponse = new com.neusoft.smart.pos.dto.order.response.PutCancelRefundOrderResponse(bResult);
        return cancelRefundOrderResponse;
    }

    /**
     * 计算并更新退款单状态方法
     * @param refundOrderNumber
     * @return
     */
    public boolean computeRefundOrderStatus(String refundOrderNumber) {
        return false;
    }

    /**
     * 更新退款单状态方法
     * @param setRefundOrderStatusRequest
     * @return
     */
    public PutSetRefundOrderStatusResponse setRefundOrderStatus(PutSetRefundOrderStatusRequest setRefundOrderStatusRequest) {
        boolean bResult = orderRefundRepository.updateOrderRefundStatus(setRefundOrderStatusRequest.getRefundOrderNumber(), setRefundOrderStatusRequest.getRefundStatus());
        val setRefundOrderStatusResponse = new com.neusoft.smart.pos.dto.order.response.PutSetRefundOrderStatusResponse(bResult);
        return setRefundOrderStatusResponse;
    }

    /**
     * 通过退款单号获得退款单信息明细方法
     * @param refundNumber
     * @return
     */
    public GetRefundOrderInfoResponse getRefundOrderInfoByRefundNumber(String refundNumber) {
        OrderRefund orderRefund = orderRefundRepository.getOrderRefund(refundNumber);
        val getRefundOrderInfoResponse = new com.neusoft.smart.pos.dto.order.response.GetRefundOrderInfoResponse();
        BeanUtils.copyProperties(orderRefund, getRefundOrderInfoResponse);
        List<OrderRefundTransaction> orderRefundDetails = orderRefundTransactionRepository.queryRefundOrderDetails(orderRefund.getRefundNumber());
        if (null != orderRefundDetails && orderRefundDetails.size() > 0) {
            getRefundOrderInfoResponse.setOrderRefundDetailList(ListUtils.convertListToList(orderRefundDetails, GetRefundOrderInfoResponse.OrderRefundDetail.class));
        }

//        List<RefundPayOrder> orderRefunds = refundPayOrderProxy.queryRefundPayOrders(orderNumber);
//        if (null != orderRefunds && orderRefunds.size() > 0) {
//            getRefundOrderInfoResponse.setRefundPayOrderInfos(ListUtils.convertListToList(orderRefunds, GetAllOrderInfoResponse.RefundPayOrderInfo.class));
//        }
        return getRefundOrderInfoResponse;
    }

    /**
     * 通过退款单号获得退货商品列表
     * @param refundNumber
     * @return
     */
    public GetRefundOrderInfoResponse getRefundOrderGoodsListByOrderNumber(String refundNumber) {
        GetRefundOrderInfoResponse getRefundOrderInfoResponse = new GetRefundOrderInfoResponse();
        List<OrderRefundTransaction> orderRefundDetails = orderRefundTransactionRepository.queryRefundOrderDetails(refundNumber);
        if (null != orderRefundDetails && orderRefundDetails.size() > 0) {
            getRefundOrderInfoResponse.setOrderRefundDetailList(ListUtils.convertListToList(orderRefundDetails, GetRefundOrderInfoResponse.OrderRefundDetail.class));
        }
        return getRefundOrderInfoResponse;
    }

    /**
     * 执行退款流程
     * @param doPayOrderRequest
     * @return
     */
    public PostDoRefundOrderResponse doRefund(PostDoPayOrderRequest doPayOrderRequest) {
        return null;
    }

    /**
     * 根据订单类型校验创建订单相关参数信息,并存入集团ID、门店ID
     */
    private void validateCreateOrderParams(PostCreateRefundOrderRequest createRefundOrderRequest) {
        if (null == createRefundOrderRequest.getRefundableAmount()) {
            //退款金额不能为空
            throw new BusinessCommonException(TradeErrorCode.ORDER_AMOUNT_IS_EMPTY);
        }
        if (createRefundOrderRequest.getRefundableAmount().longValue() < 0) {
            //退款金额输入错误
            throw new BusinessCommonException(TradeErrorCode.ORDER_AMOUNT_ERROR);
        }
    }

    public boolean updateRefundOrderStatus(String refundNumber){
        Long hasRefuntAmountSum = orderMasterRepository.queryHasRefundAmountSumByRefundNum(refundNumber);
        OrderRefund orderRefund = orderRefundRepository.getOrderRefund(refundNumber);
        OrderRefund updateOrderRefund = new OrderRefund();
        updateOrderRefund.setRefundedAmount(hasRefuntAmountSum);
        long refundAbleAmountL = orderRefund.getRefundableAmount();
        long refundedAmountL = hasRefuntAmountSum;
        if( refundedAmountL<= 0l){
            updateOrderRefund.setRefundStatus(DictionaryConstant.REFUND_STATUS_DTK.getCode());
        }else if (refundedAmountL < refundAbleAmountL){
            updateOrderRefund.setRefundStatus(DictionaryConstant.REFUND_STATUS_TKZ.getCode());
        }else if (refundedAmountL == refundAbleAmountL){
            updateOrderRefund.setRefundStatus(DictionaryConstant.REFUND_STATUS_TKWC.getCode());
            updateOrderRefund.setRefundedTime(new Date());
        }else if (refundedAmountL > refundAbleAmountL){
            updateOrderRefund.setRefundStatus(DictionaryConstant.REFUND_STATUS_TKWC.getCode());
            updateOrderRefund.setRefundedTime(new Date());
        }else{

        }
        return orderRefundRepository.updateOrderRefund(refundNumber,updateOrderRefund);
    }
}
