package com.zioinfo.kintex.module.m2;

import com.zioinfo.kintex.auth.EventAccessGuard;
import com.zioinfo.kintex.auth.EventRole;
import com.zioinfo.kintex.auth.KintexPrincipal;
import com.zioinfo.kintex.common.ApiResponse;
import com.zioinfo.kintex.module.m2.dto.ApplyOptionRequest;
import com.zioinfo.kintex.module.m2.dto.AutoLayoutOption;
import com.zioinfo.kintex.module.m2.dto.AutoLayoutRequest;
import com.zioinfo.kintex.module.m2.dto.LayoutDto;
import com.zioinfo.kintex.module.m2.dto.LayoutInterpretRequest;
import com.zioinfo.kintex.module.m2.dto.LayoutInterpretResult;
import com.zioinfo.kintex.module.m2.dto.LayoutSaveRequest;
import com.zioinfo.kintex.rules.ComplianceReport;
import jakarta.validation.Valid;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * M2 플로어플랜 스튜디오 API (SCR-03/04).
 * 편집 액션은 주최자(ORGANIZER) 권한, 조회는 행사 멤버·홀매니저 모두 가능(RBAC 가드).
 */
@RestController
@RequestMapping("/api/events/{eventId}/halls/{hallId}/layout")
public class FloorplanController {

    private final FloorplanService service;
    private final EventAccessGuard guard;

    public FloorplanController(FloorplanService service, EventAccessGuard guard) {
        this.service = service;
        this.guard = guard;
    }

    /** GET — 배치안 조회(version 미지정 시 최신). 행사 멤버/홀매니저 열람. */
    @GetMapping
    public ApiResponse<LayoutDto> get(@AuthenticationPrincipal KintexPrincipal principal,
                                      @PathVariable String eventId,
                                      @PathVariable String hallId,
                                      @RequestParam(required = false) Integer version) {
        guard.requireEventAccess(principal, eventId);
        return ApiResponse.ok(service.getLayout(eventId, hallId, version));
    }

    /** PUT — 배치 저장(주최자). */
    @PutMapping
    public ApiResponse<LayoutDto> save(@AuthenticationPrincipal KintexPrincipal principal,
                                       @PathVariable String eventId,
                                       @PathVariable String hallId,
                                       @Valid @RequestBody LayoutSaveRequest request) {
        guard.requireRole(principal, eventId, EventRole.ORGANIZER);
        return ApiResponse.ok(service.saveLayout(eventId, hallId, request));
    }

    /** POST /validate — 규정 검증 실행(주최자/홀매니저). 차단 존재 시 submittable=false. */
    @PostMapping("/validate")
    public ApiResponse<ComplianceReport> validate(@AuthenticationPrincipal KintexPrincipal principal,
                                                  @PathVariable String eventId,
                                                  @PathVariable String hallId,
                                                  @RequestParam(required = false) Integer version) {
        guard.requireRole(principal, eventId, EventRole.ORGANIZER, EventRole.HALL_MANAGER);
        return ApiResponse.ok(service.validate(eventId, hallId, version));
    }

    /**
     * POST /auto-generate/interpret — 자연어 조건 해석(주최자).
     * 문장 → AutoLayoutRequest 파싱(AI, 서버 권위 클램핑). AI 불가/파싱 실패는 degraded=true 로 강등(프론트 수동 폼 폴백).
     */
    @PostMapping("/auto-generate/interpret")
    public ApiResponse<LayoutInterpretResult> interpret(
            @AuthenticationPrincipal KintexPrincipal principal,
            @PathVariable String eventId,
            @PathVariable String hallId,
            @Valid @RequestBody LayoutInterpretRequest request) {
        guard.requireRole(principal, eventId, EventRole.ORGANIZER);
        return ApiResponse.ok(service.interpret(eventId, hallId, request.text()));
    }

    /**
     * POST /auto-generate — AI 자동배치 복수 안(주최자).
     * @param ai true 면 각 안에 엔진 metrics 근거 AI 장단점 요약을 부가(실패 시 요약만 생략, 배치는 항상 성공).
     */
    @PostMapping("/auto-generate")
    public ApiResponse<List<AutoLayoutOption>> autoGenerate(
            @AuthenticationPrincipal KintexPrincipal principal,
            @PathVariable String eventId,
            @PathVariable String hallId,
            @RequestParam(required = false, defaultValue = "false") boolean ai,
            @Valid @RequestBody AutoLayoutRequest request) {
        guard.requireRole(principal, eventId, EventRole.ORGANIZER);
        return ApiResponse.ok(service.autoGenerate(eventId, hallId, request, ai));
    }

    /** POST /apply-option — 자동배치 안 선택/병합 적용(주최자). 새 버전 저장 + 규정 재검증. */
    @PostMapping("/apply-option")
    public ApiResponse<LayoutDto> applyOption(@AuthenticationPrincipal KintexPrincipal principal,
                                              @PathVariable String eventId,
                                              @PathVariable String hallId,
                                              @Valid @RequestBody ApplyOptionRequest request) {
        guard.requireRole(principal, eventId, EventRole.ORGANIZER);
        return ApiResponse.ok(service.applyOption(eventId, hallId, request));
    }
}
