package com.gxwebsoft.shop.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gxwebsoft.apps.entity.BcAgent;
import com.gxwebsoft.apps.entity.EquipmentGoods;
import com.gxwebsoft.apps.entity.EquipmentOrderGoods;
import com.gxwebsoft.apps.param.BcAgentParam;
import com.gxwebsoft.apps.service.BcAgentService;
import com.gxwebsoft.apps.service.EquipmentGoodsService;
import com.gxwebsoft.apps.service.EquipmentOrderGoodsService;
import com.gxwebsoft.apps.service.EquipmentService;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.*;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.common.system.service.UserService;
import com.gxwebsoft.shop.entity.Order;
import com.gxwebsoft.shop.entity.UserReferee;
import com.gxwebsoft.shop.param.OrderGoodsParam;
import com.gxwebsoft.shop.param.OrderParam;
import com.gxwebsoft.shop.service.OrderGoodsService;
import com.gxwebsoft.shop.service.OrderService;
import com.gxwebsoft.shop.service.UserRefereeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.gxwebsoft.common.core.constants.OrderConstants.*;

/**
 * 订单记录表控制器
 *
 * @author WebSoft
 * @since 2022-11-16 11:25:58
 */
@Api(tags = "订单记录表管理")
@RestController
@RequestMapping("/api/shop/order")
public class OrderController extends BaseController {
    @Resource
    private OrderService orderService;
    @Resource
    private EquipmentGoodsService equipmentGoodsService;
    @Resource
    private EquipmentService equipmentService;
    @Resource
    private OrderGoodsService orderGoodsService;
    @Resource
    private EquipmentOrderGoodsService equipmentOrderGoodsService;
    @Resource
    private UserRefereeService userRefereeService;
    @Resource
    private UserService userService;
    @Resource
    private BcAgentService bcAgentService;

    @PreAuthorize("hasAuthority('shop:order:list')")
    @OperationLog
    @ApiOperation("分页查询订单记录表")
    @GetMapping("/page")
    public ApiResult<PageResult<Order>> page(OrderParam param) {
        // 搜索条件
        if (getMerchantCode() != null) {
          param.setMerchantCode(getMerchantCode());
        }
        // 云芯威项目查询关联设备
        if(getTenantId().equals(6)){
          // 查询订单的关联商品
          List<Order> list = orderService.listRel(param);
          // 查询订单的设备
          for (Order order : list) {
            final OrderGoodsParam orderGoodsParam = new OrderGoodsParam();
            orderGoodsParam.setOrderId(order.getOrderId());
            order.setGoodsList(orderGoodsService.listRel(orderGoodsParam));
            order.setEquipmentGoods(equipmentOrderGoodsService.getOne(new LambdaQueryWrapper<EquipmentOrderGoods>().eq(EquipmentOrderGoods::getOrderId,order.getOrderId())));
            order.setEquipment(equipmentService.getById(order.getEquipmentId()));
          }
          PageParam<Order, OrderParam> page = new PageParam<>(param);
          return success(new PageResult<>(list, page.getTotal()));
        }
        // 贵港自然资源报餐
        if(getTenantId().equals(10048) && getAppId() != null){
          final BcAgentParam bcAgentParam = new BcAgentParam();
          bcAgentParam.setParentId(getLoginUserId());
          bcAgentParam.setLimit(100L);
          final PageResult<BcAgent> result = bcAgentService.pageRel(bcAgentParam);
          final Set<Integer> collect = result.getList().stream().map(BcAgent::getUserId).collect(Collectors.toSet());
          collect.add(getLoginUserId());
          param.setUserId(null);
          param.setUserIds(collect);
          return success(orderService.pageRel(param));
        }

        // 使用关联查询
        return success(orderService.pageRel(param));
    }

    @PreAuthorize("hasAuthority('shop:order:list')")
    @OperationLog
    @ApiOperation("查询全部订单记录表")
    @GetMapping()
    public ApiResult<List<Order>> list(OrderParam param) {
        // 使用关联查询
      return success(orderService.listRel(param));
    }

    @PreAuthorize("hasAuthority('shop:order:list')")
    @OperationLog
    @ApiOperation("按订单集查询")
    @PostMapping("/listByIds")
    public ApiResult<List<Order>> listByIds(@RequestBody List<Integer> orderIds) {
      System.out.println("按订单集查询 = " + orderIds);
      Integer userId = getLoginUserId();
      // 代报餐情况(未完成)
      final Order order = orderService.getById(orderIds.get(0));
      if (!order.getUserId().equals(getLoginUserId())) {
        userId = order.getUserId();
        final List<Order> list1 = orderService.list(new LambdaQueryWrapper<Order>().in(Order::getOrderId,orderIds).eq(Order::getUserId, userId).eq(Order::getPayStatus,PAY_STATUS_NO_PAY));
        final Set<Integer> collect = list1.stream().map(Order::getOrderId).collect(Collectors.toSet());
        return success(orderService.listByIds(collect));
      }

      final List<Order> list1 = orderService.list(new LambdaQueryWrapper<Order>().eq(Order::getUserId, getLoginUserId()).eq(Order::getPayStatus,PAY_STATUS_NO_PAY));
      final List<Integer> collect = list1.stream().map(Order::getOrderId).collect(Collectors.toList());
      // 使用关联查询
      return success(orderService.listByIds(collect));
    }

    @PreAuthorize("hasAuthority('shop:order:list')")
    @OperationLog
    @ApiOperation("根据id查询订单记录表")
    @GetMapping("/{id}")
    public ApiResult<Order> get(@PathVariable("id") Integer id) {
      // 使用关联查询
      Order order = orderService.getByIdRel(id);
      // 云芯威关联设备查询
      if (!order.getGoodsId().equals(0) || !order.getEquipmentId().equals(0)) {
        order.setEquipmentGoods(equipmentOrderGoodsService.getOne(new LambdaQueryWrapper<EquipmentOrderGoods>().eq(EquipmentOrderGoods::getOrderId,order.getOrderId())));
        order.setEquipment(equipmentService.getById(order.getEquipmentId()));
      }
      return success(order);
    }

    @PreAuthorize("hasAuthority('shop:order:save')")
    @OperationLog
    @ApiOperation("添加订单记录表")
    @PostMapping()
    public ApiResult<?> save(@RequestBody Order order) {
        // 记录当前登录用户id、租户id
        User loginUser = getLoginUser();
        if (loginUser != null) {
          order.setUserId(loginUser.getUserId());
        }
        if (orderService.save(order)) {
          // 云芯威BMS
          if (order.getTenantId().equals(6)) {
            final EquipmentGoods eg = equipmentGoodsService.getById(order.getOrderSourceId());
            eg.setOrderId(order.getOrderId());
            // 添加订单商品
            final EquipmentOrderGoods oeg = new EquipmentOrderGoods();
            oeg.setOrderId(order.getOrderId());
            oeg.setGoodsName(eg.getGoodsName());
            oeg.setEquipmentCategory(eg.getEquipmentCategory());
            oeg.setImage(eg.getImage());
            oeg.setCategoryId(eg.getCategoryId());
            oeg.setBatteryModel(eg.getBatteryModel());
            oeg.setSellingPoint(eg.getSellingPoint());
            oeg.setStockTotal(eg.getStockTotal());
            oeg.setContent(eg.getContent());
            oeg.setBatteryPrice(eg.getBatteryPrice());
            oeg.setBatteryRent(eg.getBatteryRent());
            oeg.setBatteryInsurance(eg.getBatteryInsurance());
            oeg.setBatteryDeposit(eg.getBatteryDeposit());
            oeg.setDownPayment(eg.getDownPayment());
            oeg.setPeriods(eg.getPeriods());
            oeg.setRepayment(eg.getRepayment());
            oeg.setServiceCharges(eg.getServiceCharges());
            oeg.setPeriodsType(eg.getPeriodsType());
            oeg.setUserId(eg.getUserId());
            oeg.setComments(eg.getComments());
            oeg.setStatus(eg.getStatus());
            oeg.setMerchantCode(eg.getMerchantCode());
            oeg.setTenantId(eg.getTenantId());

            equipmentOrderGoodsService.saveOrUpdate(oeg);

            // 添加推荐人关系
            if (order.getDealerId() != null) {
              final User dealer = userService.getById(order.getDealerId());
              if(dealer == null){
                return fail("推荐人的用户ID不存在");
              }
              final UserReferee referee = new UserReferee();
              referee.setDealerId(order.getDealerId());
              referee.setUserId(getLoginUserId());
              userRefereeService.save(referee);
            }
          }
          // 是否存入星期值
          if(order.getDeliveryTime() != null){
            order.setWeek(DateUtil.dayOfWeek(order.getDeliveryTime()) - 1);
          }
          return success("添加成功",order);
        }
        return fail("添加失败");
    }

    @PreAuthorize("hasAuthority('shop:order:update')")
    @OperationLog
    @ApiOperation("修改订单记录表")
    @PutMapping()
    public ApiResult<?> update(@RequestBody Order order) {
        if (orderService.updateById(order)) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('shop:order:remove')")
    @OperationLog
    @ApiOperation("删除订单记录表")
    @DeleteMapping("/{id}")
    public ApiResult<?> remove(@PathVariable("id") Integer id) {
        if (orderService.removeById(id)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

    @PreAuthorize("hasAuthority('shop:order:save')")
    @OperationLog
    @ApiOperation("批量添加订单记录表")
    @PostMapping("/batch")
    public ApiResult<?> saveBatch(@RequestBody List<Order> list) {
        if (orderService.saveBatch(list)) {
            return success("添加成功");
        }
        return fail("添加失败");
    }

    @PreAuthorize("hasAuthority('shop:order:update')")
    @OperationLog
    @ApiOperation("批量修改订单记录表")
    @PutMapping("/batch")
    public ApiResult<?> removeBatch(@RequestBody BatchParam<Order> batchParam) {
        if (batchParam.update(orderService, "order_id")) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('shop:order:remove')")
    @OperationLog
    @ApiOperation("批量删除订单记录表")
    @DeleteMapping("/batch")
    public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
        if (orderService.removeByIds(ids)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

    @ApiOperation("支付成功")
    @PostMapping("/setPayStatus")
    public ApiResult<?> setPayStatus(@RequestBody Order order){
      if (orderService.updateById(order)) {
        return success("设置成功");
      }
      return fail("设置失败");
    }

    @PreAuthorize("hasAuthority('shop:order:list')")
    @OperationLog
    @ApiOperation("生成核销付款码（二维码）")
    @GetMapping("/generateQrCode")
    public ApiResult<?> generateQrCode(OrderParam param) throws IOException {
      // 查询当天的报餐信息
      param.setUserId(getLoginUserId());
      param.setDeliveryTime(DateUtil.beginOfDay(DateUtil.date()).toString());
      param.setOrderStatus(ORDER_STATUS_DOING);
      param.setPayStatus(PAY_STATUS_SUCCESS);
      param.setDeleted(0);
      final List<Order> list = orderService.listRel(param);
      if(list.size() == 0){
        return fail("今日无报餐记录");
      }
      final Order order = list.get(0);
      // LOGO URL地址
      String logoUrl = "https://file.wsdns.cn/20230430/6fa31aca3b0d47af98a149cf2dd26a4f.jpeg";
      // 二维码生成图片保存路径
      String filePath = "/www/wwwroot/file.ws/file/qrcode/" + getLoginUserId() + "/payQrCode.jpg";
      // 二维码访问路径
      String qrcodeUrl = "https://file.gxwebsoft.com/qrcode/" + getLoginUserId() + "/payQrCode.jpg" + "?v=" + DateUtil.current();
      // 二维码内容
      final String orderNo = order.getOrderNo().toString();
      // 将URL转为BufferedImage
      BufferedImage bufferedImage = ImageIO.read(new URL(logoUrl));
      // 生成二维码
      QrConfig config = new QrConfig(300, 300);
      // 设置边距，既二维码和背景之间的边距
      config.setMargin(1);
      // 附带小logo
      config.setImg(bufferedImage);
      QrCodeUtil.generate(orderNo, config, FileUtil.file(filePath));
      return success("请求成功",qrcodeUrl);
    }
}
