package com.example.his.api.mis.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.example.his.api.common.result.R;
import com.example.his.api.req.MisLogin.LoginForm;
import com.example.his.api.req.MisLogin.UpdatePasswordForm;
import com.example.his.api.mis.service.UserService;
import com.example.his.api.resp.PermissionAllResp;
import com.example.his.api.resp.PermissionMenuResp;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;

@RestController
@RequestMapping("/mis/admin")
public class loginController {

    @Resource
    private UserService userService;

    /**
     * 用户登录
     * @param form
     * @return
     */
    @PostMapping("/login")
    public R login(@RequestBody @Valid LoginForm form) {
        // 把Form对象转换成Map对象。因为Form对象中含有后端验证表达式，该对象仅用于Web层，不适合传给业务层
        Map param = BeanUtil.beanToMap(form);
        // 获取登陆用户的主键值
        Integer userId = userService.login(param);
        if (userId != null) {
            /*
             * 实现同端互斥效果，把该用户Web端的令牌销毁。
             * 在其他浏览器上已经登陆的该账户，令牌就失效了，实现同端互斥。
             */
            StpUtil.logout(userId, "Web");
            // 通过会话对象，向SaToken传递userId
            StpUtil.login(userId, "Web");
            // 生成新的令牌字符串，标记该令牌是给Web端用户使用的
            String token = StpUtil.getTokenValueByLoginId(userId, "Web");
            // 获取用户的权限列表
            List<String> permissionNames = StpUtil.getPermissionList();
            // 使用 Collections.sort() 排序
            Collections.sort(permissionNames);
            // 查询用户所有权限对象列表
            List<PermissionAllResp> permissions = userService.searchPermissions(permissionNames);
            // 用户管理-查询权限递归菜单
            List<PermissionMenuResp> permissionsMenu = userService.searchPermissionsMenu(permissions);
            // 向前端返回数据
            HashMap<String, Object> map = new HashMap<>();
            map.put("token", token);
            map.put("permissionNames", permissionNames);
            map.put("permissions", permissions);
            map.put("permissionsMenu", permissionsMenu);
            return R.success(map);
        }
        // 如果登陆失败，返回给前端的result是false

        return R.error();
    }

    /**
     * 用户退出
     * @return
     */
    @GetMapping("/logout")
    @SaCheckLogin
    public R logout() {
        //从令牌中解密出来userId
        int userId = StpUtil.getLoginIdAsInt();
        //销毁令牌
        StpUtil.logout(userId, "Web");
        return R.success();
    }

    /**
     * 修改密码
     * @param form
     * @return
     */
    @PostMapping("/updatePassword")
    @SaCheckLogin
    public R updatePassword(@Valid @RequestBody UpdatePasswordForm form) {
        int userId = StpUtil.getLoginIdAsInt();
        HashMap param = new HashMap() {{
            put("userId", userId);
            put("password", form.getPassword());
            put("newPassword", form.getNewPassword());
        }};
        int rows = userService.updatePassword(param);

        return rows == 1 ? R.success() : R.success("200", "修改失败");
    }

    /**
     * 查询当前医生的摘要信息
     * @return
     */
    @GetMapping("/searchDoctorById")
    @SaCheckLogin
    public R searchDoctorById() {
        Integer userId = StpUtil.getLoginIdAsInt();
        HashMap map = userService.searchDoctorById(userId);
        return R.success(map);
    }
}
