package com.pandoli365.bibimbap.controller;

import com.pandoli365.bibimbap.data.JamData;
import com.pandoli365.bibimbap.jam.JamAwardService;
import com.pandoli365.bibimbap.mapper.JamsMapper;
import com.pandoli365.bibimbap.security.CsrfTokens;
import com.pandoli365.bibimbap.security.PermissionGate;
import com.pandoli365.bibimbap.security.PermissionKeys;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.time.OffsetDateTime;
import java.util.LinkedHashMap;
import java.util.Map;

@Controller
public class JamAwardAdminController {

    private final JamsMapper jamsMapper;
    private final PermissionGate gate;
    private final JamAwardService jamAwardService;

    public JamAwardAdminController(JamsMapper jamsMapper,
                                   PermissionGate gate,
                                   JamAwardService jamAwardService) {
        this.jamsMapper = jamsMapper;
        this.gate = gate;
        this.jamAwardService = jamAwardService;
    }

    @PostMapping("/admin/jams/{jamId}/awards/compute")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> computeAwards(
            @PathVariable("jamId") long jamId,
            HttpServletRequest request,
            HttpSession session) {
        ResponseEntity<Map<String, Object>> denied = requireJamManage(session);
        if (denied != null) {
            return denied;
        }
        if (!CsrfTokens.isValid(request)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(CsrfTokens.errorBody());
        }
        JamData jam = jamsMapper.getById(jamId);
        if (jam == null) {
            return response(HttpStatus.NOT_FOUND, "게임잼을 찾을 수 없습니다.");
        }

        boolean evalEnded = jam.getEvalEndAt() != null && OffsetDateTime.now().isAfter(jam.getEvalEndAt());
        boolean computable = "CLOSED".equals(jam.getStatus()) || evalEnded;
        if (!computable) {
            return response(HttpStatus.UNPROCESSABLE_ENTITY, "시상 산정 가능 상태가 아닙니다.");
        }

        Map<String, Integer> awardCounts = jamAwardService.recompute(jam.getId());

        Map<String, Object> body = new LinkedHashMap<>();
        body.put("status", HttpStatus.OK.value());
        body.put("message", "시상을 산정했습니다.");
        body.put("jamId", jam.getId());
        body.put("awardCounts", awardCounts);
        return ResponseEntity.ok(body);
    }

    private ResponseEntity<Map<String, Object>> requireJamManage(HttpSession session) {
        if (!gate.isAuthenticated(session)) {
            return response(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.");
        }
        if (!gate.has(session, PermissionKeys.GAME_JAM_MANAGE.name())) {
            return response(HttpStatus.FORBIDDEN, "권한이 없습니다.");
        }
        return null;
    }

    private ResponseEntity<Map<String, Object>> response(HttpStatus status, String message) {
        Map<String, Object> body = new LinkedHashMap<>();
        body.put("status", status.value());
        body.put("message", message);
        return ResponseEntity.status(status).body(body);
    }
}
