package org.wcs.serve.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.wcs.constant.enums.common.TrueOrFalseEnum;
import org.wcs.constant.enums.database.UserStatusEnum;
import org.wcs.factory.AppServeResponseFactory;
import org.wcs.mapper.intf.AppBaseMenuService;
import org.wcs.mapper.intf.AppBaseUserService;
import org.wcs.model.dto.serve.user.*;
import org.wcs.model.vo.serve.AppServeDataResponse;
import org.wcs.model.vo.serve.AppServeResponse;
import org.wcs.model.vo.serve.user.*;
import org.wcs.model.pojo.serve.UserMenuPermission;
import org.wcs.model.po.app.AppBaseMenu;
import org.wcs.model.po.app.AppBaseUser;
import org.wcs.model.po.app.JoinUserInfoWithGroupInfo;
import org.wcs.serve.service.intf.IUserService;
import org.wcs.utils.AppBeanUtils;
import org.wcs.utils.AppStringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
@RequiredArgsConstructor
public class UserService implements IUserService {

    private final AppBaseUserService baseUserService;
    private final AppBaseMenuService baseMenuService;

    /**
     * 用户登录
     * @param loginReq 用户登录请求
     * @return 结果
     */
    @Override
    public AppServeDataResponse<LoginResp> login(LoginReq loginReq) {
        String encryptPwd = AppStringUtils.encryptPwd(loginReq.getPassword());
        AppBaseUser query = new AppBaseUser();
        query.setUserId(loginReq.getUserId());
        query.setUserPwd(encryptPwd);
        List<AppBaseUser> users = baseUserService.query(query);
        if(users == null) {
            return AppServeResponseFactory.internalServerError("数据服务异常", null);
        }
        if(users.isEmpty()) {
            return AppServeResponseFactory.fail("用户名或密码错误", null);
        }
        AppBaseUser user = users.getFirst();
        log.info("用户登录：{}", user.getUserId());
        if(Objects.equals(user.getUserStatus(), UserStatusEnum.OK.getCode())) {
            StpUtil.login(user.getUserId());
            // 更新用户登录时间
            AppBaseUser updateLastLoginTime = new AppBaseUser();
            updateLastLoginTime.setUserId(user.getUserId());
            updateLastLoginTime.setLastLoginTime(LocalDateTime.now());
            int updateResult = baseUserService.update(updateLastLoginTime);
            log.info("更新用户登录时间成功：{}", updateResult);
            LoginResp loginResp = new LoginResp();
            loginResp.setToken(StpUtil.getTokenValue());
            loginResp.setUserId(user.getUserId());
            loginResp.setUserLevel(user.getUserLevel());
            loginResp.setUserName(user.getUserName());
            loginResp.setLastLoginTime(user.getLastLoginTime());
            loginResp.setUserGroup(user.getUserGroup());
            return AppServeResponseFactory.success("登录成功", loginResp);
        }
        return AppServeResponseFactory.fail("用户状态异常，请联系管理员", null);
    }

    /**
     * 获取用户权限
     * @return 结果
     */
    @Override
    public AppServeDataResponse<UserPermissionResp> permission() {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录", null);
        }
        String userId = userIdObj.toString();
        List<JoinUserInfoWithGroupInfo> users = baseUserService.query(userId);
        if(users == null) {
            return AppServeResponseFactory.internalServerError("数据服务异常", null);
        }
        if(users.isEmpty()) {
            return AppServeResponseFactory.fail("用户没有权限，请联系管理员查看您的用户组是否启用", null);
        }
        JoinUserInfoWithGroupInfo user = users.getFirst();
        List<AppBaseMenu> menuList = baseMenuService.queryPermission(user.getUserGroup());
        if(menuList == null) {
            return AppServeResponseFactory.internalServerError("数据服务异常", null);
        }
        if(menuList.isEmpty()) {
            return AppServeResponseFactory.fail("用户权限不足，请联系管理员查看是否授予您访问资源的权限", null);
        }
        List<UserMenuPermission> returnMenuList = new ArrayList<>();
        for(AppBaseMenu menu : menuList) {
            UserMenuPermission userMenuPermission = new UserMenuPermission();
            userMenuPermission.setMenuId(menu.getMenuId());
            userMenuPermission.setMenuName(menu.getMenuName());
            userMenuPermission.setMenuIco(menu.getMenuIco());
            userMenuPermission.setRouterName(menu.getRouterName());
            userMenuPermission.setMenuLevel(menu.getMenuLevel());
            userMenuPermission.setFatherMenuId(menu.getFatherMenuId());
            returnMenuList.add(userMenuPermission);
        }
        UserPermissionResp userPermissionResp = new UserPermissionResp();
        userPermissionResp.setUserId(user.getUserId());
        userPermissionResp.setUserName(user.getUserName());
        userPermissionResp.setUserLevel(user.getUserLevel());
        userPermissionResp.setUserGroup(user.getUserGroup());
        userPermissionResp.setGroupLevel(user.getGroupLevel());
        userPermissionResp.setUserMenuPermission(returnMenuList);
        return AppServeResponseFactory.success("获取用户权限成功", userPermissionResp);
    }

    /**
     * 查询用户
     * @param queryUserReq 查询用户请求
     * @return 查询结果
     */
    @Override
    public AppServeDataResponse<List<QueryUserResp>> queryUser(QueryUserReq queryUserReq) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录", null);
        }
        String userId = userIdObj.toString();
        AppBaseUser query = new AppBaseUser();
        query.setUserId(userId);
        List<AppBaseUser> users = baseUserService.query(query);
        if(users == null) {
            return AppServeResponseFactory.internalServerError("数据服务异常", null);
        }
        if(users.isEmpty()) {
            return AppServeResponseFactory.fail("用户没有权限，请联系管理员查看您的用户是否启用", null);
        }
        var user = users.getFirst();
        Integer userLevel = user.getUserLevel();
        if(userLevel == null) {
            return AppServeResponseFactory.fail("用户没有设定用户级别", null);
        }
        AppBaseUser queryUser = new AppBaseUser();
        queryUser.setUserId(queryUserReq.getUserId());
        queryUser.setUserName(queryUserReq.getUserName());
        List<AppBaseUser> queryResult = baseUserService.query(queryUser, userLevel);
        if(queryResult == null) {
            return AppServeResponseFactory.internalServerError("数据服务异常", null);
        }
        List<QueryUserResp> queryUserRespList = AppBeanUtils.copyListProperties(queryResult, QueryUserResp::new);
        for(QueryUserResp queryUserResp : queryUserRespList) {
            queryUserResp.setOnline(StpUtil.isLogin(queryUserResp.getUserId()) ? TrueOrFalseEnum.TRUE.getCode() : TrueOrFalseEnum.FALSE.getCode());
        }
        return AppServeResponseFactory.success("查询用户成功", queryUserRespList);
    }

    /**
     * 登出用户
     * @param userId 需要登出用户ID
     * @return 登出结果
     */
    @Override
    public AppServeResponse logoutUser(String userId) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录");
        }
        String operationUserId = userIdObj.toString();
        StpUtil.logout(userId);
        log.info("用户：{} 登出用户：{}", operationUserId, userId);
        return AppServeResponseFactory.success("用户退出成功");
    }

    /**
     * 更新用户
     * @param updateUserReq 更新用户请求
     * @return 更新结果
     */
    @Override
    public AppServeResponse updateUser(UpdateUserReq updateUserReq) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录");
        }
        String operationUserId = userIdObj.toString();
        String encryptPwd = AppStringUtils.encryptPwd(updateUserReq.getUserPwd());
        AppBaseUser updateUser = new AppBaseUser();
        updateUser.setUserId(updateUserReq.getUserId());
        updateUser.setUserName(updateUserReq.getUserName());
        updateUser.setUserPwd(encryptPwd);
        updateUser.setUserStatus(updateUserReq.getUserStatus());
        updateUser.setUserGroup(updateUserReq.getUserGroup());
        updateUser.setSex(updateUserReq.getSex());
        updateUser.setPhoto(updateUserReq.getPhoto());
        updateUser.setUserLevel(updateUserReq.getUserLevel());
        int updateResult = baseUserService.update(updateUser);
        if(updateResult <= 0) {
            return AppServeResponseFactory.fail("更新用户失败");
        }
        if(AppStringUtils.isNotEmpty(updateUserReq.getUserPwd())) {
            StpUtil.logout(updateUserReq.getUserId());
            log.info("用户：{} 通过修改用户密码登出用户：{}", operationUserId, updateUserReq.getUserId());
        }
        log.info("用户：{} 更新用户信息：{}", operationUserId, AppStringUtils.objectToString(updateUserReq));
        return AppServeResponseFactory.success("更新用户成功");
    }

    /**
     * 删除用户
     * @param userId 需要删除用户ID
     * @return 删除结果
     */
    @Override
    public AppServeResponse deleteUser(String userId) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录");
        }
        String operationUserId = userIdObj.toString();
        log.info("用户：{} 企图删除用户：{}", operationUserId, userId);
        int deleteResult = baseUserService.deleteWithUserId(userId);
        if(deleteResult <= 0) {
            return AppServeResponseFactory.fail("删除用户失败");
        }
        StpUtil.logout(userId);
        log.info("用户：{} 通过删除用户账号登出用户：{}", operationUserId, userId);
        log.info("用户：{} 成功删除用户：{}", operationUserId, userId);
        return AppServeResponseFactory.success("删除用户成功");
    }

    /**
     * 创建一个用户
     * @param createUserReq 创建信息
     * @return 创建结果
     */
    @Override
    public AppServeResponse createUser(CreateUserReq createUserReq) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录");
        }
        String operationUserId = userIdObj.toString();
        log.info("用户：{} 企图创建用户：{}", operationUserId, AppStringUtils.objectToString(createUserReq));
        AppBaseUser checkUserExist = new AppBaseUser();
        checkUserExist.setUserId(createUserReq.getUserId());
        List<AppBaseUser> checkUsers = baseUserService.query(checkUserExist);
        if(checkUsers == null) {
            return AppServeResponseFactory.internalServerError("数据服务异常");
        }
        if(!checkUsers.isEmpty()) {
            return AppServeResponseFactory.fail("用户已存在", null);
        }
        AppBaseUser insertUser = new AppBaseUser();
        AppBeanUtils.copyProperties(createUserReq, insertUser);
        int insertCount = baseUserService.insert(insertUser);
        if(insertCount == 0) {
            return AppServeResponseFactory.internalServerError("数据服务异常");
        }
        log.info("用户：{} 成功创建用户：{}", operationUserId, AppStringUtils.objectToString(createUserReq));
        return AppServeResponseFactory.success(String.format("添加用户：%s 成功", createUserReq.getUserId()));

    }

    /**
     * 简单查询用户拥有的权限菜单
     * @return 查询结果
     */
    @Override
    public AppServeDataResponse<List<QueryUserMenuPermissionSimpleTreeResp>> queryUserMenuPermissionSimpleTree() {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录", null);
        }
        String userId = userIdObj.toString();
        List<JoinUserInfoWithGroupInfo> users = baseUserService.query(userId);
        if(users == null) {
            return AppServeResponseFactory.internalServerError("数据服务异常", null);
        }
        if(users.isEmpty()) {
            return AppServeResponseFactory.fail("用户没有权限，请联系管理员查看您的用户组是否启用", null);
        }
        JoinUserInfoWithGroupInfo user = users.getFirst();
        List<AppBaseMenu> menuList = baseMenuService.queryPermission(user.getUserGroup());
        if(menuList == null) {
            return AppServeResponseFactory.internalServerError("数据服务异常", null);
        }
        if(menuList.isEmpty()) {
            return AppServeResponseFactory.fail("用户权限不足，请联系管理员查看是否授予您访问资源的权限", null);
        }
        List<QueryUserMenuPermissionSimpleTreeResp> response = new ArrayList<>();
        List<AppBaseMenu> mainMenuList = menuList.stream().sorted(Comparator.comparing(AppBaseMenu::getMenuId)).filter(appBaseMenu -> appBaseMenu.getMenuLevel() == 1).toList();
        if(mainMenuList.isEmpty()) {
            return AppServeResponseFactory.fail("用户权限不足，请联系管理员查看是否授予您访问资源的权限", null);
        }
        for (AppBaseMenu mainMenu : mainMenuList) {
            QueryUserMenuPermissionSimpleTreeResp queryUserMenuPermissionSimpleTreeResp = new QueryUserMenuPermissionSimpleTreeResp();
            queryUserMenuPermissionSimpleTreeResp.setMenuId(mainMenu.getMenuId());
            queryUserMenuPermissionSimpleTreeResp.setMenuName(mainMenu.getMenuName());
            List<AppBaseMenu> subMenuList = menuList.stream().sorted(Comparator.comparing(AppBaseMenu::getMenuId)).filter(appBaseMenu ->
                    AppStringUtils.isNotEmpty(appBaseMenu.getFatherMenuId()) && appBaseMenu.getFatherMenuId().equals(mainMenu.getMenuId())).toList();
            if(subMenuList.isEmpty()) {
                continue;
            }
            List<MinorMenuPermissionSimpleTreeData> subMenuRespList = new ArrayList<>();
            for (AppBaseMenu subMenu : subMenuList) {
                MinorMenuPermissionSimpleTreeData minorMenuPermissionSimpleTreeData = new MinorMenuPermissionSimpleTreeData();
                minorMenuPermissionSimpleTreeData.setMenuId(subMenu.getMenuId());
                minorMenuPermissionSimpleTreeData.setMenuName(subMenu.getMenuName());
                subMenuRespList.add(minorMenuPermissionSimpleTreeData);
            }
            queryUserMenuPermissionSimpleTreeResp.setMinMenuPermissionSimpleTreeRespList(subMenuRespList);
            response.add(queryUserMenuPermissionSimpleTreeResp);
        }
        return AppServeResponseFactory.success(response);
    }

    /**
     * 修改自己的用户信息
     * @param updateSelfUserReq 修改信息
     * @return 修改结果
     */
    @Override
    public AppServeResponse updateSelfUser(UpdateSelfUserReq updateSelfUserReq) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录");
        }
        String userId = userIdObj.toString();
        if(!userId.equals(updateSelfUserReq.getUserId())) {
            log.warn("用户：{} 企图通过修改自己信息接口修改用户：{} 的信息，{}", userId, updateSelfUserReq.getUserId(), AppStringUtils.objectToString(updateSelfUserReq));
            return AppServeResponseFactory.forbidden("你不能通过此接口修改不是自己的账号的数据，你的行为已经被记录");
        }
        String encryptOldPwd = AppStringUtils.encryptPwd(updateSelfUserReq.getOldPwd());
        AppBaseUser query = new AppBaseUser();
        query.setUserId(updateSelfUserReq.getUserId());
        query.setUserPwd(encryptOldPwd);
        List<AppBaseUser> users = baseUserService.query(query);
        if(users == null) {
            return AppServeResponseFactory.internalServerError("数据服务异常");
        }
        if(users.isEmpty()) {
            return AppServeResponseFactory.fail("用户名或密码错误");
        }
        String encryptPwd = AppStringUtils.encryptPwd(updateSelfUserReq.getNewPwd());
        AppBaseUser updateUser = new AppBaseUser();
        updateUser.setUserId(updateSelfUserReq.getUserId());
        updateUser.setUserName(updateSelfUserReq.getUserName());
        updateUser.setUserPwd(encryptPwd);
        updateUser.setSex(updateSelfUserReq.getSex());
        updateUser.setPhoto(updateSelfUserReq.getPhoto());
        int updateResult = baseUserService.update(updateUser);
        if(updateResult <= 0) {
            return AppServeResponseFactory.fail("更新用户失败");
        }
        if(AppStringUtils.isNotEmpty(updateSelfUserReq.getNewPwd())) {
            StpUtil.logout(updateSelfUserReq.getUserId());
            log.info("用户：{} 通过修改自己的密码登出用户：{}", userId, updateSelfUserReq.getUserId());
        }
        log.info("用户：{} 更新自己的用户信息：{}", userId, AppStringUtils.objectToString(updateSelfUserReq));
        return AppServeResponseFactory.success("更新用户成功");
    }
}
