package com.bofeng.service;

import com.baomidou.mybatisplus.toolkit.IdWorker;
import com.bofeng.Consts;
import com.bofeng.dao.OrderMapper;
import com.bofeng.dao.RoomMapper;
import com.bofeng.dao.UserPlaceMapper;
import com.bofeng.entity.Order;
import com.bofeng.entity.Room;
import com.bofeng.entity.StatisticsOrder;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yvan.PageDb;
import com.yvan.platform.Conv;
import lombok.val;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
@Transactional(readOnly = true)
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private UserPlaceMapper userPlaceMapper;

    @Autowired
    private RoomService roomService;

    @Autowired
    private PlaceService placeService;

    @Autowired
    private TemplateMessageService templateMessageService;

    @Autowired
    private UserOpenService userOpenService;

    @Autowired
    private NotifyOpenService notifyOpenService;

    @Autowired
    private RoomMapper roomMapper;

    public List<Order> selectAll(PageDb pageDb) {
        return orderMapper.selectAll(pageDb);
    }

    public List<Order> search(PageDb pageDb, Map<String, Object> param) {
        return orderMapper.search(pageDb, param);
    }

    public List<StatisticsOrder> groupByStatistics(PageDb pageDb, Map<String, Object> param) {
        return orderMapper.groupByStatistics(pageDb, param);
    }

    public List<Order> serchCurrentMarkList(Long saleUserId) {
        return orderMapper.serchCurrentMarkList(saleUserId);
    }

    @Transactional
    public int deleteOrder(Long orderid) {
        return orderMapper.discard(orderid);
    }

    public Order selectByOrderId(String orderId) {
        return orderMapper.selectById(orderId);
    }

    public List<Order> selectByTime(PageDb pageDb, Map<String, Object> param) {
        return orderMapper.selectBySale(pageDb, param);
    }

    public List<StatisticsOrder> groupByStatistics(Map<String, Object> queryParam) {
        return orderMapper.groupByStatistics(queryParam);
    }

    @Transactional
    public int ordersSettle(String orderStartAt, String orderEndAt, Long saleId, Long placeId) {
        val ocList = orderMapper.selectOrderBySaleIdAndTimeSpace(orderStartAt, orderEndAt, saleId, placeId);
        val openId = userOpenService.getUserByUserId(saleId).getOpenId();

        if (ocList.size() > 0) {
            List<Long> ocIds = Lists.newArrayList();
            BigDecimal amount = new BigDecimal(0);
            DateTime max = DateTime.now();
            DateTime min = DateTime.now();
            for (val oc : ocList) {
                ocIds.add(oc.getCmsId());
                amount = amount.add(oc.getCmsAmount());
                if (min.isAfter(oc.getPayAt())) {
                    min = oc.getPayAt();
                }
                if (max.isBefore(oc.getPayAt())) {
                    max = oc.getPayAt();
                }
            }

            //进行结算
            val settleId = IdWorker.getId();
            int effect = orderMapper.ordersSettle(ocIds, settleId);

            //发送结算的模版消息
            Map<String, String> messMap = Maps.newLinkedHashMap();
            messMap.put("placeName", placeService.getById(placeId).getPlaceName());
            messMap.put("payAmount", amount.toString());
            messMap.put("orderCount", ocList.size() + "");
            messMap.put("startTime", Strings.isNullOrEmpty(orderStartAt) ? min.toString("YYYY-MM-DD HH:mm:ss") : orderStartAt);
            messMap.put("endTime", Strings.isNullOrEmpty(orderEndAt) ? max.toString("YYYY-MM-DD HH:mm:ss") : orderStartAt);
            templateMessageService.sendSettleMessage(openId, "", messMap);

            // 给场地管理发消息
            val notifyOpenList = notifyOpenService.getByPlaceId(placeId);
            for (val n : notifyOpenList) {
                if (n.getOpenId() != null && !Strings.isNullOrEmpty(n.getOpenId())) {
                    templateMessageService.sendSettleMessage(n.getOpenId(), "", messMap);
                }
            }

            return effect;
        }
        return 0;
    }

    public List<Order> getCmsByUser(Long userId) {
        return orderMapper.selectCmsByUserId(userId);
    }

    @Transactional
    public String saveOrder(Order order) {

        //为空判断
        if (Conv.NL(order.getSaleUserId()) <= 0) {
            return "预订销售不能为空";
        }
        if (Conv.NL(order.getRoomId()) <= 0) {
            return "预订包厢不能为空";
        }

        //判断当前销售者是否为空，或被禁用
        val user = userService.getUserById(order.getSaleUserId());
        if (user == null || !Consts.ACT_ENABLE.equals(user.getBeActive())) {
            return "销售人员被禁用，或销售人员不存在";
        }
        order.setSaleName(user.getStaffName());

        //判断当前包厢是否为空，或被禁用
        val room = roomService.getByRoomId(order.getRoomId());
        if (room == null || !Consts.ACT_ENABLE.equals(room.getBeActive())) {
            return "包厢为空，或包厢已被禁用";
        }
        //判断当前场地是否为空，或被禁用
        val place = placeService.getById(room.getPlaceId());
        if (place == null || !Consts.ACT_ENABLE.equals(place.getBeActive())) {
            return "场地为空，或场地已被禁用";
        }
        order.setRoomName(room.getRoomName());
        order.setPlaceId(place.getPlaceId());
        order.setPlaceName(place.getPlaceName());
        order.setPaid(false);
        order.setPayAmount(null);
        order.setPayAt(null);

        Room newRoom = roomService.getByRoomId(Conv.NL(order.getRoomId()));

        if (!newRoom.getBeUse().equals("N")) {
            return "包厢已经被预定";
        }
        if (Conv.NL(order.getOrderId()) == 0) {
            order.setOrderId(IdWorker.getId());

            val result = orderMapper.insert(order);

            val result1 = roomMapper.reserveRoomById(newRoom.getRoomId());

            if (result > 0 && result1 > 0) {
                Map<String, String> messMap = Maps.newLinkedHashMap();
                messMap.put("placeName", order.getPlaceName());
                messMap.put("roomName", order.getRoomName());
                messMap.put("saleName", order.getSaleName());
                messMap.put("customerName", order.getCustomerName());
                messMap.put("time", order.getArrivalAt().toString("YYYY-MM-DD HH:mm:ss"));
                val userOpen = userOpenService.getUserByUserId(order.getSaleUserId());
                if (userOpen != null) {
                    templateMessageService.sendNewMarkMessage(userOpen.getOpenId(), "", messMap);
                    val userPlace = userPlaceMapper.getByUserIdAndPlaceId(order.getSaleUserId(), order.getPlaceId());
                    if (userPlace != null && Conv.NL(userPlace.getHigherId()) > 0) {
                        val userOpenHeigher = userOpenService.getUserByUserId(userPlace.getHigherId());
                        if (userOpenHeigher != null && !Strings.isNullOrEmpty(userOpenHeigher.getOpenId())) {
                            templateMessageService.sendNewMarkMessage(userOpenHeigher.getOpenId(), "", messMap);
                        }
                    }
                }

                // 给场地管理发消息
                val notifyOpenList = notifyOpenService.getByPlaceId(place.getPlaceId());
                for (val n : notifyOpenList) {
                    if (n.getOpenId() != null && !Strings.isNullOrEmpty(n.getOpenId())) {
                        templateMessageService.sendNewMarkMessage(n.getOpenId(), "", messMap);
                    }
                }
            }

            return "";
        }

        Order oldOrder = orderMapper.selectById(order.getOrderId());

        Room oldRoom = roomService.getByRoomId(Conv.NL(oldOrder.getRoomId()));

        if (oldOrder == null) {
            //原有订单不存在
            return "原有订单不存在";
        }

        if (oldRoom.getBeUse().equals("U")) {
            return "不能更改该预定";
        }

        if (oldOrder.getPaid()) {
            return "订单已付款，不允许修改";
        }

        Map<String, String> messMap = Maps.newLinkedHashMap();
        messMap.put("placeName", order.getPlaceName());
        messMap.put("roomName", order.getRoomName());
        messMap.put("saleName", order.getSaleName());
        messMap.put("customerName", order.getCustomerName());
        messMap.put("oldTime", oldOrder.getArrivalAt().toString("YYYY-MM-DD HH:mm:ss"));
        messMap.put("newTime", order.getArrivalAt().toString("YYYY-MM-DD HH:mm:ss"));
        val userOpen = userOpenService.getUserByUserId(order.getSaleUserId());
        if (userOpen != null) {
            templateMessageService.sendUpdateMarkMessage(userOpen.getOpenId(), "", messMap);
            val userPlace = userPlaceMapper.getByUserIdAndPlaceId(order.getSaleUserId(), order.getPlaceId());
            if (userPlace != null && Conv.NL(userPlace.getHigherId()) > 0) {
                val userOpenHeigher = userOpenService.getUserByUserId(userPlace.getHigherId());
                if (userOpenHeigher != null && !Strings.isNullOrEmpty(userOpenHeigher.getOpenId())) {
                    templateMessageService.sendUpdateMarkMessage(userOpenHeigher.getOpenId(), "", messMap);
                }
            }
        }

        // 给场地管理发消息
        val notifyOpenList = notifyOpenService.getByPlaceId(place.getPlaceId());
        for (val n : notifyOpenList) {
            if (n.getOpenId() != null && !Strings.isNullOrEmpty(n.getOpenId())) {
                templateMessageService.sendUpdateMarkMessage(n.getOpenId(), "", messMap);
            }
        }

        orderMapper.updateById(order);
        roomMapper.enableRoomById(oldRoom.getRoomId());
        roomMapper.reserveRoomById(newRoom.getRoomId());

        return "";
    }
}
