package com.ema.admin.modules.system.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.ema.admin.modules.system.entity.SysMenu;
import com.ema.admin.modules.system.entity.SysRole;
import com.ema.admin.modules.system.service.SysAuthService;
import com.ema.admin.modules.system.service.SysEmailService;
import com.ema.admin.modules.system.vo.*;
import com.ema.common.aspect.logger.LogTypeEnum;
import com.ema.common.aspect.logger.Logger;
import com.ema.common.exceptions.MyAssert;
import com.ema.common.tools.redis.RedisService;
import com.ema.common.utils.CodeUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;

@Api(tags = "用户登录注册授权管理")
@Slf4j
@Validated
@RestController
public class SysAuthController {

    @Resource
    private SysAuthService sysAuthService;
    @Resource
    private RedisService redisService;
    @Resource
    private SysEmailService sysEmailService;

    @ApiOperation(value = "通过账号密码登录")
    @PostMapping(value = "/login")
    @Logger(type = LogTypeEnum.LOGIN)
    public SysUserVo login(@RequestBody @Valid SysUserPwdVo pwdVo) {
        String imgCode = redisService.getStr("IMG_CODE", pwdVo.getAccount());
        MyAssert.isTrue(StrUtil.equalsIgnoreCase(imgCode, pwdVo.getCode()), "验证码错误");
        return sysAuthService.login(pwdVo);
    }

    @ApiOperation(value = "获取图片验证码(返回图片流)")
    @ApiImplicitParam(name = "account", value = "账号", required = true, dataType = "string")
    @GetMapping(value = "/imgCode/{account}")
    public void getImgCode(@PathVariable String account, HttpServletResponse response) {
        String code = CodeUtil.outputImg(100, 40, response);
        redisService.set("IMG_CODE", account, code, 300L);
    }

    @ApiOperation(value = "发送邮箱验证码")
    @PostMapping(value = "/sendEmailCode")
    public void sendEmailCode(@RequestBody @Valid SendEmailCodeVo vo) {
        sysEmailService.sendCode("EMAIL_TEMPLATES", vo.getCode(), vo.getEmail());
    }

    @ApiOperation(value = "退出登录")
    @PostMapping(value = "/logout")
    public void logout() {
        if (StpUtil.isLogin()) {
            StpUtil.logout();
        }
    }

    @ApiOperation(value = "获取当前登录用户数量")
    @GetMapping(value = "/auth/loginUserNum")
    public Integer loginUserNum() {
        // 获取所有登录的用户ids
        List<String> logIds = StpUtil.searchSessionId("", 0, -1, false);
        return logIds.size();
    }

    @ApiOperation(value = "获取当前登录用户信息")
    @GetMapping(value = "/auth/currentUser")
    public SysUserVo getCurrentUser() {
        return sysAuthService.getCurrentUser();
    }

    @ApiOperation(value = "获取当前登录用户菜单列表")
    @GetMapping(value = "/auth/menus")
    public List<SysMenu> getCurrentUserMenus() {
        return sysAuthService.getCurrentUserMenus();
    }

    @ApiOperation(value = "获取当前登录用户菜单树")
    @GetMapping(value = "/auth/menuTree")
    public List<SysMenuVo> getCurrentUserMenuTree() {
        return sysAuthService.getCurrentUserMenuTree();
    }

    @ApiOperation(value = "获取当前登录用户角色列表")
    @GetMapping(value = "/auth/roles")
    public List<SysRole> getCurrentUseRoles() {
        return sysAuthService.getCurrentUseRoles();
    }


    @ApiOperation(value = "修改密码")
    @PostMapping(value = "/auth/updatePwd")
    public void updatePwd(@RequestBody @Valid SysUserPwdUpdateVo updatePwdVo) {
        sysAuthService.updatePwd(updatePwdVo);
    }

    @ApiOperation(value = "忘记密码")
    @PostMapping(value = "/auth/forgotPassword")
    public void forgotPassword(@RequestBody @Valid SysUserForgotPwdVo forgotPwdVo) {
        sysAuthService.forgotPassword(forgotPwdVo);
    }

}
