package com.zxdmy.excite.admin.controller.cloud.account;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zxdmy.excite.common.base.BaseController;
import com.zxdmy.excite.common.base.BaseResult;
import com.zxdmy.excite.common.config.ExciteConfig;
import com.zxdmy.excite.common.entity.PageList;
import com.zxdmy.excite.common.enums.SystemCode;
import com.zxdmy.excite.framework.aop.AnnotationSaveLoginLog;
import com.zxdmy.excite.framework.aop.AnnotationSaveReLog;
import com.zxdmy.excite.system.entity.SysUser;
import com.zxdmy.excite.system.entity.cloud.account.CloudCompany;
import com.zxdmy.excite.system.entity.cloud.account.CloudDepartment;
import com.zxdmy.excite.system.entity.dto.DepartmentTreeDTO;
import com.zxdmy.excite.system.entity.req.account.ReqDepartment;
import com.zxdmy.excite.system.entity.vo.account.DepartmentVo;
import com.zxdmy.excite.system.service.ISysUserService;
import com.zxdmy.excite.system.service.cloud.account.ICloudCompanyService;
import com.zxdmy.excite.system.service.cloud.account.ICloudDepartmentService;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.*;

@Controller
@AllArgsConstructor
@RequestMapping("/cloud/account/user/")
public class AccountUserController extends BaseController {

    private ICloudDepartmentService iCloudDepartmentService;
    private ICloudCompanyService iCloudCompanyService;
    private ISysUserService userService;
    private ExciteConfig exciteConfig;
    @RequestMapping("index")
    public String index() {
        return "cloud/account/user/index";
    }

    @RequestMapping("goAdd/{id}")
    public String goAdd(@PathVariable String id,ModelMap map) {
        map.put("id", id);
        return "cloud/account/user/add";
    }

    @RequestMapping("goEdit/{id}")
    public String goEdit(@PathVariable String id, ModelMap map) {
        // 获取该用户的信息
        SysUser user = userService.getById(id);
        // 加载至前端
        if (user == null) {
            map.put("code", 404);
            map.put("msg", "用户不存在！");
            return "error/error";
        }
        map.put("user", user);
        return "cloud/account/user/edit";
    }
    @RequestMapping("goAuthDepartment/{id}")
    public String goAuthDepartment(@PathVariable String id, ModelMap map) {
        // 获取该用户的信息
        SysUser user = userService.getById(id);
        // 加载至前端
        if (user == null) {
            map.put("code", 404);
            map.put("msg", "用户不存在！");
            return "error/error";
        }
        map.put("user", user);
        return "cloud/account/user/editDepartment";
    }

    @RequestMapping("selectDepartment")
    public String selectDepartment() {
        return "cloud/account/user/selectDepartment";
    }
    @RequestMapping("updateDepartment/{id}")
    public String selectDepartment(@PathVariable String id, ModelMap map) {
        map.put("id", id);
        return "cloud/account/user/updateDepartment";
    }
    @PostMapping(value = "/changeDepartment")
    @ResponseBody
    public BaseResult changeDepartment(String userId, String departmentId) {
        try {
            if (iCloudDepartmentService.changeDepartment(userId, departmentId)==1) {
                return success(200, "转换成功！");
            }
            return success("转换失败，请重试！");
        } catch (Exception e) {
            return error("发生错误：" + e.getMessage());
        }

    }

    /**
     * 接口功能：获取用户列表
     *
     * @param page     当前页面
     * @param limit    每页请求数
     * @param username 检索用户名
     * @param account  检索电话或邮箱
     * @return JSON：用户列表 | 错误信息
     */
    @GetMapping(value = "/list")
    @ResponseBody
    public BaseResult getUserList(Integer page, Integer limit, String username, String account,String departmentId) {
        Page<SysUser> userPage = userService.getPage(page, limit, username, account);
        if (null != userPage) {
            return success("查询成功", userPage.getRecords(), (int) userPage.getTotal());
        } else {
            return error("查询失败，用户不存在");
        }
    }

    @GetMapping(value = "/getPageList")
    @ResponseBody
    public BaseResult getPageList(Integer page, Integer limit, String username, String phone,String departmentId) {
        PageList<SysUser> dataPage = userService.queryByPage(page, limit, username,phone,departmentId);
        if (null != dataPage) {
            return success("查询成功", dataPage.getList(), (int) dataPage.getTotal());
        } else {
            return error("查询失败，用户不存在");
        }
    }

    /**
     * 接口功能：添加用户
     * 基本逻辑：接收前端的用户信息-->校验与初始化新用户信息-->添加至[用户表]-->获取新添加用户的ID-->用户ID与角色ID添加至[用户角色关联表].
     *
     * @param user    用户信息
     * @param roleIds 用户分配的角色信息
     * @return JSON：成败结果
     * @apiNote 启用注解[@AnnotationSaveReLog]保存请求日志
     */
    @PostMapping(value = "/add")
    @ResponseBody
    @AnnotationSaveReLog
    public BaseResult add(SysUser user, Integer[] roleIds,String[] roleIds1,String departmentId) {
        // 新建用户：其邮箱或手机号、密码不能为空，因为这是登录凭证.
        if (null != user && null != user.getPassword() && (null != user.getLoginName() || null != user.getPhone())) {
            // 解密
            user.setPassword(SecureUtil.md5(this.decrypt(user.getPassword())));
            // 添加
            if (userService.saveData(user, roleIds,roleIds1,departmentId) > 0) {
                return success("新用户添加成功！");
            } else {
                return error("新用户添加失败，请重试！");
            }
        }
        return error("用户信息（账号或手机号、密码）不能为空，请重试！");
    }

    /**
     * 接口功能：更新用户基本信息（不含角色信息）
     *
     * @param user 用户信息
     * @return JSON：成败结果
     * @apiNote 启用注解[@AnnotationSaveReLog]保存请求日志
     */
    @PostMapping(value = "/update")
    @ResponseBody
    @AnnotationSaveReLog
    public BaseResult update(SysUser user) {
        // 编辑用户基本信息：用户名、头像、性别、邮箱和手机号。
        if (null != user && null != user.getId()) {
            // 其他信息（状态、密码）不能通过此接口修改，故其应为null.
            if (null == user.getStatus() && null == user.getPassword()) {
                if (userService.save(user, null) > 0) {
                    return success("用户信息编辑成功！");
                } else {
                    return error("用户信息编辑失败，请重试！");
                }
            } else {
                return error("接口请求信息错误！");
            }
        } else {
            return error("用户信息不能为空，请重试！");
        }
    }

    /**
     * 接口功能：删除用户
     * 基本逻辑：删除该用户的角色信息[用户-角色关联表]-->删除用户
     *
     * @param userIds 用户ID列表
     * @return JSON：成败
     * @apiNote 启用注解[@AnnotationSaveReLog]保存请求日志
     */
    @PostMapping(value = "/delete")
    @ResponseBody
    @AnnotationSaveReLog
    public BaseResult delete(Integer[] userIds) {
        try {
            if (userService.deleteUserById(userIds)[0] > 0) {
                return success("用户删除成功");
            }
            return error("用户删除失败");
        } catch (Exception e) {
            return error("发生错误：" + e.getMessage());
        }
    }

    /**
     * 接口功能：给指定用户分配角色
     *
     * @param id      用户ID
     * @param roleIds 角色信息列表
     * @return 分配结果
     */
    @PostMapping(value = "/authRole")
    @ResponseBody
    public BaseResult setRole(Long id, String[] roleIds) {
        try {
            if (userService.setCloudRoleForUser(String.valueOf(id), roleIds)) {
                return success(200, "分配角色成功！");
            }
            return success("分配角色失败，请重试！");
        } catch (Exception e) {
            return error("发生错误：" + e.getMessage());
        }

    }

    /**
     * 接口功能：改变用户的状态
     *
     * @param status  新状态：1-正常 0-禁用
     * @param userIds 用户ID列表
     * @return 修改结果
     */
    @PostMapping(value = "/changeStatus/{status}")
    @ResponseBody
    public BaseResult changeStatus(@PathVariable String status, Integer[] userIds) {
        try {
            int[] result = userService.changeStatus(Integer.parseInt(status), userIds);
            // 没有失败
            if (result[0] != 0 && result[1] == 0) {
                return success(200, "用户状态修改成功！");
            }
            // 有成功的
            else if (result[0] != 0) {
                return success(200, result[0] + "个角色状态更新成功，" + result[1] + "个失败！");
            } else {
                return success(500, "用户状态修改失败，请重试！");
            }
        } catch (Exception e) {
            return error(500, "发生错误:" + e.getMessage());
        }
    }

    /**
     * 接口功能：重置密码
     *
     * @param userId       用户ID
     * @param newPassword  新密码
     * @param newPassword2 新密码
     * @return 重置结果
     */
    @PostMapping(value = "/resetPassword")
    @ResponseBody
    @AnnotationSaveReLog
    public BaseResult resetPassword(String userId, String newPassword, String newPassword2) {
        if (null == userId || null == newPassword || null == newPassword2) {
            return error("输入信息有误，请重新输入！");
        }
        // 密码先解密
        newPassword = this.decrypt(newPassword);
        newPassword2 = this.decrypt(newPassword2);
        // 密码相同
        if (newPassword.equals(newPassword2)) {
            SysUser user = new SysUser();
            try {
                user.setId(Integer.parseInt(userId));
                // 密码MD5加密
                user.setPassword(SecureUtil.md5(newPassword));
                if (userService.save(user, null) > 0) {
                    return success("密码重置成功！");
                } else {
                    error("密码重置失败，请重试！");
                }
            } catch (Exception e) {
                return error(e.getMessage());
            }
        }
        return error("密码重置失败，新密码不一致！");
    }

    /**
     * 接口功能：获取指定角色所分配的用户列表（拥有/不拥有此角色）
     *
     * @param roleId 角色ID
     * @param have   是否用于此角色：0-不拥有 | 1-拥有
     * @return 用户列表
     */
    @GetMapping("/listForRole/{have}/{roleId}")
    @ResponseBody
    public BaseResult getUserListForRole(@PathVariable("have") String have, @PathVariable("roleId") Long roleId) {
        try {
            // 拥有 此角色
            List<SysUser> userList;
            if (have.equals("1")) {
                userList = userService.selectUsersByCloudUploadRoleId(String.valueOf(roleId));
            }
            // 不拥有 此角色
            else {
                userList = userService.selectUsersByCloudUploadRoleIdNotIn(String.valueOf(roleId));
            }
            return success(200, "获取成功", userList);
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }



    /**
     * 私有方法：解密密码
     *
     * @param encrypt 加密密码
     * @return 解密密码
     */
    private String decrypt(String encrypt) {
        // 根据私钥生成新的对象
        RSA rsa = new RSA(exciteConfig.getRsaPrivateKey(), null);
        byte[] decrypt = rsa.decrypt(encrypt, KeyType.PrivateKey);
        return StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8);
    }
}
