package com.tasteby.controller;

import com.tasteby.domain.SiteVisitStats;
import com.tasteby.service.RateLimitService;
import com.tasteby.service.StatsService;
import com.tasteby.util.BotDetector;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("/api/stats")
public class StatsController {

    private static final Logger log = LoggerFactory.getLogger(StatsController.class);

    private final StatsService statsService;
    private final RateLimitService rateLimitService;

    public StatsController(StatsService statsService, RateLimitService rateLimitService) {
        this.statsService = statsService;
        this.rateLimitService = rateLimitService;
    }

    @PostMapping("/visit")
    public Map<String, Object> recordVisit(HttpServletRequest req) {
        // #337 — 봇 UA + IP 레이트리밋. 모두 통과해야 카운트 진행.
        String ua = req.getHeader("User-Agent");
        if (BotDetector.isBot(ua)) {
            log.debug("visit skipped (bot): {}", ua);
            return Map.of("ok", true, "counted", false);
        }

        String clientIp = resolveClientIp(req);
        if (!rateLimitService.tryConsume(clientIp)) {
            log.debug("visit skipped (rate-limit): {}", clientIp);
            return Map.of("ok", true, "counted", false);
        }

        statsService.recordVisit();
        return Map.of("ok", true, "counted", true);
    }

    @GetMapping("/visits")
    public SiteVisitStats getVisits() {
        return statsService.getVisits();
    }

    /**
     * #337 — X-Forwarded-For 우선 (Nginx Ingress 뒤). chain이면 첫 번째(원본).
     * 없으면 RemoteAddr 폴백.
     */
    private static String resolveClientIp(HttpServletRequest req) {
        String fwd = req.getHeader("X-Forwarded-For");
        if (fwd != null && !fwd.isBlank()) {
            int comma = fwd.indexOf(',');
            return (comma > 0 ? fwd.substring(0, comma) : fwd).trim();
        }
        String addr = req.getRemoteAddr();
        return addr != null ? addr : "unknown";
    }
}
