package com.gxwebsoft.cms.controller;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.gxwebsoft.cms.entity.*;
import com.gxwebsoft.cms.param.MpParam;
import com.gxwebsoft.cms.service.*;
import com.gxwebsoft.common.core.utils.JSONUtil;
import com.gxwebsoft.common.core.utils.RedisUtil;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.KVEntity;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.shop.entity.Goods;
import com.gxwebsoft.shop.param.GoodsParam;
import com.gxwebsoft.shop.service.GoodsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 小程序控制器
 *
 * @author 科技小王子
 * @since 2024-07-21 23:03:05
 */
@Api(tags = "小程序")
@RestController
@RequestMapping("/api/cms/mp")
public class MpController extends BaseController {
  @Resource
  private MpService mpService;
  @Resource
  private MpPagesService mpPagesService;
  @Resource
  private AdService adService;
  @Resource
  private MpMenuService mpMenuService;
  @Resource
  private MpFieldService mpFieldService;
  @Resource
  private GoodsService goodsService;
  @Resource
  private RedisUtil redisUtil;

  @ApiOperation("分页查询小程序")
  @GetMapping("/page")
  public ApiResult<PageResult<Mp>> page(MpParam param) {
    // 使用关联查询
    return success(mpService.pageRel(param));
  }

  @ApiOperation("查询全部小程序")
  @GetMapping()
  public ApiResult<List<Mp>> list(MpParam param) {
    // 使用关联查询
    return success(mpService.listRel(param));
  }

  @PreAuthorize("hasAuthority('cms:mp:list')")
  @ApiOperation("根据id查询小程序")
  @GetMapping("/{id}")
  public ApiResult<Mp> get(@PathVariable("id") Integer id) {
    // 使用关联查询
    return success(mpService.getByIdRel(id));
  }

  @PreAuthorize("hasAuthority('cms:mp:save')")
  @ApiOperation("添加小程序")
  @PostMapping()
  public ApiResult<?> save(@RequestBody Mp mp) {
    // 记录当前登录用户id
    User loginUser = getLoginUser();
    if (loginUser != null) {
      mp.setUserId(loginUser.getUserId());
    }
    if (mpService.save(mp)) {
      return success("添加成功");
    }
    return fail("添加失败");
  }

  @PreAuthorize("hasAuthority('cms:mp:update')")
  @ApiOperation("修改小程序")
  @PutMapping()
  public ApiResult<?> update(@RequestBody Mp mp) {
    // 只允许一个主账号
    if (mp.getType().equals(1)) {
      mpService.update(new LambdaUpdateWrapper<Mp>().eq(Mp::getType, 1).set(Mp::getType, 0));
    }
    if (mpService.updateById(mp)) {
      return success("修改成功");
    }
    return fail("修改失败");
  }

  @PreAuthorize("hasAuthority('cms:mp:remove')")
  @ApiOperation("删除小程序")
  @DeleteMapping("/{id}")
  public ApiResult<?> remove(@PathVariable("id") Integer id) {
    if (mpService.removeById(id)) {
      return success("删除成功");
    }
    return fail("删除失败");
  }

  @PreAuthorize("hasAuthority('cms:mp:save')")
  @ApiOperation("批量添加小程序")
  @PostMapping("/batch")
  public ApiResult<?> saveBatch(@RequestBody List<Mp> list) {
    if (mpService.saveBatch(list)) {
      return success("添加成功");
    }
    return fail("添加失败");
  }

  @PreAuthorize("hasAuthority('cms:mp:update')")
  @ApiOperation("批量修改小程序")
  @PutMapping("/batch")
  public ApiResult<?> removeBatch(@RequestBody BatchParam<Mp> batchParam) {
    if (batchParam.update(mpService, "mp_id")) {
      return success("修改成功");
    }
    return fail("修改失败");
  }

  @PreAuthorize("hasAuthority('cms:mp:remove')")
  @ApiOperation("批量删除小程序")
  @DeleteMapping("/batch")
  public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
    if (mpService.removeByIds(ids)) {
      return success("删除成功");
    }
    return fail("删除失败");
  }



  @ApiOperation("小程序基本信息")
  @GetMapping("/getMpInfo")
  public ApiResult<?> getMpInfo() {
    final Integer tenantId = getTenantId();
    String key = "MpInfo:" + tenantId;
    System.out.println("key = " + key);
    final String mpInfo = redisUtil.get(key);

    if (tenantId.equals(0)) {
      return fail("租户ID不存在", null);
    }
    System.out.println("mpInfo = " + mpInfo);
    // 从缓存读取信息
    if (StrUtil.isNotBlank(mpInfo)) {
      final Object object = JSONUtil.parseObject(mpInfo, Object.class);
      System.out.println("object = " + object);
      return success(object);
    }

    // 获取小程序
    if (mpService.count(new LambdaUpdateWrapper<Mp>().eq(Mp::getDeleted, 0)) == 0) {
      // 创建小程序
      createMp();
    }

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

    // 获取小程序
    final Mp mp = mpService.getOne(new LambdaQueryWrapper<Mp>().eq(Mp::getTenantId, tenantId).last("limit 1"));
    mp.setAppSecret(null);
    map.put("mp", mp);

    // 原生导航条
    final List<MpPages> tabBar = mpPagesService.list(new LambdaQueryWrapper<MpPages>().eq(MpPages::getSubpackage, "MainPackage").last("limit 5"));
    map.put("tabBar", tabBar);

    // 配置信息
    HashMap<String, Object> config = new HashMap<>();
    config.put("LICENSE_CODE", "");
    config.put("MAP_KEY", "");
    final List<MpField> fields = mpFieldService.list();
    fields.forEach(d -> {
      config.put(d.getName(), d.getValue());
    });
    map.put("config", config);

    // 服务器时间
    HashMap<String, Object> serverTime = new HashMap<>();
    // 今天日期
    DateTime date = DateUtil.date();
    String today = DateUtil.today();
    // 明天日期
    final DateTime dateTime = DateUtil.tomorrow();
    String tomorrow = DateUtil.format(dateTime, "yyyy-MM-dd");
    // 后天日期
    final DateTime dateTime2 = DateUtil.offsetDay(date, 2);
    final String afterDay = DateUtil.format(dateTime2, "yyyy-MM-dd");
    // 今天星期几
    final int week = DateUtil.thisDayOfWeek();
    final DateTime nextWeek = DateUtil.nextWeek();
    serverTime.put("now", DateUtil.now());   // 2024-07-18 22:06:36
    serverTime.put("today", today);          // 2024-07-18
    serverTime.put("tomorrow", tomorrow);    // 2024-07-19
    serverTime.put("afterDay", afterDay);    // 2024-07-20
    serverTime.put("nextWeek", nextWeek);    // 2024-07-25 22:06:36
    serverTime.put("week", week);            // 5
    map.put("serverTime", serverTime);
    redisUtil.set(key, map, 1L, TimeUnit.DAYS);
    return success(map);
  }

  private void createMp() {
    System.out.println("创建小程序 = ");
    final User loginUser = getLoginUser();
    final Integer tenantId = getTenantId();
    // 创建网站记录
    final Mp mp = new Mp();
    mp.setTenantId(tenantId);
    mp.setAppId("小程序ID");
    mp.setMpName("小程序名称");
    mp.setMainPath("/pages/index");
    if (loginUser != null) {
      mp.setUserId(getLoginUserId());
    }
    mp.setExpirationTime(DateUtil.offset(DateUtil.date(), DateField.YEAR, 1));
    mpService.save(mp);

    // 创建底部导航栏
    final MpPages mpPages = new MpPages();
    mpPages.setHome(1);
    mpPages.setTitle("首页");
    mpPages.setPath("/pages/index");
    mpPages.setSubpackage("MainPackage");
    mpPages.setIcon("HomeOutlined");
    mpPages.setSortNumber(0);
    mpPages.setTenantId(tenantId);
    mpPagesService.save(mpPages);
    mpPages.setHome(0);
    mpPages.setTitle("分类");
    mpPages.setPath("/pages/category");
    mpPages.setSubpackage("MainPackage");
    mpPages.setIcon("AppstoreOutlined");
    mpPages.setSortNumber(0);
    mpPagesService.save(mpPages);
    mpPages.setTitle("购物车");
    mpPages.setPath("/pages/category");
    mpPages.setSubpackage("MainPackage");
    mpPages.setIcon("ShoppingCartOutlined");
    mpPages.setSortNumber(0);
    mpPagesService.save(mpPages);
    mpPages.setTitle("我的");
    mpPages.setPath("/pages/user");
    mpPages.setSubpackage("MainPackage");
    mpPages.setIcon("UserOutlined");
    mpPages.setSortNumber(0);
    mpPagesService.save(mpPages);

    // 创建导航图标
    final MpMenu mpMenu = new MpMenu();
    mpMenu.setTenantId(tenantId);
    mpMenu.setTitle("分类1");
    mpMenu.setIcon("PictureOutlined");
    mpMenu.setPath("/package/order");
    mpMenu.setTarget("uni.navigateTo");
    mpMenuService.save(mpMenu);
    mpMenu.setTitle("分类2");
    mpMenu.setIcon("PictureOutlined");
    mpMenu.setPath("/package/order");
    mpMenuService.save(mpMenu);
    mpMenu.setTitle("分类3");
    mpMenu.setIcon("PictureOutlined");
    mpMenu.setPath("/package/order");
    mpMenuService.save(mpMenu);
    mpMenu.setTitle("分类4");
    mpMenu.setIcon("PictureOutlined");
    mpMenu.setPath("/package/order");
    mpMenuService.save(mpMenu);

    // 小程序配置信息
    MpField field = new MpField();
    field.setName("mpLogo");
    mpFieldService.save(field);
  }

  @ApiOperation("首页数据")
  @GetMapping("/index")
  public ApiResult<?> index(GoodsParam param) {
    // 使用关联查询
    final HashMap<String, Object> layout = new HashMap<>();
    // 瀑布流商品数据  (type：0 商城商品，1 外卖商品)
//    final List<Goods> goods = goodsService.list(new LambdaQueryWrapper<Goods>().ne(Goods::getType, 0).last("limit 10"));
//    final List<Goods> foods = goodsService.list(new LambdaQueryWrapper<Goods>().eq(Goods::getType, 1).last("limit 10"));

    layout.put("goods",goodsService.getGoodsSpecType0());
    layout.put("foods", goodsService.getGoodsSpecType1());

    return success(layout);
  }

  @PreAuthorize("hasAuthority('cms:mp:remove')")
  @ApiOperation("清除缓存")
  @DeleteMapping("/clearMpInfo/{key}")
  public ApiResult<?> clearSiteInfo(@PathVariable("key") String key) {
    redisUtil.delete("MpInfo:" + getTenantId());
    return success("清除成功");
  }

}
