package com.example.scaffold.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.example.scaffold.security.jwt.JwtUtil;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * 认证控制器 - 支持 JWT 和 Sa-Token
 * 
 * 学习要点：
 * 1. 登录认证流程
 * 2. Token 生成与刷新
 * 3. 登出处理
 */
@Slf4j
@RestController
@RequestMapping("/api/auth")
public class AuthController {
    
    private final JwtUtil jwtUtil;
    private final AuthenticationManager authenticationManager;

    public AuthController(JwtUtil jwtUtil, ObjectProvider<AuthenticationManager> authenticationManagerProvider) {
        this.jwtUtil = jwtUtil;
        this.authenticationManager = authenticationManagerProvider.getIfAvailable();
    }
    
    @Value("${auth.type:none}")
    private String authType;
    
    /**
     * 登录 - 支持多种认证方式
     */
    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest request) {
        log.info("🔐 用户登录: username={}, authType={}", request.getUsername(), authType);
        
        return switch (authType) {
            case "jwt" -> jwtLogin(request);
            case "satoken" -> saTokenLogin(request);
            default -> demoLogin(request);
        };
    }
    
    /**
     * JWT 登录
     */
    private ResponseEntity<?> jwtLogin(LoginRequest request) {
        if (authenticationManager == null) {
            return ResponseEntity.status(503).body(Map.of(
                "success", false,
                "message", "当前 profile 未启用 JWT AuthenticationManager，请切到 advanced 或 auth.type=jwt"
            ));
        }
        try {
            Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                    request.getUsername(),
                    request.getPassword()
                )
            );
            
            SecurityContextHolder.getContext().setAuthentication(authentication);
            
            // 生成 JWT Token
            String token = jwtUtil.generateToken(1L, request.getUsername(), "USER");
            
            return ResponseEntity.ok(Map.of(
                "success", true,
                "token", token,
                "type", "Bearer",
                "username", request.getUsername()
            ));
        } catch (Exception e) {
            return ResponseEntity.status(401).body(Map.of(
                "success", false,
                "message", "用户名或密码错误"
            ));
        }
    }
    
    /**
     * Sa-Token 登录
     */
    private ResponseEntity<?> saTokenLogin(LoginRequest request) {
        // 简单校验（实际应从数据库校验）
        if ("admin".equals(request.getUsername()) && "admin123".equals(request.getPassword())) {
            StpUtil.login(10001);
            return ResponseEntity.ok(Map.of(
                "success", true,
                "token", StpUtil.getTokenValue(),
                "type", "satoken",
                "username", request.getUsername()
            ));
        }
        
        return ResponseEntity.status(401).body(Map.of(
            "success", false,
            "message", "用户名或密码错误"
        ));
    }
    
    /**
     * 演示登录（无认证）
     */
    private ResponseEntity<?> demoLogin(LoginRequest request) {
        return ResponseEntity.ok(Map.of(
            "success", true,
            "message", "演示模式，无需认证",
            "username", request.getUsername()
        ));
    }
    
    /**
     * 登出
     */
    @PostMapping("/logout")
    public ResponseEntity<?> logout() {
        if ("satoken".equals(authType)) {
            StpUtil.logout();
        }
        SecurityContextHolder.clearContext();
        return ResponseEntity.ok(Map.of("success", true, "message", "登出成功"));
    }
    
    /**
     * 获取当前登录用户信息
     */
    @GetMapping("/info")
    public ResponseEntity<?> getCurrentUser() {
        if ("satoken".equals(authType) && StpUtil.isLogin()) {
            return ResponseEntity.ok(Map.of(
                "loggedIn", true,
                "userId", StpUtil.getLoginId(),
                "authType", authType
            ));
        }
        
        return ResponseEntity.ok(Map.of(
            "loggedIn", false,
            "authType", authType
        ));
    }
    
    /**
     * 刷新 Token（JWT）
     */
    @PostMapping("/refresh")
    public ResponseEntity<?> refreshToken(@RequestHeader("Authorization") String authHeader) {
        if (!authHeader.startsWith("Bearer ")) {
            return ResponseEntity.badRequest().body(Map.of("error", "无效的 Token 格式"));
        }
        
        String token = authHeader.substring(7);
        if (!jwtUtil.validateToken(token)) {
            return ResponseEntity.status(401).body(Map.of("error", "Token 无效或已过期"));
        }
        
        String newToken = jwtUtil.refreshToken(token);
        return ResponseEntity.ok(Map.of("token", newToken));
    }
    
    @Data
    public static class LoginRequest {
        private String username;
        private String password;
    }
}