package cn.iocoder.byzs.module.web.service.login;

import cn.iocoder.byzs.framework.common.enums.CommonStatusEnum;
import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
import cn.iocoder.byzs.module.system.controller.admin.auth.vo.AuthLoginRespVO;
import cn.iocoder.byzs.module.system.controller.admin.auth.vo.AuthRegisterReqVO;
import cn.iocoder.byzs.module.system.controller.admin.invitecode.vo.InviteCodeSaveReqVO;
import cn.iocoder.byzs.module.system.controller.admin.userwebexpiretime.vo.UserWebExpireTimeSaveReqVO;
import cn.iocoder.byzs.module.system.dal.dataobject.dict.DictDataDO;
import cn.iocoder.byzs.module.system.dal.dataobject.invitecode.InviteCodeDO;
import cn.iocoder.byzs.module.system.dal.dataobject.permission.RoleDO;
import cn.iocoder.byzs.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.byzs.module.system.dal.dataobject.userwebexpiretime.UserWebExpireTimeDO;
import cn.iocoder.byzs.module.system.service.auth.AdminAuthService;
import cn.iocoder.byzs.module.system.service.dict.DictDataService;
import cn.iocoder.byzs.module.system.service.invitecode.InviteCodeService;
import cn.iocoder.byzs.module.system.service.permission.PermissionService;
import cn.iocoder.byzs.module.system.service.permission.RoleService;
import cn.iocoder.byzs.module.system.service.user.AdminUserServiceImpl;
import cn.iocoder.byzs.module.system.service.userwebexpiretime.UserWebExpireTimeService;
import cn.iocoder.byzs.module.web.controller.admin.login.vo.WebRegisterVO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static cn.iocoder.byzs.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.byzs.module.system.enums.ErrorCodeConstants.USER_CODE_FAILURE;
import static cn.iocoder.byzs.module.system.enums.ErrorCodeConstants.USER_CODE_USED;

@Service
public class WebLoginServiceImpl {
    @Resource
    private AdminUserServiceImpl userService;
    @Resource
    private RoleService roleService;
    @Resource
    private DictDataService dictDataService;
    @Resource
    private PermissionService permissionService;
    @Resource
    private InviteCodeService inviteCodeService;
    @Resource
    private UserWebExpireTimeService userWebExpireTimeService;
    @Resource
    private AdminAuthService authService;

    public Long register(WebRegisterVO registerVO) {

        //校验邀请码
        InviteCodeDO inviteCode = inviteCodeService.getUnusedInviteCode(registerVO.getInviteCode());
        if (inviteCode == null) {
            throw exception(USER_CODE_FAILURE);
        }
        if(!"0".equals(inviteCode.getStatus())){
            throw exception(USER_CODE_USED);
        }

        // 注册
        AuthRegisterReqVO registerReqVo = new AuthRegisterReqVO();
        BeanUtils.copyProperties(registerVO, registerReqVo);
//        Long userId = userService.registerUser(registerReqVo);
        AuthLoginRespVO register = authService.register(registerReqVo);
        Long userId = register.getUserId();

        //租户id
        AdminUserDO user = userService.getUser(userId);
        Set<Long> roleIds = Arrays.stream(inviteCode.getRoleIds().split(","))
                .map(s ->Long.parseLong(s.trim())).collect(Collectors.toSet());
        permissionService.assignUserRole(userId, roleIds);

        // 更新邀请码为已使用
        inviteCodeService.updateInviteCode(new InviteCodeSaveReqVO()
                        .setId(inviteCode.getId())
                        .setUseUserId(userId)
                        .setUseUserTenantId(user.getTenantId())
                        .setUseTime(LocalDateTime.now())
                        .setExpireTime(LocalDateTime.now().plusDays(inviteCode.getValidTime()))
                        .setStatus("1"));


        List<RoleDO> roleList = roleService.getRoleList(roleIds);
        roleList.removeIf(role -> !CommonStatusEnum.ENABLE.getStatus().equals(role.getStatus())); // 移除禁用的角色
        Set<String> roleWebMap = new HashSet<>();
        roleList.forEach(role -> {
            if(role.getDataScopeWebRoute() != null && !role.getDataScopeWebRoute().isEmpty()){
                roleWebMap.addAll(role.getDataScopeWebRoute());
            }
        });

        //当前用户web过期时间
        UserWebExpireTimeDO userWebExpireTime = userWebExpireTimeService.getUserWebExpireTime(userId);
        if (userWebExpireTime != null) {
            if(roleWebMap.contains("course")){
                userWebExpireTime.setCourseExpireTime(userWebExpireTime.getCourseExpireTime().plusDays(inviteCode.getValidTime()));
            }
            if(roleWebMap.contains("blockly")){
                userWebExpireTime.setBlocklyExpireTime(userWebExpireTime.getBlocklyExpireTime().plusDays(inviteCode.getValidTime()));
            }
            if (roleWebMap.contains("aiCourse")){
                userWebExpireTime.setAiCourseExpireTime(userWebExpireTime.getAiCourseExpireTime().plusDays(inviteCode.getValidTime()));
            }

            // 更新用户web过期时间
            userWebExpireTimeService.updateUserWebExpireTime(BeanUtils.toBean(userWebExpireTime, UserWebExpireTimeSaveReqVO.class));
        }else{
            // 创建用户web过期时间
            UserWebExpireTimeSaveReqVO userWebExpireTimeDO = new UserWebExpireTimeSaveReqVO().setUserId(userId);
            if(roleWebMap.contains("course")){
                userWebExpireTimeDO.setCourseExpireTime(LocalDateTime.now().plusDays(inviteCode.getValidTime()));
            }
            if(roleWebMap.contains("blockly")){
                userWebExpireTimeDO.setBlocklyExpireTime(LocalDateTime.now().plusDays(inviteCode.getValidTime()));
            }
            if (roleWebMap.contains("aiCourse")){
                userWebExpireTimeDO.setAiCourseExpireTime(LocalDateTime.now().plusDays(inviteCode.getValidTime()));
            }
            userWebExpireTimeService.createUserWebExpireTime(userWebExpireTimeDO);
        }
        // 用户id
        return userId;
    }

    public Set<String> getRoleRoute(Long userId) {
        Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(userId);
        List<RoleDO> roles = roleService.getRoleList(roleIds);
        roles.removeIf(role -> !CommonStatusEnum.ENABLE.getStatus().equals(role.getStatus())); // 移除禁用的角色

        // 填充角色路由
        Set<String> roleRouteSet = new HashSet<>();
        for (RoleDO role : roles) {
            if(role.getDataScopeWebRoute() != null && !role.getDataScopeWebRoute().isEmpty()){
                roleRouteSet.addAll(role.getDataScopeWebRoute());
            }
        }
        // 如果roleRoutes为空，则从字典中获取默认路由
        if (roleRouteSet.isEmpty()) {
            List<DictDataDO> webRoleRoute = dictDataService.getDictDataListByDictType("web_role_route");
            Set<String> roleRoute = webRoleRoute.stream().map(DictDataDO::getValue).collect(Collectors.toSet());
            roleRouteSet.addAll(roleRoute);
        }

        // 获得用户激活的邀请码
        List<InviteCodeDO> inviteCodes = inviteCodeService.getInviteCodeByUserId(userId);
        if (inviteCodes.isEmpty()) {
            return roleRouteSet;
        }

        //当前用户web过期时间
        UserWebExpireTimeDO userWebExpireTime = userWebExpireTimeService.getUserWebExpireTime(userId);
        if (userWebExpireTime != null) {
            LocalDateTime now = LocalDateTime.now();
            if(userWebExpireTime.getCourseExpireTime() == null || userWebExpireTime.getCourseExpireTime().isBefore(now)){
                roleRouteSet.remove("course");
            }
            if(userWebExpireTime.getBlocklyExpireTime() == null || userWebExpireTime.getBlocklyExpireTime().isBefore(now)){
                roleRouteSet.remove("blockly");
            }
            if(userWebExpireTime.getAiCourseExpireTime() == null || userWebExpireTime.getAiCourseExpireTime().isBefore(now)){
                roleRouteSet.remove("aiCourse");
            }
        }
        return roleRouteSet;
    }
}
