package com.bonus.canteen.core.order.controller;

import cn.hutool.core.collection.CollUtil;
import com.bonus.canteen.core.order.domain.OrderInfo;
import com.bonus.canteen.core.order.domain.OrderRefundHistoryVO;
import com.bonus.canteen.core.order.domain.param.*;
import com.bonus.canteen.core.order.service.IOrderInfoService;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.utils.poi.ExcelUtil;
import com.bonus.common.core.web.controller.BaseController;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.core.web.page.TableDataInfo;
import com.bonus.common.log.annotation.SysLog;
import com.bonus.common.log.enums.OperaType;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Objects;

/**
 * 订单Controller
 * 
 * @author ruoyi
 * @date 2025-04-14
 */
@Controller
@RequestMapping("/order")
public class OrderInfoController extends BaseController
{
    @Autowired
    private IOrderInfoService orderInfoService;

    /**
     * 查询订单列表
     */
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo h5List(@RequestBody @Valid OrderQueryParam orderQueryParam)
    {
        if(Objects.isNull(orderQueryParam.getUserId())) {
            throw new ServiceException("用户ID不能为空");
        }
        startPage();
        List<OrderInfo> list = orderInfoService.selectOrderInfoList(orderQueryParam);
        return getDataTable(list);
    }

    @PostMapping("/web/refund/list")
    @ResponseBody
    public TableDataInfo webRefundList(@RequestBody @Valid OrderRefundHistoryParam param)
    {
        startPage();
        List<OrderRefundHistoryVO> list = orderInfoService.orderRefundHistory(param);
        return getDataTable(list);
    }

    @PostMapping("/web/list")
    @ResponseBody
    public TableDataInfo webList(@RequestBody @Valid OrderQueryParam orderQueryParam)
    {
        if(Objects.isNull(orderQueryParam) || CollUtil.isEmpty(orderQueryParam.getOrderTypeList())) {
            throw new ServiceException("订单类型不能为空");
        }
        orderQueryParam.setStartDateTime(orderQueryParam.getStartDate().atTime(0,0,0));
        orderQueryParam.setEndDateTime(orderQueryParam.getEndDate().atTime(23,59,59));
        startPage();
        List<OrderInfo> list = orderInfoService.selectOrderInfoList(orderQueryParam);
        return getDataTable(list);
    }

    @PostMapping("/device/list")
    @ResponseBody
    public TableDataInfo deviceList(@RequestBody @Valid OrderQueryParam orderQueryParam)
    {
        startPage();
        List<OrderInfo> list = orderInfoService.selectOrderInfoList(orderQueryParam);
        return getDataTable(list);
    }

    /**
     * 查询订单
     */
    @PostMapping("/{orderId}")
    @ResponseBody
    public AjaxResult get(@PathVariable("orderId") Long orderId)
    {
        if(Objects.isNull(orderId)) {
            throw new ServiceException("订单ID不能为空");
        }
        OrderInfo orderInfo = orderInfoService.selectOrderInfoByOrderId(orderId);
        return AjaxResult.success(orderInfo);
    }

    @PostMapping("/device/{deviceOrderId}")
    @ResponseBody
    public AjaxResult deviceGet(@PathVariable("deviceOrderId") String deviceOrderId)
    {
        if(Objects.isNull(deviceOrderId)) {
            throw new ServiceException("订单ID不能为空");
        }
        OrderInfo orderInfo = orderInfoService.selectOrderInfoBydeviceOrderId(deviceOrderId);
        return AjaxResult.success(orderInfo);
    }

    /**
     * 导出订单列表
     */
    @SysLog(title = "订单", module = "订单", businessType = OperaType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public void export(@RequestBody @Valid OrderQueryParam orderQueryParam, HttpServletResponse response)
    {
        List<OrderInfo> list = orderInfoService.selectOrderInfoList(orderQueryParam);
        ExcelUtil<OrderInfo> util = new ExcelUtil<OrderInfo>(OrderInfo.class);
        util.exportExcel(response, list, "订单数据");
    }

    /**
     * 新增保存订单
     */
    @SysLog(title = "下单",  module = "订单", businessType = OperaType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(@RequestBody @Valid OrderAddParam orderAddParam)
    {
        try {
            orderInfoService.insertCanteenOrderInfo(orderAddParam);
        }catch (ServiceException ex) {
            logger.error("h5下单异常: {}", ex.getMessage(), ex);
            if(Integer.valueOf(500001).equals(ex.getCode())) {
                return AjaxResult.success(ex.getMessage());
            }else {
                return AjaxResult.error(ex.getMessage());
            }
        }catch (Exception ex) {
            logger.error("h5下单失败: {}", ex.getMessage(), ex);
            return AjaxResult.error("下单失败");
        }
        return AjaxResult.success();
    }

    @SysLog(title = "下单",  module = "订单", businessType = OperaType.INSERT)
    @PostMapping("/device/add")
    @ResponseBody
    public AjaxResult deviceAddSave(@RequestBody @Valid DeviceOrderAddParam orderAddParam)
    {
        return toAjax(orderInfoService.insertDeviceOrderInfo(orderAddParam));
    }

    @SysLog(title = "下单",  module = "订单", businessType = OperaType.INSERT)
    @PostMapping("/shop/add")
    @ResponseBody
    public AjaxResult shopAddSave(@RequestBody @Valid ShopOrderAddParam orderAddParam)
    {
        return toAjax(orderInfoService.insertShopOrderInfo(orderAddParam));
    }

    @SysLog(title = "退单",  module = "订单", businessType = OperaType.UPDATE)
    @PostMapping("/refund/{orderId}")
    @ResponseBody
    public AjaxResult refund(@PathVariable("orderId") Long orderId)
    {
        orderInfoService.refund(orderId, StringUtils.EMPTY);
        return AjaxResult.success();
    }

    @SysLog(title = "退单",  module = "订单", businessType = OperaType.UPDATE)
    @PostMapping("/device/refund")
    @ResponseBody
    public AjaxResult deviceRefund(@RequestBody @Valid DeviceRefundParam param)
    {
        OrderInfo orderInfo = orderInfoService.selectOrderInfoBydeviceOrderId(param.getDeviceOrderId());
        orderInfoService.refund(orderInfo.getOrderId(), param.getOperationUser());
        return AjaxResult.success();
    }

    @SysLog(title = "付款",  module = "订单", businessType = OperaType.INSERT)
    @PostMapping("/pay/{orderId}")
    @ResponseBody
    public AjaxResult pay(@PathVariable Long orderId)
    {
        orderInfoService.pay(orderId);
        return AjaxResult.success();
    }
    @SysLog(title = "付款",  module = "订单", businessType = OperaType.INSERT)
    @PostMapping("/device/pay/{deviceOrderId}")
    @ResponseBody
    public AjaxResult devicePay(@PathVariable("deviceOrderId") String deviceOrderId)
    {
        if(Objects.isNull(deviceOrderId)) {
            throw new ServiceException("订单ID不能为空");
        }
        OrderInfo orderInfo = orderInfoService.selectOrderInfoBydeviceOrderId(deviceOrderId);
        orderInfoService.pay(orderInfo.getOrderId());
        return AjaxResult.success();
    }
    /**
     * 修改订单
     */
    @GetMapping("/edit/{orderId}")
    public OrderInfo edit(@PathVariable("orderId") @NotNull Long orderId, ModelMap mmap)
    {
        OrderInfo orderInfo = orderInfoService.selectOrderInfoByOrderId(orderId);
        mmap.put("orderInfo", orderInfo);
        return orderInfo;
    }

    /**
     * 修改保存订单
     */
    @SysLog(title = "订单",  module = "订单", businessType = OperaType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(OrderInfo orderInfo)
    {
        return toAjax(orderInfoService.updateOrderInfo(orderInfo));
    }

    /**
     * 删除订单
     */
    @SysLog(title = "订单",  module = "订单", businessType = OperaType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(@RequestBody List<Long> ids)
    {
        return toAjax(orderInfoService.deleteOrderInfoByOrderIds(ids));
    }

    @SysLog(title = "核销",  module = "订单", businessType = OperaType.UPDATE)
    @PostMapping( "/write-off")
    @ResponseBody
    public AjaxResult writeOff(@RequestBody @Valid OrderWriteOffParam param)
    {
        if(Objects.isNull(param) || CollUtil.isEmpty(param.getOrderIdList())) {
            throw new ServiceException("订单ID不能为空");
        }
        orderInfoService.writeOffOrderByOrderIds(param);
        return AjaxResult.success();
    }
}
