package com.lesingle.edu.controller;

import com.lesingle.edu.common.annotation.Log;
import com.lesingle.edu.common.enums.LogModule;
import com.lesingle.edu.common.enums.LogOperationType;
import com.lesingle.edu.common.mapper.AdminUserMapper;
import com.lesingle.edu.common.mapper.ParentMapper;
import com.lesingle.edu.common.mapper.TenantMapper;
import com.lesingle.edu.common.mapper.TeacherMapper;
import com.lesingle.edu.common.response.Result;
import com.lesingle.edu.common.util.RsaEncryptionUtil;
import com.lesingle.edu.dto.request.EncryptedLoginRequest;
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.PublicKeyResponse;
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.service.AuthService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

@Tag(name = "认证管理", description = "Authentication APIs")
@RestController
@RequestMapping("/api/v1/auth")
@RequiredArgsConstructor
public class AuthController {

    private final AuthService authService;
    private final TenantMapper tenantMapper;
    private final TeacherMapper teacherMapper;
    private final ParentMapper parentMapper;
    private final AdminUserMapper adminUserMapper;
    private final RsaEncryptionUtil rsaEncryptionUtil;

    @Operation(summary = "获取 RSA 公钥")
    @GetMapping("/public-key")
    public Result<PublicKeyResponse> getPublicKey() {
        PublicKeyResponse response = new PublicKeyResponse();
        response.setPublicKey(rsaEncryptionUtil.getPublicKey());
        response.setKeyVersion(rsaEncryptionUtil.getKeyVersion());
        return Result.success(response);
    }

    @Operation(summary = "加密登录（RSA）")
    @Log(module = LogModule.AUTH, type = LogOperationType.OTHER, description = "用户加密登录")
    @PostMapping("/login/encrypted")
    public Result<LoginResponse> loginEncrypted(@Valid @RequestBody EncryptedLoginRequest request) {
        // 解密密码
        String decryptedPassword;
        try {
            decryptedPassword = rsaEncryptionUtil.decrypt(request.getEncryptedPassword());
        } catch (Exception e) {
            return Result.error("密码解密失败，请重试");
        }

        // 构造普通登录请求
        LoginRequest loginRequest = new LoginRequest();
        loginRequest.setUsername(request.getUsername());
        loginRequest.setPassword(decryptedPassword);
        loginRequest.setRole(request.getRole());

        return Result.success(authService.login(loginRequest));
    }

    @Operation(summary = "用户登录")
    @Log(module = LogModule.AUTH, type = LogOperationType.OTHER, description = "用户登录")
    @PostMapping("/login")
    public Result<LoginResponse> login(@Valid @RequestBody LoginRequest request) {
        return Result.success(authService.login(request));
    }

    @Operation(summary = "用户登出")
    @Log(module = LogModule.AUTH, type = LogOperationType.OTHER, description = "用户登出")
    @PostMapping("/logout")
    public Result<Void> logout() {
        authService.logout();
        return Result.success();
    }

    @Operation(summary = "刷新 Token")
    @PostMapping("/refresh")
    public Result<TokenResponse> refreshToken() {
        return Result.success(authService.refreshToken());
    }

    @Operation(summary = "获取当前用户信息")
    @GetMapping("/profile")
    public Result<UserInfoResponse> getCurrentUser() {
        Object userInfo = authService.getCurrentUserInfo();
        UserInfoResponse response = convertToUserInfoResponse(userInfo);
        return Result.success(response);
    }

    @Operation(summary = "修改密码")
    @Log(module = LogModule.AUTH, type = LogOperationType.UPDATE, description = "修改密码", recordParams = false)
    @PostMapping("/change-password")
    public Result<Void> changePassword(
            @RequestParam String oldPassword,
            @RequestParam String newPassword,
            HttpServletRequest request) {
        String token = resolveToken(request);
        authService.changePassword(oldPassword, newPassword, token);
        return Result.success();
    }

    @Operation(summary = "修改个人信息")
    @Log(module = LogModule.AUTH, type = LogOperationType.UPDATE, description = "修改个人信息")
    @PutMapping("/profile")
    public Result<UpdateProfileResponse> updateProfile(
            @Valid @RequestBody UpdateProfileRequest request) {
        UpdateProfileResponse response = authService.updateProfile(request);
        return Result.success(response);
    }

    private UserInfoResponse convertToUserInfoResponse(Object userInfo) {
        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("school")
                    .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("teacher")
                    .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("parent")
                    .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("admin")
                    .tenantId(null)
                    .build();
        }
        return null;
    }

    /**
     * 从请求头获取 token
     */
    private String resolveToken(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }

}
