package com.micer.easyball.service.Impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.micer.easyball.mapper.ClubMapper;
import com.micer.easyball.mapper.ClubPlayerMapper;
import com.micer.easyball.mapper.PlayerLastClubMapper;
import com.micer.easyball.mapper.UserMapper;
import com.micer.easyball.pojo.*;
import com.micer.easyball.pojo.Dto.UserDto;
import com.micer.easyball.service.LoginService;
import com.micer.easyball.service.UserService;
import com.micer.easyball.utils.JwtUtil;
import com.micer.easyball.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.parameters.P;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ClubMapper clubMapper;

    @Autowired
    private ClubPlayerMapper clubPlayerMapper;

    @Autowired
    private PlayerLastClubMapper playerLastClubMapper;

    @Autowired
    private LoginService loginService;

    @Override
    @Transactional
    public ResponseResult switchRole(String roleName) {
        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId();

        // 获取用户信息
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("id", userId));

        // 校验用户角色
        List<String> roleList =  JSON.parseArray(user.getRoleList(), String.class);
        boolean exist = false;
        for (String role: roleList)
        {
            if (role.equals(roleName))
            {
                exist = true;
                break;
            }
        }

        // 修改用户角色
        if (exist)
        {
            user.setCurrentRole(roleName);
            userMapper.updateById(user);

            // 查询对应的权限信息
            List<String> list = new ArrayList<>();
            list.add(user.getCurrentRole());

            // 把数据封装成UserDetail
            LoginUser newLoginUser = new LoginUser(user, list);

            // 更新redis
            redisUtil.set("Easyball Login User:" + userId, newLoginUser);

            // 更新上次的俱乐部（增加空值保护）
            ClubPlayer clubPlayer = clubPlayerMapper.selectOne(new QueryWrapper<ClubPlayer>().eq("player_id", userId));
            if (clubPlayer != null) {
                PlayerLastClub playerLastClub = playerLastClubMapper.selectOne(new QueryWrapper<PlayerLastClub>().eq("player_id", userId));
                if (playerLastClub != null) {
                    playerLastClub.setLastClubId(clubPlayer.getClubId());
                    playerLastClubMapper.updateById(playerLastClub);
                }
            }

            return new ResponseResult(200, "成功");
        } else
        {
            return new ResponseResult(410, "用户无该权限");
        }
    }

    @Override
    public ResponseResult getRole() {
        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId();

        // 获取用户的所有角色
        List<String> roleList =  JSON.parseArray(loginUser.getUser().getRoleList(), String.class);

        // 返回角色信息
        return new ResponseResult(200, "成功", roleList);
    }

    @Override
    public ResponseResult getCurrentRole() {
        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId();

        // 获取用户的所有角色
        String role =  loginUser.getUser().getCurrentRole();

        // 返回角色信息
        return new ResponseResult(200, "成功", role);
    }

    @Override
    @Transactional
    public ResponseResult switchClub(String clubId) {
        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId();
        User user = userMapper.selectById(userId);

        // 获取俱乐部
        Club club = clubMapper.selectById(clubId);
        if (Objects.isNull(club))
        {
            return new ResponseResult(411, "该俱乐部不存在");
        }

        // 获取用户所属俱乐部角色
        ClubPlayer clubPlayer = clubPlayerMapper.selectOne(new QueryWrapper<ClubPlayer>().eq("player_id", userId).eq("club_id",club.getId()));
        if (Objects.isNull(clubPlayer) && !user.getCurrentRole().equals("ROLE_ADMIN"))
        {
            return new ResponseResult(412, "用户不属于该俱乐部");
        }

        // 切换俱乐部
        PlayerLastClub playerLastClub = playerLastClubMapper.selectOne(new QueryWrapper<PlayerLastClub>().eq("player_id", userId));
        playerLastClub.setLastClubId(club.getId());
        playerLastClubMapper.updateById(playerLastClub);

        return new ResponseResult(200, "成功");
    }

    @Override
    public ResponseResult getClub() {
        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId();
        User user = userMapper.selectById(userId);

        // 获取用户的所有俱乐部
        List<Club> clubList = new ArrayList<>();
        if (user.getCurrentRole().equals("ROLE_ADMIN"))
        {
            clubList = clubMapper.selectList(null);
        } else
        {
            clubList = clubPlayerMapper.selectAllClubByUserId(userId);
        }


        // 返回俱乐部信息
        return new ResponseResult(200, "成功", clubList);
    }

    @Override
    public ResponseResult getCurrentClub() {
        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId();

        // 获取用户当前俱乐部
        PlayerLastClub playerLastClub = playerLastClubMapper.selectOne(new QueryWrapper<PlayerLastClub>().eq("player_id", userId));
        Club club = clubMapper.selectOne(new QueryWrapper<Club>().eq("id", playerLastClub.getLastClubId()));

        // 返回俱乐部信息
        return new ResponseResult(200, "成功", club);
    }

    @Override
    @Transactional
    public ResponseResult addUser(String telephone) {
        // 校验电话号码
        if ((telephone.length() != 11) || (!telephone.matches("\\d+")))
        {
            return new ResponseResult(413, "电话号码不合法");
        }

        // 新增用户
        User user = new User();
        user.setTelephone(telephone);
        user.setUsername(telephone);
        user.setId(JwtUtil.getUUID());
        user.setRoleList("[\"ROLE_USER\"]");
        user.setCurrentRole("ROLE_USER");
        user.setCreateAt(new Date(System.currentTimeMillis()));
        user.setIsEnable(true);

        // 生成强随机初始密码并标记为需首次登录修改
        String rawPassword = generateStrongPassword();
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encode = passwordEncoder.encode(rawPassword);
        user.setPassword(encode);
        user.setForceChangePassword(true);

        userMapper.insert(user);

        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId();

        // 获取登录用户当前的俱乐部
        PlayerLastClub playerLastClub = playerLastClubMapper.selectOne(new QueryWrapper<PlayerLastClub>().eq("player_id", userId));

        playerLastClubMapper.insert(new PlayerLastClub(JwtUtil.getUUID(), user.getId(), playerLastClub.getLastClubId()));

        // 返回初始密码给调用者（请通过安全渠道传递给用户）
        return new ResponseResult(200, "新增成功", java.util.Collections.singletonMap("initialPassword", rawPassword));
    }

    /**
     * 生成一个包含大写、小写、数字和特殊字符的强随机密码，长度为12
     */
    private String generateStrongPassword() {
        String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String lower = "abcdefghijklmnopqrstuvwxyz";
        String digits = "0123456789";
        String special = "!@#$%^&*";

        java.security.SecureRandom random = new java.security.SecureRandom();
        StringBuilder password = new StringBuilder(12);

        // 确保每类字符至少出现一次
        password.append(upper.charAt(random.nextInt(upper.length())));
        password.append(lower.charAt(random.nextInt(lower.length())));
        password.append(digits.charAt(random.nextInt(digits.length())));
        password.append(special.charAt(random.nextInt(special.length())));

        // 填充剩余长度
        String all = upper + lower + digits + special;
        for (int i = 4; i < 12; i++) {
            password.append(all.charAt(random.nextInt(all.length())));
        }

        // 打乱顺序
        char[] chars = password.toString().toCharArray();
        for (int i = chars.length - 1; i > 0; i--) {
            int j = random.nextInt(i + 1);
            char temp = chars[i];
            chars[i] = chars[j];
            chars[j] = temp;
        }

        return new String(chars);
    }

    @Override
    @Transactional
    public ResponseResult addUserToClub(String telephone, String role) {
        // 判断新增用户角色
        if (!(role.equals("ROLE_CLUB_ADMIN") || (role.equals("ROLE_CLUB_PLAYER"))))
        {
            return new ResponseResult(414, "用户角色不合法");
        }

        // 判断数据库中有没有该用户，如果没有就新增
        User userFromDatabase = userMapper.selectOne(new QueryWrapper<User>().eq("telephone", telephone));
        if (Objects.isNull(userFromDatabase))
        {
            ResponseResult res = addUser(telephone);
            if (res.getStatus() == 413)
            {
                return res;
            }
        }

        // 从数据库中获取该用户
        userFromDatabase = userMapper.selectOne(new QueryWrapper<User>().eq("telephone", telephone));

        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId();

        // 获取登录用户当前的俱乐部
        PlayerLastClub playerLastClub = playerLastClubMapper.selectOne(new QueryWrapper<PlayerLastClub>().eq("player_id", userId));
        Club club = clubMapper.selectOne(new QueryWrapper<Club>().eq("id", playerLastClub.getLastClubId()));

        // 将用户添加进俱乐部
        if (!Objects.isNull(clubPlayerMapper.selectOne(new QueryWrapper<ClubPlayer>().eq("player_id", userFromDatabase.getId()).eq("club_id", club.getId()))))
        {
            return new ResponseResult(416, "该用户已经添加");
        }
        clubPlayerMapper.insert(new ClubPlayer(JwtUtil.getUUID(), club.getId(), userFromDatabase.getId(), new Date(System.currentTimeMillis()), role, true));
        return new ResponseResult(200, "添加成功");
    }

    @Override
    @Transactional
    public ResponseResult deleteUserFromClub(String telephone) {
        // 判断用户是否存在
        User userFromDatabase = userMapper.selectOne(new QueryWrapper<User>().eq("telephone", telephone));
        if (Objects.isNull(userFromDatabase))
        {
            return new ResponseResult(415, "用户不存在");
        }

        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId();

        // 获取登录用户当前的俱乐部
        PlayerLastClub playerLastClub = playerLastClubMapper.selectOne(new QueryWrapper<PlayerLastClub>().eq("player_id", userId));

        clubPlayerMapper.delete(new QueryWrapper<ClubPlayer>().eq("player_id", userFromDatabase.getId()).eq("club_id", playerLastClub.getLastClubId()));
        return new ResponseResult(200, "删除成功");
    }

    @Override
    @Transactional
    public ResponseResult modifyRole(String telephone, String role) {
        // 判断角色是否合法
        if (!role.equals("ROLE_CLUB_ADMIN") && !role.equals("ROLE_CLUB_PLAYER"))
        {
            return new ResponseResult(418, "权限不合法");
        }

        // 判断用户是否存在
        User userFromDatabase = userMapper.selectOne(new QueryWrapper<User>().eq("telephone", telephone));
        if (Objects.isNull(userFromDatabase))
        {
            return new ResponseResult(417, "用户不存在");
        }

        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId();

        // 获取登录用户当前的俱乐部
        PlayerLastClub playerLastClub = playerLastClubMapper.selectOne(new QueryWrapper<PlayerLastClub>().eq("player_id", userId));

        // 获取要修改用户信息
        ClubPlayer clubPlayer = clubPlayerMapper.selectOne(new QueryWrapper<ClubPlayer>().eq("player_id", userFromDatabase.getId()).eq("club_id", playerLastClub.getLastClubId()));
        if (Objects.isNull(clubPlayer))
        {
            return new ResponseResult(417, "用户不存在");
        }

        // 修改用户角色
        clubPlayer.setRole(role);
        clubPlayerMapper.updateById(clubPlayer);
        return new ResponseResult(200, "修改成功");
    }

    @Override
    @Transactional
    public ResponseResult modifyPassword(String oldPassword, String newPassword) {
        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId();
        User user = userMapper.selectById(userId);

        // 校验旧密码
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        if (!passwordEncoder.matches(oldPassword, user.getPassword()))
        {
            return new ResponseResult(419, "旧密码错误");
        }

        // 修改密码
        String newPasswordEncoder = passwordEncoder.encode(newPassword);
        user.setPassword(newPasswordEncoder);
        userMapper.updateById(user);

        // 登出
        loginService.logout();

        return new ResponseResult(200, "成功");
    }

    @Override
    public ResponseResult modifyUsername(String newUserName) {
        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId();
        User user = userMapper.selectById(userId);

        // 修改用户名
        user.setUsername(newUserName);
        userMapper.updateById(user);

        return new ResponseResult(200, "成功");
    }

    @Override
    public ResponseResult getLoginUserInfo() {
        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId();
        User user = userMapper.selectById(userId);

        UserDto userDto = new UserDto(user);
        PlayerLastClub playerLastClub = playerLastClubMapper.selectOne(new QueryWrapper<PlayerLastClub>().eq("player_id", userId));
        Club club = clubMapper.selectById(playerLastClub.getLastClubId());
        ClubPlayer clubPlayer = clubPlayerMapper.selectOne(new QueryWrapper<ClubPlayer>().eq("club_id", club.getId()).eq("player_id", userId));

        userDto.setLastClubId(club.getId());
        userDto.setLastClubName(club.getName());
        if (user.getCurrentRole().equals("ROLE_ADMIN"))
        {
            userDto.setClubRole("ROLE_CLUB_ADMIN");
        } else
        {
            userDto.setClubRole(clubPlayer.getRole());
        }


        return new ResponseResult(200, "成功", userDto);
    }
}
