package com.gxwebsoft.common.system.controller;

import cn.hutool.core.stream.CollectorUtil;
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.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.*;
import com.gxwebsoft.common.system.entity.Company;
import com.gxwebsoft.common.system.entity.Dict;
import com.gxwebsoft.common.system.entity.Menu;
import com.gxwebsoft.common.system.entity.Version;
import com.gxwebsoft.common.system.param.MenuParam;
import com.gxwebsoft.common.system.param.VersionParam;
import com.gxwebsoft.common.system.service.CompanyService;
import com.gxwebsoft.common.system.service.MenuService;
import com.gxwebsoft.common.system.service.VersionService;
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.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 菜单控制器
 *
 * @author WebSoft
 * @since 2018-12-24 16:10:23
 */
@Api(tags = "菜单")
@RestController
@RequestMapping("/api/system/menu")
public class MenuController extends BaseController {
    @Resource
    private MenuService menuService;
    @Resource
    private CompanyService companyService;
    @Resource
    private VersionService versionService;

    @PreAuthorize("hasAuthority('sys:menu:list')")
    @ApiOperation("分页查询菜单")
    @GetMapping("/page")
    public ApiResult<PageResult<Menu>> page(MenuParam param) {
        PageParam<Menu, MenuParam> page = new PageParam<>(param);
        page.setDefaultOrder("sort_number asc, create_time desc");
        return success(menuService.page(page, page.getWrapper()));
    }

    @PreAuthorize("hasAuthority('sys:menu:list')")
    @ApiOperation("查询全部菜单")
    @GetMapping()
    public ApiResult<List<Menu>> list(MenuParam param) {
        PageParam<Menu, MenuParam> page = new PageParam<>(param);
        page.setDefaultOrder("sort_number asc, create_time desc");
        return success(menuService.list(page.getOrderWrapper()));
    }

    @PreAuthorize("hasAuthority('sys:menu:list')")
    @ApiOperation("根据id查询菜单")
    @GetMapping("/{id}")
    public ApiResult<Menu> get(@PathVariable("id") Integer id) {
        return success(menuService.getById(id));
    }

    @PreAuthorize("hasAuthority('sys:menu:save')")
    @OperationLog
    @ApiOperation("添加菜单")
    @PostMapping()
    public ApiResult<?> add(@RequestBody Menu menu) {
        if (menu.getParentId() == null) {
            menu.setParentId(0);
        }
        // 去除字符串前面的空格
        menu.setTitle(StrUtil.trimStart(menu.getTitle()));
        menu.setPath(StrUtil.trimStart(menu.getPath()));
        menu.setComponent(StrUtil.trimStart(menu.getComponent()));
        menu.setAuthority(StrUtil.trimStart(menu.getAuthority()));
        if (menuService.save(menu)) {
            return success("添加成功");
        }
        return fail("添加失败");
    }

    @PreAuthorize("hasAuthority('sys:menu:update')")
    @OperationLog
    @ApiOperation("修改菜单")
    @PutMapping()
    public ApiResult<?> update(@RequestBody Menu menu) {
        // 去除字符串前面的空格
        menu.setTitle(StrUtil.trimStart(menu.getTitle()));
        menu.setPath(StrUtil.trimStart(menu.getPath()));
        menu.setComponent(StrUtil.trimStart(menu.getComponent()));
        menu.setAuthority(StrUtil.trimStart(menu.getAuthority()));
        if (menuService.updateById(menu)) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('sys:menu:remove')")
    @OperationLog
    @ApiOperation("删除菜单")
    @DeleteMapping("/{id}")
    public ApiResult<?> remove(@PathVariable("id") Integer id) {
        if (menuService.removeById(id)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

    @PreAuthorize("hasAuthority('sys:menu:save')")
    @OperationLog
    @ApiOperation("批量添加菜单")
    @PostMapping("/batch")
    public ApiResult<?> saveBatch(@RequestBody List<Menu> menus) {
        if (menuService.saveBatch(menus)) {
            return success("添加成功");
        }
        return fail("添加失败");
    }

    @PreAuthorize("hasAuthority('sys:menu:update')")
    @OperationLog
    @ApiOperation("批量修改菜单")
    @PutMapping("/batch")
    public ApiResult<?> updateBatch(@RequestBody BatchParam<Menu> batchParam) {
        if (batchParam.update(menuService, "menu_id")) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('sys:menu:remove')")
    @OperationLog
    @ApiOperation("批量删除菜单")
    @DeleteMapping("/batch")
    public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
        if (menuService.removeByIds(ids)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

    @PreAuthorize("hasAuthority('sys:menu:remove')")
    @ApiOperation("删除父级以下菜单")
    @DeleteMapping("/deleteParentMenu/{id}")
    public ApiResult<?> deleteParentMenu(@PathVariable("id") Integer id) {
      final List<Menu> list = menuService.list(new LambdaQueryWrapper<Menu>().eq(Menu::getParentId, id));
      if (CollectionUtils.isEmpty(list)) {
        menuService.removeById(id);
        return success("删除成功");
      }
      final Set<Integer> ids = list.stream().map(Menu::getMenuId).collect(Collectors.toSet());
      final List<Menu> list2 = menuService.list(new LambdaUpdateWrapper<Menu>().in(Menu::getParentId, ids));
      final Set<Integer> collect = list2.stream().map(Menu::getMenuId).collect(Collectors.toSet());
      if (!CollectionUtils.isEmpty(list2)) {
        ids.addAll(collect);
        final List<Menu> list3 = menuService.list(new LambdaUpdateWrapper<Menu>().in(Menu::getParentId, ids));
        final Set<Integer> collect1 = list3.stream().map(Menu::getMenuId).collect(Collectors.toSet());
        if (!CollectionUtils.isEmpty(collect1)) {
          ids.addAll(collect1);
        }
        ids.add(id);
        if (menuService.removeByIds(ids)) {
          return success("删除成功");
        }
      }
      ids.add(id);
      if (menuService.removeByIds(ids)) {
        return success("删除成功");
      }
      return fail("删除失败");
    }


    @PreAuthorize("hasAuthority('sys:menu:update')")
    @ApiOperation("菜单克隆")
    @PostMapping("/clone")
    public ApiResult<?> onClone(@RequestBody MenuParam param){
      if(menuService.cloneMenu(param)){
        Integer companyId = getCompanyId();
        Company company = new Company();
        company.setCompanyId(companyId);
        company.setPlanId(param.getTenantId());
        VersionParam versionParam = new VersionParam();
        versionParam.setLimit(1L);
        final PageResult<Version> result = versionService.pageRel(versionParam);
        if (!CollectionUtils.isEmpty(result.getList())) {
          Version version = result.getList().get(0);
          company.setVersionName(version.getVersionName());
          company.setVersionCode(version.getVersionCode());
        }
        companyService.updateById(company);
        return success("安装成功");
      }
      return fail("安装失败");
    }

    @PreAuthorize("hasAuthority('sys:menu:update')")
    @ApiOperation("安装插件")
    @GetMapping("/install/{id}")
    public ApiResult<?> install(@PathVariable("id") Integer id){
      if(menuService.install(id)){
        // 更新安装次数
//        final Plug plug = plugService.getOne(new LambdaQueryWrapper<Plug>().eq(Plug::getMenuId, id));
//        plug.setInstalls(plug.getInstalls() + 1);
//        plugService.updateById(plug);
        return success("安装成功");
      }
      return fail("安装失败",id);
    }
}
