package com.gxwebsoft.apps.controller;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.apps.entity.HualalaFood;
import com.gxwebsoft.apps.entity.HualalaFoodCategory;
import com.gxwebsoft.apps.entity.HualalaShop;
import com.gxwebsoft.apps.entity.ItemVo;
import com.gxwebsoft.apps.param.*;
import com.gxwebsoft.apps.result.AllShopResult;
import com.gxwebsoft.apps.result.FoodCategoryResult;
import com.gxwebsoft.apps.result.OpenFoodResult;
import com.gxwebsoft.apps.result.ShopBaseInfoResult;
import com.gxwebsoft.apps.service.HualalaFoodCategoryService;
import com.gxwebsoft.apps.service.HualalaFoodService;
import com.gxwebsoft.apps.service.HualalaService;
import com.gxwebsoft.apps.service.HualalaShopService;
import com.gxwebsoft.common.core.utils.CacheClient;
import com.gxwebsoft.common.core.utils.CommonUtil;
import com.gxwebsoft.common.core.utils.JSONUtil;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.shop.entity.Merchant;
import com.gxwebsoft.shop.entity.Order;
import com.gxwebsoft.shop.entity.OrderGoods;
import com.gxwebsoft.shop.mapper.OrderGoodsMapper;
import com.gxwebsoft.shop.param.MerchantParam;
import com.gxwebsoft.shop.param.OrderParam;
import com.gxwebsoft.shop.service.OrderGoodsService;
import com.gxwebsoft.shop.service.OrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.val;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

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

/**
 * 哗啦啦接口
 * 桂小厨GO
 * AppID:wx445232847c503f1b
 * AppSecret:eb81fbcac21da949d819143b43d18636
 * 桂小厨+
 * AppID:wx445232847c503f1b
 * AppSecret:eb81fbcac21da949d819143b43d18636
 * @author 科技小王子
 * @since 2022-11-25 12:55:33
 */
@Api(tags = "哗啦啦接口")
@RestController
@RequestMapping("/api/apps/hualala")
public class HualalaController extends BaseController {
  @Resource
  private HualalaService hualalaService;
  @Resource
  private HualalaShopService hualalaShopService;
  @Resource
  private StringRedisTemplate stringRedisTemplate;
  @Resource
  private CacheClient cacheClient;
  @Resource
  private HualalaFoodService hualalaFoodService;
  @Resource
  private HualalaFoodCategoryService hualalaFoodCategoryService;
  @Resource
  private OrderService orderService;
  @Resource
  private OrderGoodsService orderGoodsService;
  @Resource
  private OrderGoodsMapper orderGoodsMapper;

  @ApiOperation("哗啦啦万能接口")
  @PostMapping()
  public ApiResult<?> post(@RequestBody HualalaParam hualalaParam) {
    // 接口
    String apiUrl = hualalaParam.getApiUrl();
    // 请求参数
    HashMap<String, Object> params = hualalaParam.getParams();
    // 执行请求
    JSONObject response = hualalaService.doPost(apiUrl, params);
    return success("请求成功",response);
  }

  @ApiOperation("查询集团店铺列表")
  @PostMapping("/getAllShop")
  public ApiResult<?> getAllShop(@RequestBody Map<String, Object> params) {
    // 请求缓存数据
    AllShopResult cache = cacheClient.get(getAllShop, AllShopResult.class);
    if(cache != null){
      return success("请求成功",cache.getShopInfoList());
    }

    // 执行请求解析data数据
    JSONObject response = hualalaService.doPost("/doc/getAllShop", params);
    AllShopResult result = JSONObject.parseObject(response.getString("data"), AllShopResult.class);
    cacheClient.set(getAllShop,result);

    List<HualalaShop> shopInfoList = result.getShopInfoList();
    // 过滤非桂小厨品牌门店
    List<HualalaShop> shops = shopInfoList.stream().filter(d -> d.getBrandName().equals("桂小厨")).collect(Collectors.toList());
    shops.forEach(d -> {
      d.setCreateTime(null);
      d.setTenantId(getTenantId());
      cacheClient.geoAdd(haulalaGeoKey,d.getMapLongitudeValueBaiDu(),d.getMapLatitudeValueBaiDu(),d.getShopId().toString());
    });
    hualalaShopService.saveBatch(shops);
    return success("缓存成功",shops);


//    try {
//      // 执行请求解析data数据
//      JSONObject response = hualalaService.doPost("/doc/getAllShop", params);
//      AllShopResult result = JSONObject.parseObject(response.getString("data"), AllShopResult.class);
//      cacheClient.set(getAllShop,result,1L,TimeUnit.DAYS);
//      return success("请求成功",result);
//    } catch (Exception e) {
//      throw new RuntimeException();
//    }
  }


  @ApiOperation("查询店铺信息")
  @PostMapping("/getBaseInfo")
  public ApiResult<?> getBaseInfo(@RequestBody Map<String, Object> params) {
    // 请求缓存数据
    String key = getBaseInfo.concat(":").concat(params.get("shopId").toString());
    Merchant merchant = cacheClient.get(key, Merchant.class);
    if(merchant != null){
      return success("请求成功",merchant);
    }
    try {
      // 执行请求解析data数据
      JSONObject response = hualalaService.doPost("/doc/getBaseInfo", params);
      ShopBaseInfoResult result = JSONObject.parseObject(response.getString("data"), ShopBaseInfoResult.class);
      cacheClient.set(key,result);
      return success("缓存成功",result);
    } catch (Exception e) {
      throw new RuntimeException();
    }
  }


  @ApiOperation("查询店铺菜品分类")
  @PostMapping("/getFoodClassCategory")
  public ApiResult<?> getFoodClassCategory(@RequestBody Map<String, Object> params) {
    // 只查询外卖菜品
    params.put("type",1);
    // 请求缓存数据
    String key = getFoodClassCategory.concat(":").concat(params.get("shopId").toString());
    FoodCategoryResult cache = cacheClient.get(key, FoodCategoryResult.class);
    if(cache != null){
      return success("请求成功",cache);
    }

    try {
      // 执行请求解析data数据
      JSONObject response = hualalaService.doPost("/doc/getFoodClassCategory", params);
      FoodCategoryResult result = JSONObject.parseObject(response.getString("data"), FoodCategoryResult.class);
      cacheClient.set(key,result);
      return success("缓存成功",result);
    } catch (Exception e) {
      throw new RuntimeException();
    }
  }

  @ApiOperation("查询店铺菜品列表")
  @PostMapping("/getOpenFood")
  public ApiResult<?> getOpenFood(@RequestBody Map<String, Object> params) {
    // 请求缓存数据
    String key = getOpenFood.concat(":").concat(params.get("shopId").toString());
    OpenFoodResult cache = cacheClient.get(key, OpenFoodResult.class);
    if(cache != null){
      // 计算加入购物车的商品数量
      List<HualalaFood> foodList = cache.getFoodList();
      foodList.forEach(d -> {
        String cartKey = HLL_CART_FOOD_KEY.concat(d.getShopId()).concat(":").concat(getLoginUserId().toString());
        ItemVo item = cacheClient.hGet(cartKey, d.getFoodId(), ItemVo.class);
        if(item != null){
          d.setCartNum(item.getNum());
        }
      });
//      List<HualalaFood> foods = CommonUtil.toTreeData(cache.getFoodList(), null, HualalaFood::getParentFoodId, HualalaFood::getFoodOnlineCategoryId, HualalaFood::setChildren);
      Map<String, List<HualalaFood>> collect = foodList.stream().collect(Collectors.groupingBy(HualalaFood::getFoodOnlineCategoryId));
      return success("请求成功",collect);
    }

    // 执行请求解析当前店铺的菜品数据
    JSONObject response = hualalaService.doPost("/doc/getOpenFood", params);
    OpenFoodResult result = JSONObject.parseObject(response.getString("data"), OpenFoodResult.class);
    // 筛选出外卖菜品
    List<HualalaFood> foodList = result.getFoodList();
    List<HualalaFood> foodList2 = foodList.stream().filter(d -> d.getTakeawayTag().equals("2")).collect(Collectors.toList());
    // 筛选出可以点单的菜品
    List<HualalaFood> foods = foodList2.stream().filter(d -> d.getIsSingleSale().equals(1)).collect(Collectors.toList());
    // 存入redis
    result.setFoodList(foods);
    result.setCount(foods.size());
    cacheClient.set(key,result);
    hualalaFoodService.saveBatch(foods);
    return success("缓存成功",result.getFoodList());
  }

//  @ApiOperation("查询店铺菜品列表(备份)")
//  @PostMapping("/getOpenFood2")
//  public ApiResult<?> getOpenFood2(@RequestBody Map<String, Object> params) {
//    // 请求缓存数据
//    String key = getOpenFood.concat(":").concat(params.get("shopId").toString());
//    OpenFoodResult cache = cacheClient.get(key, OpenFoodResult.class);
//    if(cache != null){
//      // 计算加入购物车的商品数量
//      List<HualalaFood> foodList = cache.getFoodList();
//      foodList.forEach(d -> {
//        String cartKey = HLL_CART_FOOD_KEY.concat(d.getShopId()).concat(":").concat(getLoginUserId().toString());
//        ItemVo item = cacheClient.hGet(cartKey, d.getFoodId(), ItemVo.class);
//        if(item != null){
//          d.setCartNum(item.getNum());
//        }
//      });
//      return success("请求成功",foodList);
//    }
//    try {
//      // 执行请求解析当前店铺的菜品数据
//      JSONObject response = hualalaService.doPost("/doc/getOpenFood", params);
//      OpenFoodResult result = JSONObject.parseObject(response.getString("data"), OpenFoodResult.class);
//      // 筛选出外卖菜品
//      List<HualalaFood> foodList = result.getFoodList();
//      List<HualalaFood> foodList2 = foodList.stream().filter(d -> d.getTakeawayTag().equals("2")).collect(Collectors.toList());
//      // 筛选出可以点单的菜品
//      List<HualalaFood> foods = foodList2.stream().filter(d -> d.getIsSingleSale().equals(1)).collect(Collectors.toList());
//      // 存入redis
//      result.setFoodList(foods);
//      result.setCount(foods.size());
//      cacheClient.set(key,result);
//      return success("缓存成功",result.getFoodList());
//    } catch (Exception e) {
//      throw new RuntimeException();
//    }
//  }

  @PreAuthorize("hasAuthority('apps:hualala:list')")
  @ApiOperation("保存菜品到redis（已废弃）")
  @PostMapping("/setOpenFoodToRedis")
  public ApiResult<?> setOpenFoodToRedis(@RequestBody HualalaFoodParam food) {
    System.out.println("food = " + food);
    String key = "cache:getOpenFood:shop-"+food.getShopId()+":category-"+food.getFoodCategoryCode()+":"+food.getFoodId();
//    stringRedisTemplate.opsForHash().put(key,food.getFoodId(),food.getData().toString());
    return success("请求成功",food);
    // 请求缓存数据
//    String key = getOpenFood + params.get("shopId");
//    String jsonStr = stringRedisTemplate.opsForValue().get(key);
//    if(StrUtil.isNotBlank(jsonStr)){
//      return success("请求成功",JSON.parseObject(jsonStr));
//    }
//    try {
//      // 执行请求解析data数据
//      JSONObject response = hualalaService.doPost("/doc/getOpenFood", params);
//      stringRedisTemplate.opsForValue().set(key, response.getString("data"),1,TimeUnit.DAYS);
//      return success("请求成功",JSON.parseObject(response.getString("data")));
//    } catch (Exception e) {
//      throw new RuntimeException();
//    }
  }

  @ApiOperation("根据定位查询附近的门店列表")
  @PostMapping("/getListByGeo")
  public ApiResult<List<HualalaShop>> getListByGeo(@RequestBody HualalaShopParam param) {
    return success(hualalaShopService.listByGeo(param));
  }

  @PreAuthorize("hasAuthority('apps:hualala:list')")
  @ApiOperation("把商户坐标写入redis缓存")
  @PostMapping("/geoAdd")
  public ApiResult<?> geoAdd(){
    String key1 = "shop:geo:guixiaochu";
    stringRedisTemplate.opsForGeo().add(key1,new Point(108.321614,22.815124),"76230180");
    stringRedisTemplate.opsForGeo().add(key1,new Point(108.335703,22.813917),"76230181");
    stringRedisTemplate.opsForGeo().add(key1,new Point(108.370343,22.830116),"76230179");
    stringRedisTemplate.opsForGeo().add(key1,new Point(108.292017,22.869498),"76258872");
    stringRedisTemplate.opsForGeo().add(key1,new Point(108.393005,22.81194),"76230126");
    stringRedisTemplate.opsForGeo().add(key1,new Point(108.325202,22.785341),"76230178");
    return success("添加完毕");
  }

  @ApiOperation("推送订单")
  @PostMapping("/pushOrder")
  public ApiResult<?> pushOrder(@RequestBody OrderParam param){
    Integer orderId = param.getOrderId();
    Order orderInfo = orderService.getById(orderId);
    System.out.println("orderInfo = " + orderInfo);
    final List<OrderGoods> goodsInfo = orderGoodsMapper.selectByOrderId(orderId);
    System.out.println("goodsInfo = " + goodsInfo);
    // 菜品信息
    ArrayList<Object> orderItem = new ArrayList<>();
    goodsInfo.forEach(goods -> {
      JSONObject item = new JSONObject();
      item.put("foodID",goods.getGoodsId());      // 菜品id
      item.put("foodName",goods.getGoodsName());  // 菜品名称
      item.put("foodUnit","份");                      // 规格名称
      item.put("foodUnitID",goods.getGoodsSkuId());   // 菜品规格id
      item.put("isSetFood",0);                        // 是/否套餐，0：非套餐 1：套餐
      item.put("isBatching",0);                       // 0：正常菜，1：主菜，2：配菜，3：加价做法
      item.put("foodCount",goods.getTotalNum());         // 菜品数量
      item.put("originPrice",goods.getTotalPrice());  // 菜品原价
      item.put("takeoutPackagingFee","0");            // 打包费
      item.put("isDiscount",0);                       // 是/否打折 ，0：不是 1：是
      item.put("duePrice",goods.getTotalPrice());     // TODO 菜品成售价
      orderItem.add(item);
    });

    // 支付信息
    ArrayList<Object> payInfo = new ArrayList<>();
    JSONObject payItem = new JSONObject();
    payItem.put("paymentSubjectID",Long.valueOf("51010440"));   // 科目id
    payItem.put("paymentSubjectName","微信小程序实收");    // 科目名称
    payItem.put("dueAmount",orderInfo.getPayPrice());    // TODO 实收金额
    payItem.put("paymentStatus",20);      // 支付状态，15：未支付；20：已支付
    payItem.put("payWay",70);             // 支付方式，70：商家自定义科目
    payInfo.add(payItem);

    // 用户信息
    JSONObject userInfo = new JSONObject();
    userInfo.put("userName","邓莉莉");
    userInfo.put("userMobile","15878179339");
    userInfo.put("shopMpID","wxa4e2b8bc9c14c743");
    userInfo.put("userSex","0");           // 用户性别, 1:先生 0:女士 2:不显示，不传默认0 女士

    // 订单信息
    JSONObject order = new JSONObject();
    order.put("orderSubType",20);         // 订单类型 20: 外送
    order.put("orderStatus",20);          // 订单状态 20：已付款
    order.put("discountTotalAmount","0"); // TODO 优惠金额
    order.put("dinners",1);               // 用餐人数
    // 期望送达时间
    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddHHmm");
    order.put("orderTime",sdf1.format(orderInfo.getCreateTime()));
    order.put("orderItem",orderItem);     // 菜品信息
    order.put("takeoutAddress","南宁市良庆区五象大道401号五象航洋城1号楼1226室"); // TODO 外送地址
    order.put("deliveryAmount","8.00");      // TODO 配送费
    order.put("serviceAmount","0");       // 服务费，必传0
    order.put("channelKey","399_weixin"); // 渠道:微信小程序
    order.put("isAlreadyPaid","1");       // 是/否支付
    order.put("orderMode",1);             // 1：先付，2：后付
    order.put("OrderRemark","测试订单(不需要制作及发货)");          // TODO 订单备注
    order.put("payment",payInfo);         // 支付信息
    order.put("userInfo",userInfo);       // 用户信息

    HashMap<String,Object> params = new HashMap<>();
    params.put("shopID",Long.valueOf("76220517"));  // 店铺ID
    params.put("isCheackOut",0);          // 0 ：默认 不需要收银台数据 1： 需要收银台数据
    params.put("isThirdPay",2);           // 只有单纯核销哗啦啦会员卡时传1，其它都传2
    params.put("bankCode","weChat");      // 支付方式，weChat微信 aliPay支付宝，非哗啦啦支付传weChat
    params.put("order",order);            // 订单信息
    params.put("isSentMsg",1);            // 下单后pos是/否显示订单，下单带支付科目信息先付传1，下单不带支付科目信息先付传0，后付传1
    params.put("msgType",120);            // 消息类型，240： 堂食、闪吃，120：外送，121：自提 ，与order中orderSubType要对应
    params.put("thirdOrderID",orderInfo.getOrderNo());   // 三方订单号，作用：十分钟内对相同的thirdOrderID进行去重处理，仅开放平台使用做去重处理，不会传到pos及报表

    // 执行订单推送
//    JSONObject response = hualalaService.doPost("/order/submitordernew", params);
//    System.out .println("response = " + response);

    // 同步配送平台
//    JSONObject result = hualalaService.doExpress(orderInfo);

    return success("推送成功",null);
  }

}
