package com.lesingle.modules.sys.controller;

import com.lesingle.common.constants.CacheConstants;
import com.lesingle.common.result.Result;
import com.lesingle.common.util.SecurityUtil;
import com.lesingle.modules.sys.dto.LoginDto;
import com.lesingle.modules.sys.service.AuthService;
import com.lesingle.security.annotation.Public;
import com.lesingle.security.util.JwtUtil;
import io.jsonwebtoken.Claims;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Tag(name = "认证管理")
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {

    private final AuthService authService;
    private final JwtUtil jwtUtil;
    private final StringRedisTemplate redisTemplate;

    @Public
    @PostMapping("/login")
    @Operation(summary = "登录")
    public Result<Map<String, Object>> login(@Valid @RequestBody LoginDto dto, HttpServletRequest request) {
        // 优先从请求头获取租户 ID，其次从 body 的 tenantCode 查找
        String tenantIdHeader = request.getHeader("X-Tenant-Id");
        Long tenantId = tenantIdHeader != null && !tenantIdHeader.isBlank() ? Long.parseLong(tenantIdHeader) : null;

        return Result.success(authService.login(dto.getUsername(), dto.getPassword(), tenantId, dto.getTenantCode()));
    }

    @GetMapping("/user-info")
    @Operation(summary = "获取当前用户信息")
    public Result<Map<String, Object>> getUserInfo() {
        Long userId = SecurityUtil.getCurrentUserId();
        return Result.success(authService.getUserInfo(userId));
    }

    @PostMapping("/logout")
    @Operation(summary = "登出")
    public Result<Map<String, String>> logout(HttpServletRequest request) {
        String token = extractToken(request);
        if (StringUtils.hasText(token)) {
            try {
                Claims claims = jwtUtil.parseToken(token);
                // 计算 Token 剩余有效时间（毫秒）
                Date expiration = claims.getExpiration();
                long ttl = expiration.getTime() - System.currentTimeMillis();
                if (ttl > 0) {
                    // 将 Token 加入黑名单，过期时间与 Token 剩余有效期一致
                    String blacklistKey = CacheConstants.TOKEN_BLACKLIST_PREFIX + token;
                    redisTemplate.opsForValue().set(blacklistKey, "1", ttl, TimeUnit.MILLISECONDS);
                    log.info("Token 已加入黑名单，用户ID：{}，TTL：{}ms", claims.getSubject(), ttl);
                }
            } catch (Exception e) {
                log.debug("登出时 Token 解析失败（可能已过期）：{}", e.getMessage());
            }
        }
        return Result.success(Map.of("message", "登出成功"));
    }

    private String extractToken(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }
}
