package com.ruoyi.app.order;

/**
 * 订单商家操作
 */

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.app.order.dto.OrderPushBodyDto;
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.StringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.system.domain.InfoUser;
import com.ruoyi.system.domain.PosOrder;
import com.ruoyi.system.service.IInfoUserService;
import com.ruoyi.system.service.IPosOrderService;
import com.ruoyi.system.utils.Auth;
import com.ruoyi.system.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.TimerTask;

/**
 * posorderController
 *
 * @author ruoyi
 * @date 2023-05-23
 */
@RestController
@RequestMapping("/system/orderShOprate")
public class PosOrderShOprateController extends BaseController {
    @Autowired
    private IPosOrderService posOrderService;
    @Autowired
    private IInfoUserService infoUserService;
    @Autowired
    private PushEventService pushEventService;

    /**
     * 商家接单：state 从 0 改为 1
     */
    @Anonymous
    @Auth
    @GetMapping("/acceptOrder")
    public AjaxResult acceptOrder(@RequestHeader String token, @RequestParam Long id) {
        PosOrder order = posOrderService.getOne(new LambdaQueryWrapper<PosOrder>().eq(PosOrder::getId, id));
        if (order == null || order.getState() == null || order.getState() != 0L) {
            throw new ServiceException("订单不存在或状态不允许接单");
        }
        PosOrder update = new PosOrder();
        update.setId(order.getId());
        update.setState(1L);
        posOrderService.saveOrUpdate(update);
        return AjaxResult.success();
    }

    /**
     * 商家出餐：state 从 1 改为 2
     * 外送订单额外设置 deliveryStatus=0（等待骑手接单）
     */
    @Anonymous
    @Auth
    @GetMapping("/dispatchOrder")
    public AjaxResult dispatchOrder(@RequestHeader String token, @RequestParam Long id) {
        PosOrder order = posOrderService.getOne(new LambdaQueryWrapper<PosOrder>().eq(PosOrder::getId, id));
        if (order == null || order.getState() == null || order.getState() != 1L) {
            throw new ServiceException("订单不存在或状态不允许出餐");
        }
        PosOrder update = new PosOrder();
        update.setId(order.getId());
        update.setState(2L);
        // 外送订单：设置 deliveryStatus=0 等待骑手接单
        if (order.getType() != null && order.getType() == 0L) {
            update.setDeliveryStatus(0L);
        }
        posOrderService.saveOrUpdate(update);
        // 出餐推送
        chuCan(order, update);
        return AjaxResult.success();
    }

    /**
     * 商家完成（自取/堂食）：state 从 2 改为 3，payStatus 从 0 改为 1
     */
    @Anonymous
    @Auth
    @GetMapping("/completeOrder")
    public AjaxResult completeOrder(@RequestHeader String token, @RequestParam Long id) {
        PosOrder order = posOrderService.getOne(new LambdaQueryWrapper<PosOrder>().eq(PosOrder::getId, id));
        if (order == null || order.getState() == null || order.getState() != 2L) {
            throw new ServiceException("订单不存在或状态不允许完成");
        }
        // 仅限自取(type=1)或堂食(type=2)
        if (order.getType() == null || (order.getType() != 1L && order.getType() != 2L)) {
            throw new ServiceException("仅自取和堂食订单支持此操作");
        }
        PosOrder update = new PosOrder();
        update.setId(order.getId());
        update.setState(3L);
        update.setPayStatus(1L);
        posOrderService.saveOrUpdate(update);
        return AjaxResult.success();
    }

    /**
     * 商家取消订单：校验 state IN (0,1)，设 state=4
     */
    @Anonymous
    @Auth
    @GetMapping("/cancelOrder")
    public AjaxResult cancelOrder(@RequestHeader String token, @RequestParam Long id) {
        PosOrder order = posOrderService.getOne(new LambdaQueryWrapper<PosOrder>().eq(PosOrder::getId, id));
        if (order == null || order.getState() == null) {
            throw new ServiceException("订单不存在");
        }
        if (order.getState() != 0L && order.getState() != 1L) {
            throw new ServiceException("当前状态不允许取消");
        }
        PosOrder update = new PosOrder();
        update.setId(order.getId());
        update.setState(4L);
        posOrderService.saveOrUpdate(update);
        return AjaxResult.success();
    }

    /**
     * 商家出餐推送：给用户和骑手推送通知
     */
    public void chuCan(PosOrder oldOrder, PosOrder posOrder) {
        List<Long> ids = new ArrayList<>();
        ids.add(oldOrder.getUserId());
        if (oldOrder.getQsId() != null) {
            ids.add(oldOrder.getQsId());
        }
        List<InfoUser> users = infoUserService.list(new LambdaQueryWrapper<InfoUser>().in(InfoUser::getUserId, ids));
        Optional<InfoUser> user = users.stream().filter(x -> "0".equals(x.getUserType())).findFirst();
        Optional<InfoUser> qsUser = users.stream().filter(x -> "2".equals(x.getUserType())).findFirst();

        String title = "no.message.push.message";
        String content = "no.message.push.merchant.ready.content";
        Long stateVal = posOrder.getState() != null ? posOrder.getState() : oldOrder.getState();
        String stateStr = stateVal != null ? String.valueOf(stateVal) : "2";
        String body = OrderPushBodyDto.getJson(String.valueOf(oldOrder.getDdId()), stateStr);
        String ddId = String.valueOf(oldOrder.getDdId());

        if (user.isPresent()) {
            InfoUser u = user.get();
            PayPush push = new PayPush();
            Long uUserId = u.getUserId();
            String uCid = u.getCid();
            AsyncManager.me().execute(new TimerTask() {
                @Override
                public void run() {
                    PayPush.userPushHandleLocal(push, pushEventService, uUserId, uCid, title, content, body, "", ddId);
                }
            });
        }
        if (qsUser.isPresent()) {
            InfoUser qs = qsUser.get();
            if (!StringUtils.isEmpty(qs.getCid())) {
                PayPush push = new PayPush();
                Long qsUserId = qs.getUserId();
                String qsCid = qs.getCid();
                AsyncManager.me().execute(new TimerTask() {
                    @Override
                    public void run() {
                        PayPush.qsPushHandleLocal(push, pushEventService, qsUserId, qsCid, title, content, body, "", ddId);
                    }
                });
            }
        }
    }

    /**
     * 商家端订单列表（Tab分页）
     * ta
     */
    @Anonymous
    @Auth
    @GetMapping("/orderList")
    public AjaxResult orderList(@RequestHeader String token,
                                @RequestParam(defaultValue = "1") int page,
                                @RequestParam(defaultValue = "10") int size,
                                @RequestParam(required = false) String tab,
                                @RequestParam(required = false) String type) {
        JwtUtil jwtUtil = new JwtUtil();
        String userId = jwtUtil.getusid(token);
        // 查询当前用户信息
        InfoUser currentUser = infoUserService.getOne(new LambdaQueryWrapper<InfoUser>().eq(InfoUser::getUserId, Long.valueOf(userId)));
        if (currentUser == null) {
            throw new ServiceException("用户信息不存在");
        }

        LambdaQueryWrapper<PosOrder> wrapper = new LambdaQueryWrapper<>();
        String userType = currentUser.getUserType();
        if ("3".equals(userType)) {
            // 夜市商家：shId等于用户id
            wrapper.eq(PosOrder::getShId, Long.valueOf(userId));
        } else if ("1".equals(userType)) {
            // 普通商家：shId等于用户id
            wrapper.eq(PosOrder::getShId, Long.valueOf(userId));
        } else {
            // 摊位商家：mdId等于用户表中的storeId
            if (currentUser.getStoreId() == null) {
                throw new ServiceException("摊位关联门店信息不存在");
            }
            wrapper.eq(PosOrder::getMdId, currentUser.getStoreId());
        }
        if (type != null && !type.isEmpty()) {
            wrapper.eq(PosOrder::getType, Long.valueOf(type));
        }
        switch (tab) {
            case "pending":
                wrapper.eq(PosOrder::getState, 0L)
                       .and(w -> w.eq(PosOrder::getPayStatus, 1L).or().in(PosOrder::getType, 1L, 2L));
                break;
            case "preparing":
                wrapper.eq(PosOrder::getState, 1L);
                break;
            case "ready":
                wrapper.eq(PosOrder::getState, 2L).eq(PosOrder::getAfterSaleStatus, 0L);
                break;
            case "completed":
                wrapper.eq(PosOrder::getState, 3L).eq(PosOrder::getAfterSaleStatus, 0L);
                break;
            case "cancelled":
                wrapper.eq(PosOrder::getState, 4L).eq(PosOrder::getAfterSaleStatus, 0L);
                break;
            case "refund":
                wrapper.gt(PosOrder::getAfterSaleStatus, 0L);
                break;
            default:
               break;
        }
        wrapper.orderByDesc(PosOrder::getCretim);

        com.baomidou.mybatisplus.extension.plugins.pagination.Page<PosOrder> pageParam =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page, size);
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<PosOrder> result = posOrderService.page(pageParam, wrapper);

        return success(result);
    }

}
