package com.lesingle.edu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lesingle.edu.common.enums.ErrorCode;
import com.lesingle.edu.common.enums.GenericStatus;
import com.lesingle.edu.common.enums.TenantStatus;
import com.lesingle.edu.common.enums.UserRole;
import com.lesingle.edu.common.exception.BusinessException;
import com.lesingle.edu.common.security.JwtPayload;
import com.lesingle.edu.common.security.JwtTokenProvider;
import com.lesingle.edu.common.security.JwtTokenRedisService;
import com.lesingle.edu.common.security.SecurityUtils;
import com.lesingle.edu.dto.request.LoginRequest;
import com.lesingle.edu.dto.request.UpdateProfileRequest;
import com.lesingle.edu.dto.response.LoginResponse;
import com.lesingle.edu.dto.response.TokenResponse;
import com.lesingle.edu.dto.response.UpdateProfileResponse;
import com.lesingle.edu.dto.response.UserInfoResponse;
import com.lesingle.edu.entity.AdminUser;
import com.lesingle.edu.entity.Parent;
import com.lesingle.edu.entity.Tenant;
import com.lesingle.edu.entity.Teacher;
import com.lesingle.edu.mapper.AdminUserMapper;
import com.lesingle.edu.mapper.ParentMapper;
import com.lesingle.edu.mapper.TenantMapper;
import com.lesingle.edu.mapper.TeacherMapper;
import com.lesingle.edu.service.AuthService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

@Slf4j
@Service
@RequiredArgsConstructor
public class AuthServiceImpl implements AuthService {

    private final AdminUserMapper adminUserMapper;
    private final TeacherMapper teacherMapper;
    private final ParentMapper parentMapper;
    private final TenantMapper tenantMapper;
    private final JwtTokenProvider jwtTokenProvider;
    private final JwtTokenRedisService jwtTokenRedisService;
    private final PasswordEncoder passwordEncoder;

    @Override
    public LoginResponse login(LoginRequest request) {
        String username = request.getUsername();
        String password = request.getPassword();
        String role = request.getRole();

        // 如果指定了角色，使用指定角色登录
        if (role != null && !role.isEmpty()) {
            return loginWithRole(username, password, role);
        }

        // 尝试管理员登录
        AdminUser adminUser = adminUserMapper.selectOne(
                new LambdaQueryWrapper<AdminUser>().eq(AdminUser::getUsername, username)
        );
        if (adminUser != null) {
            if (!passwordEncoder.matches(password, adminUser.getPassword())) {
                log.warn("登录失败：密码错误，用户名：{}", username);
                throw new BusinessException(ErrorCode.INCORRECT_PASSWORD);
            }
            if (!GenericStatus.isActive(adminUser.getStatus())) {
                log.warn("登录失败：账户已禁用，用户名：{}", username);
                throw new BusinessException(ErrorCode.ACCOUNT_DISABLED);
            }
            // 更新最后登录时间
            adminUser.setLastLoginAt(LocalDateTime.now());
            adminUserMapper.updateById(adminUser);

            JwtPayload payload = JwtPayload.builder()
                    .userId(adminUser.getId())
                    .username(adminUser.getUsername())
                    .role(UserRole.ADMIN.getCode())
                    .tenantId(null)
                    .name(adminUser.getName())
                    .build();

            String token = jwtTokenProvider.generateToken(payload);
            // 存储 token 到 Redis
            jwtTokenRedisService.storeToken(adminUser.getUsername(), token, jwtTokenProvider.getExpiration());

            log.info("管理员登录成功，用户名：{}", username);
            return LoginResponse.builder()
                    .token(token)
                    .userId(adminUser.getId())
                    .username(adminUser.getUsername())
                    .name(adminUser.getName())
                    .role(UserRole.ADMIN.getCode())
                    .tenantId(null)
                    .build();
        }

        // 尝试教师登录
        Teacher teacher = teacherMapper.selectOne(
                new LambdaQueryWrapper<Teacher>().eq(Teacher::getUsername, username)
        );
        if (teacher != null) {
            if (!passwordEncoder.matches(password, teacher.getPassword())) {
                log.warn("登录失败：密码错误，用户名：{}", username);
                throw new BusinessException(ErrorCode.INCORRECT_PASSWORD);
            }
            if (!GenericStatus.isActive(teacher.getStatus())) {
                log.warn("登录失败：账户已禁用，用户名：{}", username);
                throw new BusinessException(ErrorCode.ACCOUNT_DISABLED);
            }
            // 检查教师所属租户状态
            Tenant tenant = tenantMapper.selectById(teacher.getTenantId());
            if (tenant != null && TenantStatus.SUSPENDED.getCode().equalsIgnoreCase(tenant.getStatus())) {
                log.warn("登录失败：租户服务已暂停，租户 ID: {}, 教师用户名：{}", tenant.getId(), username);
                throw new BusinessException(ErrorCode.TENANT_SUSPENDED);
            }
            // 更新最后登录时间
            teacher.setLastLoginAt(LocalDateTime.now());
            teacherMapper.updateById(teacher);

            JwtPayload payload = JwtPayload.builder()
                    .userId(teacher.getId())
                    .username(teacher.getUsername())
                    .role(UserRole.TEACHER.getCode())
                    .tenantId(teacher.getTenantId())
                    .name(teacher.getName())
                    .build();

            String token = jwtTokenProvider.generateToken(payload);
            // 存储 token 到 Redis
            jwtTokenRedisService.storeToken(teacher.getUsername(), token, jwtTokenProvider.getExpiration());

            log.info("教师登录成功，用户名：{}", username);
            return LoginResponse.builder()
                    .token(token)
                    .userId(teacher.getId())
                    .username(teacher.getUsername())
                    .name(teacher.getName())
                    .role(UserRole.TEACHER.getCode())
                    .tenantId(teacher.getTenantId())
                    .build();
        }

        // 尝试家长登录
        Parent parent = parentMapper.selectOne(
                new LambdaQueryWrapper<Parent>().eq(Parent::getUsername, username)
        );
        if (parent != null) {
            if (!passwordEncoder.matches(password, parent.getPassword())) {
                log.warn("登录失败：密码错误，用户名：{}", username);
                throw new BusinessException(ErrorCode.INCORRECT_PASSWORD);
            }
            if (!GenericStatus.isActive(parent.getStatus())) {
                log.warn("登录失败：账户已禁用，用户名：{}", username);
                throw new BusinessException(ErrorCode.ACCOUNT_DISABLED);
            }
            // 更新最后登录时间
            parent.setLastLoginAt(LocalDateTime.now());
            parentMapper.updateById(parent);

            JwtPayload payload = JwtPayload.builder()
                    .userId(parent.getId())
                    .username(parent.getUsername())
                    .role(UserRole.PARENT.getCode())
                    .tenantId(parent.getTenantId())
                    .name(parent.getName())
                    .build();

            String token = jwtTokenProvider.generateToken(payload);
            // 存储 token 到 Redis
            jwtTokenRedisService.storeToken(parent.getUsername(), token, jwtTokenProvider.getExpiration());

            log.info("家长登录成功，用户名：{}", username);
            return LoginResponse.builder()
                    .token(token)
                    .userId(parent.getId())
                    .username(parent.getUsername())
                    .name(parent.getName())
                    .role(UserRole.PARENT.getCode())
                    .tenantId(parent.getTenantId())
                    .build();
        }

        // 尝试租户（学校）登录
        Tenant tenant = tenantMapper.selectOne(
                new LambdaQueryWrapper<Tenant>().eq(Tenant::getUsername, username)
        );
        if (tenant != null) {
            if (!passwordEncoder.matches(password, tenant.getPassword())) {
                log.warn("登录失败：密码错误，用户名：{}", username);
                throw new BusinessException(ErrorCode.INCORRECT_PASSWORD);
            }
            if (!TenantStatus.ACTIVE.getCode().equalsIgnoreCase(tenant.getStatus())) {
                log.warn("登录失败：账户已禁用，用户名：{}", username);
                throw new BusinessException(ErrorCode.ACCOUNT_DISABLED);
            }

            JwtPayload payload = JwtPayload.builder()
                    .userId(tenant.getId())
                    .username(tenant.getUsername())
                    .role(UserRole.SCHOOL.getCode())
                    .tenantId(tenant.getId())
                    .name(tenant.getName())
                    .build();

            String token = jwtTokenProvider.generateToken(payload);
            // 存储 token 到 Redis
            jwtTokenRedisService.storeToken(tenant.getUsername(), token, jwtTokenProvider.getExpiration());

            log.info("学校登录成功，用户名：{}", username);
            return LoginResponse.builder()
                    .token(token)
                    .userId(tenant.getId())
                    .username(tenant.getUsername())
                    .name(tenant.getName())
                    .role(UserRole.SCHOOL.getCode())
                    .tenantId(tenant.getId())
                    .build();
        }

        log.warn("登录失败：账号不存在，用户名：{}", username);
        throw new BusinessException(ErrorCode.ACCOUNT_NOT_FOUND);
    }

    private LoginResponse loginWithRole(String username, String password, String role) {
        UserRole userRole = UserRole.fromCode(role);

        switch (userRole) {
            case ADMIN -> {
                AdminUser adminUser = adminUserMapper.selectOne(
                        new LambdaQueryWrapper<AdminUser>().eq(AdminUser::getUsername, username)
                );
                if (adminUser == null) {
                    log.warn("登录失败：账号不存在，用户名：{}", username);
                    throw new BusinessException(ErrorCode.ACCOUNT_NOT_FOUND);
                }
                if (!passwordEncoder.matches(password, adminUser.getPassword())) {
                    log.warn("登录失败：密码错误，用户名：{}", username);
                    throw new BusinessException(ErrorCode.INCORRECT_PASSWORD);
                }
                if (!GenericStatus.isActive(adminUser.getStatus())) {
                    log.warn("登录失败：账户已禁用，用户名：{}", username);
                    throw new BusinessException(ErrorCode.ACCOUNT_DISABLED);
                }
                // 更新最后登录时间
                adminUser.setLastLoginAt(LocalDateTime.now());
                adminUserMapper.updateById(adminUser);

                JwtPayload payload = JwtPayload.builder()
                        .userId(adminUser.getId())
                        .username(adminUser.getUsername())
                        .role(UserRole.ADMIN.getCode())
                        .tenantId(null)
                        .name(adminUser.getName())
                        .build();

                String token = jwtTokenProvider.generateToken(payload);
                jwtTokenRedisService.storeToken(adminUser.getUsername(), token, jwtTokenProvider.getExpiration());

                log.info("管理员登录成功，用户名：{}", username);
                return LoginResponse.builder()
                        .token(token)
                        .userId(adminUser.getId())
                        .username(adminUser.getUsername())
                        .name(adminUser.getName())
                        .role(UserRole.ADMIN.getCode())
                        .tenantId(null)
                        .build();
            }
            case SCHOOL -> {
                Tenant tenant = tenantMapper.selectOne(
                        new LambdaQueryWrapper<Tenant>().eq(Tenant::getUsername, username)
                );
                if (tenant == null) {
                    log.warn("登录失败：账号不存在，用户名：{}", username);
                    throw new BusinessException(ErrorCode.ACCOUNT_NOT_FOUND);
                }
                if (!passwordEncoder.matches(password, tenant.getPassword())) {
                    log.warn("登录失败：密码错误，用户名：{}", username);
                    throw new BusinessException(ErrorCode.INCORRECT_PASSWORD);
                }
                if (!GenericStatus.isActive(tenant.getStatus())) {
                    log.warn("登录失败：账户已禁用，用户名：{}", username);
                    throw new BusinessException(ErrorCode.ACCOUNT_DISABLED);
                }

                JwtPayload payload = JwtPayload.builder()
                        .userId(tenant.getId())
                        .username(tenant.getUsername())
                        .role(UserRole.SCHOOL.getCode())
                        .tenantId(tenant.getId())
                        .name(tenant.getName())
                        .build();

                String token = jwtTokenProvider.generateToken(payload);
                jwtTokenRedisService.storeToken(tenant.getUsername(), token, jwtTokenProvider.getExpiration());

                log.info("学校登录成功，用户名：{}", username);
                return LoginResponse.builder()
                        .token(token)
                        .userId(tenant.getId())
                        .username(tenant.getUsername())
                        .name(tenant.getName())
                        .role(UserRole.SCHOOL.getCode())
                        .tenantId(tenant.getId())
                        .build();
            }
            case TEACHER -> {
                Teacher teacher = teacherMapper.selectOne(
                        new LambdaQueryWrapper<Teacher>().eq(Teacher::getUsername, username)
                );
                if (teacher == null) {
                    log.warn("登录失败：账号不存在，用户名：{}", username);
                    throw new BusinessException(ErrorCode.ACCOUNT_NOT_FOUND);
                }
                if (!passwordEncoder.matches(password, teacher.getPassword())) {
                    log.warn("登录失败：密码错误，用户名：{}", username);
                    throw new BusinessException(ErrorCode.INCORRECT_PASSWORD);
                }
                if (!GenericStatus.isActive(teacher.getStatus())) {
                    log.warn("登录失败：账户已禁用，用户名：{}", username);
                    throw new BusinessException(ErrorCode.ACCOUNT_DISABLED);
                }
                // 检查教师所属租户状态
                Tenant tenant = tenantMapper.selectById(teacher.getTenantId());
                if (tenant != null && TenantStatus.SUSPENDED.getCode().equalsIgnoreCase(tenant.getStatus())) {
                    log.warn("登录失败：租户服务已暂停，租户 ID: {}, 教师用户名：{}", tenant.getId(), username);
                    throw new BusinessException(ErrorCode.TENANT_SUSPENDED);
                }
                // 更新最后登录时间
                teacher.setLastLoginAt(LocalDateTime.now());
                teacherMapper.updateById(teacher);

                JwtPayload payload = JwtPayload.builder()
                        .userId(teacher.getId())
                        .username(teacher.getUsername())
                        .role(UserRole.TEACHER.getCode())
                        .tenantId(teacher.getTenantId())
                        .name(teacher.getName())
                        .build();

                String token = jwtTokenProvider.generateToken(payload);
                jwtTokenRedisService.storeToken(teacher.getUsername(), token, jwtTokenProvider.getExpiration());

                log.info("教师登录成功，用户名：{}", username);
                return LoginResponse.builder()
                        .token(token)
                        .userId(teacher.getId())
                        .username(teacher.getUsername())
                        .name(teacher.getName())
                        .role(UserRole.TEACHER.getCode())
                        .tenantId(teacher.getTenantId())
                        .build();
            }
            case PARENT -> {
                Parent parent = parentMapper.selectOne(
                        new LambdaQueryWrapper<Parent>().eq(Parent::getUsername, username)
                );
                if (parent == null) {
                    log.warn("登录失败：账号不存在，用户名：{}", username);
                    throw new BusinessException(ErrorCode.ACCOUNT_NOT_FOUND);
                }
                if (!passwordEncoder.matches(password, parent.getPassword())) {
                    log.warn("登录失败：密码错误，用户名：{}", username);
                    throw new BusinessException(ErrorCode.INCORRECT_PASSWORD);
                }
                if (!GenericStatus.isActive(parent.getStatus())) {
                    log.warn("登录失败：账户已禁用，用户名：{}", username);
                    throw new BusinessException(ErrorCode.ACCOUNT_DISABLED);
                }
                // 更新最后登录时间
                parent.setLastLoginAt(LocalDateTime.now());
                parentMapper.updateById(parent);

                JwtPayload payload = JwtPayload.builder()
                        .userId(parent.getId())
                        .username(parent.getUsername())
                        .role(UserRole.PARENT.getCode())
                        .tenantId(parent.getTenantId())
                        .name(parent.getName())
                        .build();

                String token = jwtTokenProvider.generateToken(payload);
                jwtTokenRedisService.storeToken(parent.getUsername(), token, jwtTokenProvider.getExpiration());

                log.info("家长登录成功，用户名：{}", username);
                return LoginResponse.builder()
                        .token(token)
                        .userId(parent.getId())
                        .username(parent.getUsername())
                        .name(parent.getName())
                        .role(UserRole.PARENT.getCode())
                        .tenantId(parent.getTenantId())
                        .build();
            }
            default -> throw new BusinessException(ErrorCode.ACCOUNT_NOT_FOUND);
        }
    }

    @Override
    public Object getCurrentUserInfo() {
        log.debug("获取当前用户信息");

        JwtPayload payload = SecurityUtils.getCurrentUser();
        String role = payload.getRole();

        return switch (role) {
            case "admin" -> {
                log.debug("查询管理员信息，ID: {}", payload.getUserId());
                yield adminUserMapper.selectById(payload.getUserId());
            }
            case "school" -> {
                log.debug("查询租户信息，ID: {}", payload.getUserId());
                yield tenantMapper.selectById(payload.getUserId());
            }
            case "teacher" -> {
                log.debug("查询教师信息，ID: {}", payload.getUserId());
                yield teacherMapper.selectById(payload.getUserId());
            }
            case "parent" -> {
                log.debug("查询家长信息，ID: {}", payload.getUserId());
                yield parentMapper.selectById(payload.getUserId());
            }
            default -> throw new BusinessException(ErrorCode.USER_NOT_FOUND);
        };
    }

    @Override
    public void changePassword(String oldPassword, String newPassword) {
        log.info("开始修改密码，用户 ID: {}", SecurityUtils.getCurrentUser().getUserId());

        JwtPayload payload = SecurityUtils.getCurrentUser();
        String role = payload.getRole();
        Long userId = payload.getUserId();

        switch (UserRole.fromCode(role)) {
            case ADMIN -> {
                AdminUser adminUser = adminUserMapper.selectById(userId);
                if (!passwordEncoder.matches(oldPassword, adminUser.getPassword())) {
                    log.warn("旧密码错误，用户 ID: {}", userId);
                    throw new BusinessException(ErrorCode.OLD_PASSWORD_ERROR);
                }
                adminUser.setPassword(passwordEncoder.encode(newPassword));
                adminUserMapper.updateById(adminUser);
                log.info("管理员密码修改成功，用户 ID: {}", userId);
            }
            case SCHOOL -> {
                Tenant tenant = tenantMapper.selectById(userId);
                if (!passwordEncoder.matches(oldPassword, tenant.getPassword())) {
                    log.warn("旧密码错误，用户 ID: {}", userId);
                    throw new BusinessException(ErrorCode.OLD_PASSWORD_ERROR);
                }
                tenant.setPassword(passwordEncoder.encode(newPassword));
                tenantMapper.updateById(tenant);
                log.info("租户密码修改成功，用户 ID: {}", userId);
            }
            case TEACHER -> {
                Teacher teacher = teacherMapper.selectById(userId);
                if (!passwordEncoder.matches(oldPassword, teacher.getPassword())) {
                    log.warn("旧密码错误，用户 ID: {}", userId);
                    throw new BusinessException(ErrorCode.OLD_PASSWORD_ERROR);
                }
                teacher.setPassword(passwordEncoder.encode(newPassword));
                teacherMapper.updateById(teacher);
                log.info("教师密码修改成功，用户 ID: {}", userId);
            }
            case PARENT -> {
                Parent parent = parentMapper.selectById(userId);
                if (!passwordEncoder.matches(oldPassword, parent.getPassword())) {
                    log.warn("旧密码错误，用户 ID: {}", userId);
                    throw new BusinessException(ErrorCode.OLD_PASSWORD_ERROR);
                }
                parent.setPassword(passwordEncoder.encode(newPassword));
                parentMapper.updateById(parent);
                log.info("家长密码修改成功，用户 ID: {}", userId);
            }
            default -> throw new BusinessException(ErrorCode.USER_NOT_FOUND);
        }
    }

    @Override
    public void changePassword(String oldPassword, String newPassword, String currentToken) {
        // 先修改密码
        changePassword(oldPassword, newPassword);

        // 将当前 token 加入黑名单
        if (StringUtils.hasText(currentToken)) {
            // 获取 token 剩余过期时间
            long remainingTime = jwtTokenProvider.getRemainingExpiration(currentToken);
            jwtTokenRedisService.addToBlacklist(currentToken, remainingTime);
            log.info("Token 已加入黑名单，token: {}, 剩余过期时间：{}秒", currentToken, remainingTime);
        }
    }

    @Override
    public void logout() {
        JwtPayload payload = SecurityUtils.getCurrentUser();
        log.info("用户登出，用户名：{}", payload.getUsername());

        // 将当前 token 加入黑名单（需要从请求中获取 token）
        // 注意：由于 logout 接口需要 token 才能获取到当前用户信息，
        // 所以 token 已经在 JwtAuthenticationFilter 中被解析
        // 这里我们不需要额外操作，因为 SecurityContext 中的用户信息已经证明 token 有效
    }

    @Override
    public TokenResponse refreshToken() {
        log.debug("刷新 Token");
        JwtPayload currentPayload = SecurityUtils.getCurrentUser();
        // 生成新的 token
        return TokenResponse.builder()
                .token(jwtTokenProvider.generateToken(currentPayload))
                .build();
    }

    @Override
    public UpdateProfileResponse updateProfile(UpdateProfileRequest request) {
        log.info("开始修改个人信息，用户 ID: {}", SecurityUtils.getCurrentUser().getUserId());

        JwtPayload payload = SecurityUtils.getCurrentUser();
        String role = payload.getRole();
        Long userId = payload.getUserId();

        // 根据角色更新对应表的字段
        switch (UserRole.fromCode(role)) {
            case ADMIN -> {
                AdminUser adminUser = adminUserMapper.selectById(userId);
                if (request.getName() != null) {
                    adminUser.setName(request.getName());
                }
                if (request.getPhone() != null) {
                    adminUser.setPhone(request.getPhone());
                }
                if (request.getEmail() != null) {
                    adminUser.setEmail(request.getEmail());
                }
                adminUserMapper.updateById(adminUser);
                log.info("管理员信息修改成功，用户 ID: {}", userId);
            }
            case SCHOOL -> {
                Tenant tenant = tenantMapper.selectById(userId);
                if (request.getName() != null) {
                    tenant.setContactName(request.getName());
                }
                if (request.getPhone() != null) {
                    tenant.setContactPhone(request.getPhone());
                }
                if (request.getEmail() != null) {
                    tenant.setContactEmail(request.getEmail());
                }
                tenantMapper.updateById(tenant);
                log.info("租户信息修改成功，用户 ID: {}", userId);
            }
            case TEACHER -> {
                Teacher teacher = teacherMapper.selectById(userId);
                if (request.getName() != null) {
                    teacher.setName(request.getName());
                }
                if (request.getPhone() != null) {
                    teacher.setPhone(request.getPhone());
                }
                if (request.getEmail() != null) {
                    teacher.setEmail(request.getEmail());
                }
                teacherMapper.updateById(teacher);
                log.info("教师信息修改成功，用户 ID: {}", userId);
            }
            case PARENT -> {
                Parent parent = parentMapper.selectById(userId);
                if (request.getName() != null) {
                    parent.setName(request.getName());
                }
                if (request.getPhone() != null) {
                    parent.setPhone(request.getPhone());
                }
                if (request.getEmail() != null) {
                    parent.setEmail(request.getEmail());
                }
                parentMapper.updateById(parent);
                log.info("家长信息修改成功，用户 ID: {}", userId);
            }
            default -> throw new BusinessException(ErrorCode.USER_NOT_FOUND);
        }

        // 生成新的 token
        JwtPayload currentPayload = SecurityUtils.getCurrentUser();
        String newToken = jwtTokenProvider.generateToken(currentPayload);

        // 更新 Redis 中的 token
        jwtTokenRedisService.storeToken(currentPayload.getUsername(), newToken, jwtTokenProvider.getExpiration());

        // 获取更新后的用户信息
        Object updatedUserInfo = getCurrentUserInfo();
        UserInfoResponse userInfoResponse = convertToUserInfoResponse(updatedUserInfo, role);

        return UpdateProfileResponse.builder()
                .userInfo(userInfoResponse)
                .token(newToken)
                .build();
    }

    /**
     * 将 Entity 对象转换为 UserInfoResponse
     */
    private UserInfoResponse convertToUserInfoResponse(Object userInfo, String role) {
        if (userInfo instanceof Tenant) {
            Tenant tenant = (Tenant) userInfo;
            return UserInfoResponse.builder()
                    .id(tenant.getId())
                    .username(tenant.getUsername())
                    .name(tenant.getName())
                    .email(tenant.getContactEmail())
                    .phone(tenant.getContactPhone())
                    .avatarUrl(tenant.getLogoUrl())
                    .role(UserRole.SCHOOL.getCode())
                    .tenantId(tenant.getId())
                    .build();
        } else if (userInfo instanceof Teacher) {
            Teacher teacher = (Teacher) userInfo;
            return UserInfoResponse.builder()
                    .id(teacher.getId())
                    .username(teacher.getUsername())
                    .name(teacher.getName())
                    .email(teacher.getEmail())
                    .phone(teacher.getPhone())
                    .avatarUrl(teacher.getAvatarUrl())
                    .role(UserRole.TEACHER.getCode())
                    .tenantId(teacher.getTenantId())
                    .build();
        } else if (userInfo instanceof Parent) {
            Parent parent = (Parent) userInfo;
            return UserInfoResponse.builder()
                    .id(parent.getId())
                    .username(parent.getUsername())
                    .name(parent.getName())
                    .email(parent.getEmail())
                    .phone(parent.getPhone())
                    .avatarUrl(parent.getAvatarUrl())
                    .role(UserRole.PARENT.getCode())
                    .tenantId(parent.getTenantId())
                    .build();
        } else if (userInfo instanceof AdminUser) {
            AdminUser adminUser = (AdminUser) userInfo;
            return UserInfoResponse.builder()
                    .id(adminUser.getId())
                    .username(adminUser.getUsername())
                    .name(adminUser.getName())
                    .email(adminUser.getEmail())
                    .phone(adminUser.getPhone())
                    .avatarUrl(adminUser.getAvatarUrl())
                    .role(UserRole.ADMIN.getCode())
                    .tenantId(null)
                    .build();
        }
        return null;
    }

}
