package com.younike.system.service.impl;

import com.younike.common.core.domain.AjaxResult;
import com.younike.common.exception.ServiceException;
import com.younike.common.utils.SecurityUtils;
import com.younike.hlpay.dto.OrderParam;
import com.younike.system.domain.*;
import com.younike.system.domain.vo.OrderVo;
import com.younike.system.domain.vo.OrdersVO;
import com.younike.system.domain.vo.ReconciliationVo;
import com.younike.system.mapper.*;
import com.younike.system.param.OrderQueryParam;
import com.younike.system.param.UjdChangeRedordQueryParam;
import com.younike.system.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static java.math.BigDecimal.ZERO;

/**
 * 订单主Service业务层处理
 *
 * @author jubs
 * @date 2022-01-05
 */
@Service
public class MerchantOrderServiceImpl implements  IMerchantOrderService {
    @Autowired
    private MerchantOrderMapper orderMapper;
    @Autowired
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private IOrderGoodsService orderGoodsService;
    @Autowired
    private ISysCodeService sysCodeService;
    @Autowired
    private IOrderModifyService orderModifyService;
    @Autowired
    private IOrderPaymentService orderPaymentService;
    @Autowired
    private ServerTimeMapper serverTimeMapper;
    @Autowired
    private IServerTimeBookService serverTimeBookService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IMerchantService merchantService;
    @Autowired
    private UjdChangeRecordMapper ujdChangeRecordMapper;
    @Autowired
    private GoodsSpecificationMapper goodsSpecificationMapper;

    @Autowired
    private IOrderVerificationRecordService orderVerificationRecordService;

    /**
     * 查询订单主
     *
     * @param orderId 订单主主键
     * @return 订单主
     */
    @Override
    public OrdersVO selectOrderByOrderId(Long orderId) {

        OrdersVO ordersVO = orderMapper.selectOrderByOrderId(orderId);
        if (ordersVO != null && ordersVO.getGoodsSpecificationId() != null) {
            // 查询规格描述
            GoodsSpecification goodsSpecification = goodsSpecificationMapper.selectGoodsSpecificationByGoodsSpecificationId(ordersVO.getGoodsSpecificationId());
            ordersVO.setSpecificationDesc(goodsSpecification == null ? "-" : goodsSpecification.getSpecificationDesc());
        }
        if("003".equals(ordersVO.getOrderType())){
            OrderVerificationRecord orderVerificationRecord = new OrderVerificationRecord();
            orderVerificationRecord.setOrderId(ordersVO.getOrderId());
            //查询订单核销记录
            ordersVO.setOrderVerificationRecordList(orderVerificationRecordService.selectOrderVerificationRecordList(orderVerificationRecord));
        }
        //规格单位
        if(!"999".equals(ordersVO.getGoodsUnit())){
            //查询到的数据
            ordersVO.setOtherUnit(ordersVO.getDictLabel());
        }

        return ordersVO;
    }

    /**
     * 查询订单主列表
     *
     * @param order 订单主
     * @return 订单主
     */
    @Override
    public List<OrdersVO> selectOrderList(OrdersVO order)
    {

        return orderMapper.selectOrderList(order);
    }

    /**
     * 新增订单主
     *
     * @param order 订单主
     * @return 结果
     */
    @Override
    public int insertOrder(OrdersVO order)
    {
//        order.setCreateTime(DateUtils.getNowDate());
        return orderMapper.insertOrder(order);
    }

    /**
     * 修改订单主
     *
     * @param order 订单主
     * @return 结果
     */
    @Override
    public int updateOrder(OrdersVO order)
    {
        return orderMapper.updateOrder(order);
    }

    /**
     * 批量删除订单主
     *
     * @param orderIds 需要删除的订单主主键
     * @return 结果
     */
    @Override
    public int deleteOrderByOrderIds(Long[] orderIds)
    {
        return orderMapper.deleteOrderByOrderIds(orderIds);
    }

    /**
     * 删除订单主信息
     *
     * @param orderId 订单主主键
     * @return 结果
     */
    @Override
    public int deleteOrderByOrderId(Long orderId)
    {
        return orderMapper.deleteOrderByOrderId(orderId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int modifyPrice(OrdersVO order) {
        Long orderId = order.getOrderId();
        if (Objects.isNull(orderId)){
            throw new ServiceException("订单id不能为空");
        }
        OrdersVO exist = selectOrderByOrderId(orderId);
        if (Objects.isNull(exist)){
            throw new ServiceException("订单不存在或已被删除");
        }
        if (!"000".equals(exist.getOrderState())){
            throw new ServiceException("只有待支付状态的订单可以改价");
        }
        BigDecimal price = order.getPrice();
        if (Objects.isNull(price) || price.compareTo(ZERO) <= 0){
            throw new ServiceException("商品单价不能为空且必须大于0");
        }
        // 1. 修改商品单价
        OrderGoods updateOrderGoods = new OrderGoods();
        BigDecimal existPrice = orderGoodsService.selectOrderGoodsByOrderId(orderId).getPrice();
        updateOrderGoods.setOrderId(orderId);
        updateOrderGoods.setPrice(price);
        orderGoodsService.updateOrderGoods(updateOrderGoods);

        // 2. 重新计算订单金额
        OrdersVO updateOrder = new OrdersVO();
        updateOrder.setOrderId(orderId);
        // 2.1 总金额
        updateOrder.setOrderAmount(exist.getGoodsCounts().multiply(price));
        // 2.2 实付金额（去除优金豆和优惠金额）
        BigDecimal totalAmount = updateOrder.getOrderAmount();
        if (Objects.nonNull(exist.getBeanAmount())){
            totalAmount = totalAmount.subtract(BigDecimal.valueOf(exist.getBeanAmount()/100));
        }
        if (Objects.nonNull(exist.getCouponAmount())){
            totalAmount = totalAmount.subtract(exist.getCouponAmount());
        }
        updateOrder.setTotalAmount(totalAmount);

        // 3. 计算店铺可得
        //平台抽成百分比
        BigDecimal percaent = new BigDecimal(sysConfigMapper.checkConfigKeyUnique("platform.commission.rate").getConfigValue());
        BigDecimal shopAmount= totalAmount.subtract(totalAmount.multiply(percaent).divide(new BigDecimal(100),2,BigDecimal.
                ROUND_HALF_UP));
        //判断有无使用优金豆，如果有，加上优金豆优惠金额
        //判断优金豆抵扣金额
        if(Objects.nonNull(exist.getBeanAmount())){
            shopAmount.add(new BigDecimal(exist.getBeanAmount())
                    .divide(new BigDecimal(100)));
        }

        // 4. 记录修改履历
        OrderModify orderModify = new OrderModify();
        orderModify.setOrderId(orderId);
        orderModify.setOriginalPrice(existPrice);
        orderModify.setModifyPrice(price);
        orderModifyService.insertOrderModify(orderModify);
        orderPaymentService.clearPaymentStr(orderId);

        updateOrder.setUpdateTime(LocalDateTime.now());
        updateOrder.setUpdateBy(SecurityUtils.getUserId().toString());
        return orderMapper.updateOrder(updateOrder);
    }

    /**
     * 修改上门时间
     * @param o
     * @return
     */
    @Override
    public AjaxResult updateServiceStartTime(OrdersVO o) {
        //根据账号id查数据
        OrdersVO ordersVO = orderMapper.selectOrderByOrderId(o.getOrderId());
        if(ObjectUtils.isEmpty(ordersVO)){
            return AjaxResult.error("订单不存在");
        }
        if(!"001".equals(ordersVO.getOrderState())){
            return AjaxResult.error("当前订单状态不可进行修改上门时间");
        }
        if(o.getAppointmentStartTime().compareTo(new Date())<0){
            return AjaxResult.error("修改上门时间不可小于当前时间");
        }
        Merchant merchant = merchantService.selectMerchantByMerchantId(ordersVO.getMerchantId());

        //查出订单时长  单次服务标准时长×服务次数
        BigDecimal multiply = ordersVO.getGoodsCounts().multiply(ordersVO.getSingleTime());
        //要修改的上门时间
        LocalDateTime appointmentStart = o.getAppointmentStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        LocalDateTime appointmentEnd = orderService.recordAppointmentInfo(appointmentStart, multiply, Long.valueOf(ordersVO.getServerId()), merchant.getAllowCompose());


        OrderParam  param = new OrderParam();
        //开始时间
        param.setAppointmentStartTime(appointmentStart);
        //结束时间
        param.setAppointmentEndTime(appointmentEnd);
        param.setServerId(Long.valueOf(ordersVO.getServerId()));
        param.setOrderId(o.getOrderId());
        //星期几
        //验证预约结束时间是否超出服务人员工作时间
        // 结束时间不排除两订单间隔时间（下班时间）
        LocalDateTime appointmentEndTime =param.getAppointmentStartTime().plusMinutes((long)(multiply.doubleValue() * 60));
        param.setAppointmentEndTime(appointmentEndTime);
        Date from = Date.from(appointmentEndTime.atZone(ZoneId.systemDefault()).toInstant());
        o.setAppointmentEndTime(from);

        if(this.updateOrder(o)<1){
            return AjaxResult.error("修改上门时间失败");
        }

        return AjaxResult.success();
    }

    /**
     * 修改上门时间校验
     * @param o
     * @return
     */
    @Override
    public AjaxResult editVerify(OrdersVO o) {
        //根据账号id查数据
        OrdersVO ordersVO = orderMapper.selectOrderByOrderId(o.getOrderId());
        if(ObjectUtils.isEmpty(ordersVO)){
            return AjaxResult.error("订单不存在");
        }
        if(!"001".equals(ordersVO.getOrderState())){
            return AjaxResult.error("当前订单状态不可进行修改上门时间");
        }
        if(o.getAppointmentStartTime().compareTo(new Date())<0){
            return AjaxResult.error("修改上门时间不可小于当前时间");
        }

        //查出订单时长  单次服务标准时长×服务次数
        BigDecimal multiply = ordersVO.getGoodsCounts().multiply(ordersVO.getSingleTime());

        ServerTime serverTime = serverTimeMapper.selectServerTimeByServerId(Long.valueOf(ordersVO.getServerId()));
        if(ObjectUtils.isEmpty(serverTime)){
            return AjaxResult.error("服务人员查无服务时间");
        }
        if(serverTime.getStopOrder() == 1){
            return AjaxResult.success( "服务人员已经停止接单,是否确认修改上门服务时间？",201);
        }

        BigDecimal serverGrap = serverTime.getServerGrap();

        //要修改的上门时间
        LocalDateTime localDateTime = o.getAppointmentStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        //计算出预约结束时间(预约结束时间加上服务人员休息时间间隔)
        LocalDateTime serverEndTime =localDateTime.plusMinutes((long)(multiply.add(serverGrap).doubleValue() * 60));

        OrderParam  param = new OrderParam();
        //开始时间
        param.setAppointmentStartTime(localDateTime);
        //结束时间
        param.setAppointmentEndTime(serverEndTime);
        param.setServerId(Long.valueOf(ordersVO.getServerId()));
        param.setOrderId(o.getOrderId());
        //星期几
        //验证预约结束时间是否超出服务人员工作时间
        // 结束时间不排除两订单间隔时间（下班时间）
        LocalDateTime appointmentEndTime =param.getAppointmentStartTime().plusMinutes((long)(multiply.doubleValue() * 60));
        param.setAppointmentEndTime(appointmentEndTime);

        // 服务人员预约时间段列表
        List<ServerTimeBook> serverTimeBookList = serverTimeBookService
                .selectAvailableServerTimeBookList(param.getServerId(), param.getAppointmentStartTime().toLocalDate(),
                        param.getAppointmentStartTime().toLocalTime(), serverEndTime.toLocalTime());

        for (ServerTimeBook serverTimeBook : serverTimeBookList) {
            if (serverTimeBook.getBooked() > 0) {
                // 预约时间段中存在已被预约时间段
                return AjaxResult.success("修改预约时间段中存在已被预约时间段或服务人员休息时间,是否确认修改上门服务时间？",201);
            }
        }

        return AjaxResult.success("可预约",200);
    }

    /**
     * 财务对账：查询订单账单
     * @param vo
     * @return
     */
    @Override
    public List<ReconciliationVo> selectReconciliationOrderList(ReconciliationVo vo) {



        List<ReconciliationVo> reconciliationVos = orderMapper.selectReconciliationOrderList(vo);
//        判断订单是否支付
        for (ReconciliationVo reconciliationVo: reconciliationVos) {
            //支付成功
            if(reconciliationVo.getIsSettle() == 1) {
                //判断追加服务是否支付成功
                if (reconciliationVo.getAddPayStatus() == null || reconciliationVo.getAddPayStatus() == 0) {
                    reconciliationVo.setShopMoney(reconciliationVo.getShopAmount());
                    reconciliationVo.setTerraceMoney(reconciliationVo.getTotalAmount().subtract(reconciliationVo.getShopMoney()));
                } else if (reconciliationVo.getAddPayStatus() == 1) {
                    reconciliationVo.setShopMoney(reconciliationVo.getShopAmount().add(reconciliationVo.getAddShopAmount()));
                    reconciliationVo.setTerraceMoney(reconciliationVo.getTotalAmount().subtract(reconciliationVo.getShopMoney()));
                }
            }else {
//                //店铺可得金额
                reconciliationVo.setShopMoney(new BigDecimal(0));
                //平台可得金额
                reconciliationVo.setTerraceMoney(new BigDecimal(0));
            }
        }


        return reconciliationVos;
    }

    /**
     * 统计店铺入账总金额，以及平台抽成
     *
     * @param vo
     * @return
     */
    @Override
    public ReconciliationVo orderStatistics(ReconciliationVo vo) {
        ReconciliationVo statistics = new ReconciliationVo();

        //查询店铺实收金额统计 主订单店铺收入
        ReconciliationVo reconciliationVo = orderMapper.getOrderStatistics(vo);
        //查询追加服务店铺收入
        ReconciliationVo addShopAmount = orderMapper.getOrderAddStatistics(vo);
        if (ObjectUtils.isEmpty(reconciliationVo)) {
            statistics.setShopMoney(new BigDecimal(0));
            statistics.setTerraceMoney(new BigDecimal(0));
            return statistics;
        }
        if (ObjectUtils.isEmpty(addShopAmount)) {
            statistics.setShopMoney(reconciliationVo.getShopMoney());
        } else {
            statistics.setShopMoney(reconciliationVo.getShopMoney().add(addShopAmount.getAddShopAmount()));
        }
        statistics.setTerraceMoney(reconciliationVo.getTotalAmount().subtract(statistics.getShopMoney()));

        return statistics;
    }

    /**
     * 运营管理：财务对账：查询订单账单
     *
     * @param vo
     * @return
     */
    @Override
    public List<ReconciliationVo> getReconciliationOrderList(ReconciliationVo vo) {
        List<ReconciliationVo> reconciliationVos = orderMapper.getReconciliationOrderList(vo);
//        判断订单是否支付
        for (ReconciliationVo reconciliationVo : reconciliationVos) {
            //支付成功
            if (reconciliationVo.getIsSettle() == 1) {
                //判断追加服务是否支付成功
                if (reconciliationVo.getAddPayStatus() == null || reconciliationVo.getAddPayStatus() == 0) {
                    reconciliationVo.setShopMoney(reconciliationVo.getShopAmount());
                    reconciliationVo.setTerraceMoney(reconciliationVo.getTotalAmount().subtract(reconciliationVo.getShopMoney()));
                } else if (reconciliationVo.getAddPayStatus() == 1) {
                    reconciliationVo.setShopMoney(reconciliationVo.getShopAmount().add(reconciliationVo.getAddShopAmount()));
                    reconciliationVo.setTerraceMoney(reconciliationVo.getTotalAmount().subtract(reconciliationVo.getShopMoney()));
                }
            } else {
//                //店铺可得金额
                reconciliationVo.setShopMoney(new BigDecimal(0));
                //平台可得金额
                reconciliationVo.setTerraceMoney(new BigDecimal(0));
            }
        }


        return reconciliationVos;
    }

    /**
     * 运营管理:统计店铺入账总金额，以及平台抽成
     *
     * @param vo
     * @return
     */
    @Override
    public ReconciliationVo adminOrderStatistics(ReconciliationVo vo) {


        ReconciliationVo statistics = new ReconciliationVo();

        //运营管理:查询店铺实收金额统计 主订单店铺收入
        ReconciliationVo reconciliationVo = orderMapper.getAdminOrderStatistics(vo);
        //运营管理:查询追加服务店铺收入
        ReconciliationVo addShopAmount = orderMapper.getAdminOrderAddStatistics(vo);
        if (ObjectUtils.isEmpty(reconciliationVo)) {
            statistics.setShopMoney(new BigDecimal(0));
            statistics.setTerraceMoney(new BigDecimal(0));
            return statistics;
        }
        if (ObjectUtils.isEmpty(addShopAmount)) {
            statistics.setShopMoney(reconciliationVo.getShopMoney());
        } else {
            statistics.setShopMoney(reconciliationVo.getShopMoney().add(addShopAmount.getAddShopAmount()));
        }
        statistics.setTerraceMoney(reconciliationVo.getTotalAmount().subtract(statistics.getShopMoney()));

        return statistics;
    }

    /**
     * 保证金运营list
     * @param ujdChangeRedordQueryParam
     * @return
     */
    @Override
    public List<UjdChangeRecord> reconciliationlist(UjdChangeRedordQueryParam ujdChangeRedordQueryParam) {



        return orderMapper.reconciliationlist(ujdChangeRedordQueryParam);
    }

    /**
     * 查询团购订单分页列表
     *
     * @param queryParam
     * @return
     */
    @Override
    public List<OrdersVO> listGroupOrder(OrderQueryParam queryParam) {


        List<OrdersVO> ordersVOList = orderMapper.listOrder(queryParam);

        if (CollectionUtils.isEmpty(ordersVOList)) {
            return Lists.newArrayList();
        }

        // 处理规格数据
        for (OrdersVO ordersVO : ordersVOList) {
            if (Objects.isNull(ordersVO.getGoodsSpecificationId())) {
                continue;
            }
            // 次数
            if (ordersVO.getGroupTimes() != null && ordersVO.getGroupRemainingTimes() != null) {
                ordersVO.setTimes(ordersVO.getGroupRemainingTimes() + "/" + ordersVO.getGroupTimes());
            }
            // 查询规格信息
            GoodsSpecification goodsSpecification = goodsSpecificationMapper.selectGoodsSpecificationByGoodsSpecificationId(ordersVO.getGoodsSpecificationId());
            ordersVO.setSpecificationDesc(goodsSpecification == null ? null : goodsSpecification.getSpecificationDesc());
            ordersVO.setSpecificationCurrentPrice(goodsSpecification == null ? null : goodsSpecification.getCurrentPrice());
        }

        return ordersVOList;
    }

    /**
     * 根据核销码查询订单详情信息
     *
     * @param orderVerificationCode
     * @return
     */
    @Override
    public OrdersVO getOrderByVerificationCode(String orderVerificationCode) {
        OrdersVO ordersVO = orderMapper.getOrderByVerificationCode(orderVerificationCode);
        if (ordersVO != null && ordersVO.getGoodsSpecificationId() != null) {
            // 查询规格描述
            GoodsSpecification goodsSpecification = goodsSpecificationMapper.selectGoodsSpecificationByGoodsSpecificationId(ordersVO.getGoodsSpecificationId());
            ordersVO.setSpecificationDesc(goodsSpecification == null ? "-" : goodsSpecification.getSpecificationDesc());
        }
        return ordersVO;
    }

}
