package com.gxwebsoft.apps.controller;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gxwebsoft.apps.entity.BcPlan;
import com.gxwebsoft.apps.param.BcPlanParam;
import com.gxwebsoft.apps.service.BcPlanService;
import com.gxwebsoft.common.core.utils.JSONUtil;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.common.system.service.OrganizationService;
import com.gxwebsoft.common.system.service.UserService;
import com.gxwebsoft.shop.entity.Goods;
import com.gxwebsoft.shop.entity.Order;
import com.gxwebsoft.shop.entity.OrderGoods;
import com.gxwebsoft.shop.param.OrderGoodsParam;
import com.gxwebsoft.shop.service.GoodsService;
import com.gxwebsoft.shop.service.OrderGoodsService;
import com.gxwebsoft.shop.service.OrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

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

/**
 * 报餐统计控制器
 *
 * @author 科技小王子
 * @since 2023-04-27 17:59:40
 */
@Api(tags = "报餐统计管理")
@RestController
@RequestMapping("/api/apps/bc-statistics")
public class BcStatisticsController extends BaseController {
  @Resource
  private GoodsService goodsService;
  @Resource
  private OrderService orderService;
  @Resource
  private OrderGoodsService orderGoodsService;
  @Resource
  private BcPlanService bcPlanService;
  @Resource
  private UserService userService;
  @Resource
  private OrganizationService organizationService;


  @ApiOperation("预定菜品统计")
  @GetMapping("/baoCanFoodCount")
  public ApiResult<?> baoCanFoodCount(BcPlanParam param) {
    // 验证签名
    isCheckSign();

    BcPlan plan = param.getOne(bcPlanService.listRel(param));
    System.out.println("1查询菜品列表param = " + plan);
    if (plan == null) {
      return fail("当日未发布菜品");
    }
    // json转数组 如：[0,1]转为ArrayList
    ArrayList goodsIds = JSONUtil.parseObject(plan.getGoodsIds(), ArrayList.class);
    final List<Goods> list = goodsService.listByIds(goodsIds);
    final ArrayList<Goods> goods = new ArrayList<>();

    // 查询今日有效订单
    final List<Order> orders = orderService.list(new LambdaQueryWrapper<Order>()
      .eq(Order::getDeliveryTime, param.getDayTime())
      .eq(Order::getPayStatus, PAY_STATUS_SUCCESS)
      .ne(Order::getOrderStatus, ORDER_STATUS_CANCEL)
    );
    final List<Integer> orderIds = orders.stream().map(Order::getOrderId).collect(Collectors.toList());

    // 整理餐段菜品数据
    list.forEach(d -> {
      if (d.getCategoryId().equals(param.getCategoryId())) {
        final int DeliveryTimes = orderGoodsService.count(new LambdaQueryWrapper<OrderGoods>()
          .in(OrderGoods::getOrderId, orderIds)
          .eq(OrderGoods::getCategoryId, param.getCategoryId())
          .eq(OrderGoods::getGoodsId, d.getGoodsId())
          .gt(OrderGoods::getTotalNum, 0)
        );
        final int NoDeliveryTimes = orderGoodsService.count(new LambdaQueryWrapper<OrderGoods>()
          .in(OrderGoods::getOrderId, orderIds)
          .eq(OrderGoods::getCategoryId, param.getCategoryId())
          .eq(OrderGoods::getGoodsId, d.getGoodsId())
          .gt(OrderGoods::getTotalNum, 0)
          .eq(OrderGoods::getDeliveryStatus, 10)
        );

        d.setDeliveryTimes(DeliveryTimes);
        d.setNoDeliveryTimes(NoDeliveryTimes);
        goods.add(d);
      }
    });
    return success("查询成功", goods);
  }

  @ApiOperation("预定人员统计")
  @GetMapping("/baoCanUserCount")
  public ApiResult<?> baoCanUserCount(BcPlanParam param) {
    // 验证签名
    isCheckSign();
    // 查询今日有效订单
    final List<Order> list = orderService.list(new LambdaQueryWrapper<Order>()
      .eq(Order::getDeliveryTime, param.getDayTime())
      .eq(Order::getPayStatus, PAY_STATUS_SUCCESS)
      .ne(Order::getOrderStatus, ORDER_STATUS_CANCEL)
    );
    final List<Integer> orderIds = list.stream().map(Order::getOrderId).collect(Collectors.toList());
//    System.out.println("list.size() = " + list.size());
    final List<OrderGoods> list25 = orderGoodsService.list(new LambdaQueryWrapper<OrderGoods>()
      .in(OrderGoods::getOrderId, orderIds)
      .eq(OrderGoods::getCategoryId, param.getCategoryId())
      .gt(OrderGoods::getTotalNum, 0)
      .eq(OrderGoods::getDeleted, 0)
    );
    final List<Integer> userIds25 = list25.stream().map(OrderGoods::getUserId).collect(Collectors.toList());
    final List<User> users25 = userService.listByIds(userIds25);
    return success("查询成功", users25);
  }

  @ApiOperation("报餐统计")
  @GetMapping("/baoCanUsers")
  public ApiResult<?> baoCanUsers(OrderGoodsParam param) {
    // 验证签名
    isCheckSign();
    System.out.println("param = " + param);
    // 修复订单商品的支付状态
//      repairPayPriceStatus();

    final HashMap<Object, Object> map = new HashMap<>();

    LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
    // 默认查询条件
    wrapper.ge(Order::getPayStatus,PAY_STATUS_SUCCESS)
      .ne(Order::getOrderStatus, ORDER_STATUS_CANCEL);

    // 按部门查询
    if(param.getOrganizationId() != null){
      System.out.println("按部门查询 = ");
      final List<User> users = userService.list(new LambdaQueryWrapper<User>().eq(User::getOrganizationId,param.getOrganizationId()));
      final List<Integer> collect = users.stream().map(User::getUserId).collect(Collectors.toList());
      System.out.println("userIds = " + collect);
      wrapper.in(Order::getUserId,collect);
    }

    // 是否选择日期
    if(param.getDeliveryTime() == null && param.getDeliveryTimeStart() == null && param.getCategoryId() != 0){
      return success("请选择预定日期",map);
    }
    // 按时间范围查询
    if(param.getDeliveryTimeStart() != null){
      // 最大只能选择一个月
      SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      try {
        Date date1 = df.parse(param.getDeliveryTimeStart());
        Date date2 = df.parse(param.getDeliveryTimeEnd());
        final boolean after = date1.after(date2);
        final long between = DateUtil.between(date1, date2, DateUnit.DAY);
        if(between > 30L){
          return fail("超出日期查询范围");
        }
        System.out.println("between = " + between);
        System.out.println("after = " + after);
      } catch (ParseException e) {
        e.printStackTrace();
      }
      wrapper.ge(Order::getDeliveryTime,param.getDeliveryTimeStart());
      wrapper.le(Order::getDeliveryTime,param.getDeliveryTimeEnd());
    }
    // 按预定日期查询
    if(param.getDeliveryTime() != null){
      wrapper.eq(Order::getDeliveryTime,param.getDeliveryTime());
    }

    final List<Order> list = orderService.list(wrapper);

    if(list.size() == 0){
      return success("查询成功",null);
    }

    System.out.println("报餐统计 = " + list.size());
    final List<Integer> orderIds = list.stream().map(Order::getOrderId).collect(Collectors.toList());
    System.out.println("orderIds = " + orderIds.size());

    LambdaQueryWrapper<OrderGoods> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(OrderGoods::getDeleted,0)
      .gt(OrderGoods::getTotalNum,0)
      .in(OrderGoods::getOrderId,orderIds);

    if(param.getCategoryId() != null){
      queryWrapper.eq(OrderGoods::getCategoryId,param.getCategoryId());
    }
    if(param.getGear() != null){
      queryWrapper.eq(OrderGoods::getGear,param.getGear());
    }
    // 已报餐
    final int post = orderGoodsService.count(queryWrapper);

    // 已签到
    queryWrapper.eq(OrderGoods::getDeliveryStatus,DELIVERY_STATUS_YES);
    final int sign = orderGoodsService.count(queryWrapper);

    // 未签到
    int noSign = post - sign;

    map.put("post",post);
    map.put("sign",sign);
    map.put("noSign", noSign);
    return success(map);


//
////       查询今日签到记录
//    final int sign25 = orderGoodsService.count(new LambdaQueryWrapper<OrderGoods>()
//      .in(OrderGoods::getOrderId, orderIds)
//      .eq(OrderGoods::getCategoryId, 25)
//      .eq(OrderGoods::getDeliveryStatus, 20)
//      .gt(OrderGoods::getTotalNum, 0)
//      .eq(OrderGoods::getDeleted, 0)
//    );
//    final int sign26 = orderGoodsService.count(new LambdaQueryWrapper<OrderGoods>()
//      .in(OrderGoods::getOrderId, orderIds)
//      .eq(OrderGoods::getCategoryId, 26)
//      .eq(OrderGoods::getDeliveryStatus, 20)
//      .gt(OrderGoods::getTotalNum, 0)
//      .eq(OrderGoods::getDeleted, 0)
//    );
//    final int sign27 = orderGoodsService.count(new LambdaQueryWrapper<OrderGoods>()
//      .in(OrderGoods::getOrderId, orderIds)
//      .eq(OrderGoods::getCategoryId, 27)
//      .eq(OrderGoods::getDeliveryStatus, 20)
//      .gt(OrderGoods::getTotalNum, 0)
//      .eq(OrderGoods::getDeleted, 0)
//    );
////      // 查询今日报餐人数
//    final int post25 = orderGoodsService.count(new LambdaQueryWrapper<OrderGoods>()
//      .in(OrderGoods::getOrderId, orderIds)
//      .eq(OrderGoods::getCategoryId, 25)
//      .gt(OrderGoods::getTotalNum, 0)
//      .eq(OrderGoods::getDeleted, 0)
//    );
//    final int post26 = orderGoodsService.count(new LambdaQueryWrapper<OrderGoods>()
//      .in(OrderGoods::getOrderId, orderIds)
//      .eq(OrderGoods::getCategoryId, 26)
//      .gt(OrderGoods::getTotalNum, 0)
//      .eq(OrderGoods::getDeleted, 0)
//    );
//    final int post27 = orderGoodsService.count(new LambdaQueryWrapper<OrderGoods>()
//      .in(OrderGoods::getOrderId, orderIds)
//      .eq(OrderGoods::getCategoryId, 27)
//      .gt(OrderGoods::getTotalNum, 0)
//      .eq(OrderGoods::getDeleted, 0)
//    );
////
//    map.put("breakfastSignUsers", sign25);
//    map.put("lunchSignUsers", sign26);
//    map.put("dinnerSignUsers", sign27);
//
//    map.put("breakfastPostUsers", post25);
//    map.put("lunchPostUsers", post26);
//    map.put("dinnerPostUsers", post27);


  }

  @ApiOperation("导出报表")
  @GetMapping("/export")
  public ApiResult<?> export(OrderGoodsParam param) {
    return success("导出报表");
  }

  private void repairPayPriceStatus() {
    final OrderGoodsParam param = new OrderGoodsParam();
    param.setUserId(0);
    final List<OrderGoods> list = orderGoodsService.listRel(param);
    System.out.println("修复支付状态 = " + list.size());
    list.forEach(d -> {
      final Order order = orderService.getById(d.getOrderId());
      if (order != null) {
        System.out.println("order = " + order);
        d.setPayStatus(PAY_STATUS_SUCCESS);
        d.setUserId(order.getUserId());
        orderGoodsService.updateById(d);
      } else {
        orderGoodsService.removeById(d);
      }
    });
  }

  private void updateTimeByOrderGoods() {
    System.out.println("修复数据 = ");
//      final Order order = orderService.getById(2467);
    final LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
//      wrapper.eq(Order::getTenantId,10048);
//      wrapper.eq(Order::getDeleted,0);
//      wrapper.eq(Order::getOrderStatus,10);
//      wrapper.eq(Order::getDeliveryStatus,10);
    wrapper.in(Order::getOrderId, 3184);
//      wrapper.eq(Order::getPayStatus,20);
//      wrapper.gt(Order::getOrderId,1000);
//      wrapper.lt(Order::getOrderId,2000);
    final List<Order> list = orderService.list(wrapper);
    System.out.println("修复数据list = " + list.size());
    list.forEach(order -> {
      final OrderGoodsParam orderGoodsParam = new OrderGoodsParam();
      orderGoodsParam.setOrderId(order.getOrderId());
      final List<OrderGoods> goods = orderGoodsService.listRel(orderGoodsParam);
      goods.forEach(d -> {
        d.setDeliveryTime(order.getDeliveryTime());
        d.setPayStatus(order.getPayStatus());
        orderGoodsService.updateById(d);
        System.out.println("修复预定时间 = " + d.getOrderId());
      });
    });
  }
}
