package com.ruoyi.app.order;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.app.order.dto.OrderCreateInput;
import com.ruoyi.app.order.dto.OrderCreatItem;
import com.ruoyi.app.order.dto.OrderPushBodyDto;
import com.ruoyi.app.utils.DateUtil;
import com.ruoyi.app.utils.OperatingUtil;
import com.ruoyi.app.utils.PayPush;
import com.ruoyi.app.utils.event.PushEventService;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import com.ruoyi.system.utils.Auth;
import com.ruoyi.system.utils.JwtUtil;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.TimerTask;
import java.util.stream.Collectors;

/**
 * 用户订单Controller
 *
 * @author ruoyi
 * @date 2020-04-01
 */
@RestController
@RequestMapping("/system/userOrder")
public class UserOrderController extends BaseController {
    @Autowired
    private IOrderParentService orderParentService;
    @Autowired
    private IPosOrderService posOrderService;
    @Autowired
    private IPosStoreService posStoreService;
    @Autowired
    private IInfoAddressService infoAddressService;
    @Autowired
    private IOperatingHoursService operatingHoursService;
    @Autowired
    private IUserFootprintService userFootprintService;
    @Autowired
    private IInfoUserService infoUserService;
    @Autowired
    private PushEventService pushEventService;

    /**
     * 创建订单
     */
    @PostMapping("/createOrder")
    @Auth
    @Anonymous
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult createOrder(@RequestHeader String token, @RequestBody OrderCreateInput input)
    {
        JwtUtil jwtUtil = new JwtUtil();
        String id = jwtUtil.getusid(token);
        String shdz=null;
        if(input.getType()==0){
            InfoAddress usadd = infoAddressService.getById(input.getShdzId());
            if (usadd == null) {
                throw new ServiceException(MessageUtils.message("no.address.not.exist"));
            }
            shdz= JSON.toJSONString(usadd);
        }
        createOrderParent(input,Long.valueOf(id),shdz);
        createOrderChild(input,Long.valueOf(id),Long.valueOf(id),shdz);

        OrderParent result = orderParentService.getOne(new LambdaQueryWrapper<OrderParent>().eq(OrderParent::getDdId, input.getDdId().toString()));
        System.out.println("创建返回信息："+result);
        return super.success(result);
    }

    //创建父订单
    private void createOrderParent(OrderCreateInput input,Long UserId,String shdz){
        OrderParent orderParent = new OrderParent();
        orderParent.setUserId(UserId);
        orderParent.setOrderStatus(0L);
        orderParent.setTotalAmount(input.getTotalAmount());
        orderParent.setActualPayAmount(input.getActualPayAmount());
        orderParent.setPaymentMethod(input.getPaymentMethod());
//        orderParent.setPaymentTime(new Date());
        orderParent.setCreateTime(new Date());
//        orderParent.setUpdateTime(new Date());
        orderParent.setDdId(input.getDdId().toString());
        orderParent.setTableNum(input.getTableNum());
        orderParent.setShdzId(input.getShdzId());
        orderParent.setShAddress(shdz);
        orderParent.setType(input.getType());
        orderParent.setRemarks(input.getRemarks());
        orderParentService.save(orderParent);
    }
    //创建子订单
    private void createOrderChild(OrderCreateInput input,Long orderParentId,Long userId,String shdz){
        // 检查items是否为空
        if (input.getItems() == null || input.getItems().isEmpty()) {
            throw new ServiceException(MessageUtils.message("订单商品不能为空"));
        }
        String ddId = input.getDdId().toString();
        List<Long> mdIdList = input.getItems().stream().map(OrderCreatItem::getMdId).collect(Collectors.toList());
        // 将Long类型的门店ID转换为Integer类型用于查询（因为PosStore.getId()返回Integer）
        List<Integer> mdIdIntegerList = mdIdList.stream().map(Long::intValue).collect(Collectors.toList());
        List<PosStore> storeList = posStoreService.list(new LambdaQueryWrapper<PosStore>().in(PosStore::getId, mdIdIntegerList));
        LambdaQueryWrapper<OperatingHours> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(OperatingHours::getMdId, mdIdList);
        List<OperatingHours> hourslist = operatingHoursService.list(wrapper);
        boolean isMultiStore = input.getItems().size() > 1;
        // 循环items，为每个item创建一条PosOrder
        int index = 0;
        for (OrderCreatItem item : input.getItems()) {

            // 检查门店是否开放
            checkStoreOpen(storeList,hourslist,item);
            index++;
            // 单店铺：子订单号与父订单一致；多店铺：子订单号追加序号
            String subddId = isMultiStore ? ddId + String.format("%03d", index) : ddId;
            PosOrder posOrder = new PosOrder();
            posOrder.setIsDisplay(false);
            handleIsDisplay(posOrder);
            posOrder.setShdzId(input.getShdzId());
            // 设置子订单的基本信息
            posOrder.setDdId(subddId);
            posOrder.setParentDdId(input.getDdId().toString()); // 设置父订单ID
            posOrder.setCretim(new Date());
            posOrder.setState(0L); // 初始状态
            // 根据item设置订单信息
            posOrder.setShId(item.getShId());
            posOrder.setMdId(item.getMdId());
            posOrder.setShdzId(input.getShdzId());
            posOrder.setUserId(userId);
            posOrder.setAmount(item.getAmount());
            posOrder.setRemarks(item.getRemarks());
            posOrder.setType(item.getType());
            posOrder.setDelryTime(item.getDelryTime());
            posOrder.setFood(JSON.toJSONString(item.getFood()));
            if("1".equals(input.getPaymentMethod())){
                posOrder.setCollectPayment("1");
            }
            // 设置支付相关信息（从父订单继承）
            posOrder.setPayType(input.getPaymentMethod());
            //设置桌号（从父订单继承）
            posOrder.setTableNum(input.getTableNum());
            posOrder.setLogo(item.getLogo());
            posOrder.setPosName(item.getPosName());
            posOrder.setJvli(item.getJvli());
            posOrder.setFreight(item.getFreight());
            posOrder.setShdzId(input.getShdzId());
            posOrder.setShAddress(shdz);
            posOrder.setFoodAmount(item.getFoodAmount());
           Optional<PosStore> storeOptional = storeList.stream()
                   .filter(x -> item.getMdId().equals(Long.valueOf(x.getId())))
                   .findFirst();
           if (storeOptional.isEmpty()) {
               throw new ServiceException(MessageUtils.message("no.mendian.not.exist"));
           }
           PosStore store = storeOptional.get();
            posOrder.setLongitude(store.getLongitude());
            posOrder.setLatitude(store.getLatitude());
            //设置订单分类
            storeList.stream().filter(s -> Long.valueOf(s.getId()).equals(item.getMdId())).findFirst().ifPresent(st -> {
                posOrder.setOrderCategory(String.valueOf(st.getType()));
            });
            // 保存子订单
            createFootprint(userId, item.getMdId());
            posOrderService.save(posOrder);

            // 创建订单成功，给商家推送"您有新订单了"
            InfoUser shUser = infoUserService.getById(item.getShId());
            if (shUser != null && !StringUtils.isEmpty(shUser.getCid())) {
                PayPush push = new PayPush();
                String title = "no.message.push.message";
                String content = "no.message.push.new.order";
                String body = OrderPushBodyDto.getJson(subddId, String.valueOf(posOrder.getState()), 0);
                Long shUserId = shUser.getUserId();
                String cid = shUser.getCid();

                AsyncManager.me().execute(new TimerTask() {
                    @Override
                    public void run() {
                        PayPush.shPushHandleLocal(push, pushEventService, shUserId, cid, title, content, body, "", subddId);
                    }
                });
            }
        }
    }

    //设置显示状态
    private void handleIsDisplay(PosOrder posOrder){
        if (StringUtils.isEmpty(posOrder.getDelryTime())) {
            posOrder.setIsDisplay(true);
            posOrder.setDisplayTime(new Date());
        }
        //预约单不在时间范围内不显示
        if (StringUtils.isNotEmpty(posOrder.getDelryTime())) {
            int minute = DateUtil.getAppoinmentOrderHandleTime();
            boolean isNear = DateUtil.isNearOrPastStartTime(posOrder.getDelryTime(), minute);
            if (isNear) {
                posOrder.setIsDisplay(true);
                posOrder.setDisplayTime(new Date());
            }
        }
    }


    private void createFootprint(Long uid,Long mdId){
        QueryWrapper<UserFootprint> Wrapper = new QueryWrapper<>();
        Wrapper.eq("user_id", uid);
        Wrapper.eq("md_id", mdId);
        UserFootprint foot = userFootprintService.getOne(Wrapper);
        DateUtil dateString = new DateUtil();
        if (foot == null) {
            UserFootprint usf = new UserFootprint();
            usf.setUserId(uid);
            usf.setMdId(mdId);
            usf.setCretim(dateString.GetDate());
            userFootprintService.saveOrUpdate(usf);
        } else {
            foot.setCretim(dateString.GetDate());
            userFootprintService.saveOrUpdate(foot);
        }
    }
    /**
     * 检查门店是否开放
     */
    private void checkStoreOpen( List<PosStore> storeList,List<OperatingHours> hourslist, OrderCreatItem item) {
        List<OperatingHours> storeHourslist = hourslist.stream().filter(x-> x.getMdId().equals(item.getMdId())).collect(Collectors.toList());
        PosStore store = storeList.stream()
                .filter(x -> Long.valueOf(x.getId()).equals(item.getMdId()))
                .findFirst()
                .orElseThrow(() -> new ServiceException(MessageUtils.message("no.mendian.not.exist")));
        if (storeHourslist.isEmpty()) {
            throw new ServiceException(store.getPosName()+MessageUtils.message("no.mendian.not.set.business.hours"));
        }
        if (store.getState() == 1) {
            throw new ServiceException(store.getPosName()+MessageUtils.message("no.mendian.is.closed"));
        }
        boolean isOperating = OperatingUtil.storeIsOperatingOfDay(storeHourslist);
        if (!isOperating) {
            throw new ServiceException(store.getPosName()+MessageUtils.message("no.mendian.is.closed"));
        }
    }

    /**
     * 获取父订单详情
     */
    @GetMapping("/getParentOrderDetail")
    @Auth
    @Anonymous
    public AjaxResult getParentOrderDetail(@RequestHeader String token, @RequestParam String ddId){
        OrderParent result = orderParentService.getOne(new LambdaQueryWrapper<OrderParent>().eq(OrderParent::getDdId,ddId));
        List<PosOrder> posOrders = posOrderService.list(new LambdaQueryWrapper<PosOrder>().eq(PosOrder::getParentDdId,ddId).orderBy(true,true,PosOrder::getCretim));
        result.setItems(posOrders);
        return super.success(result);
    }


}
