package com.zioinfo.kintex.work.meeting;

import com.zioinfo.kintex.auth.EventAccessGuard;
import com.zioinfo.kintex.auth.KintexPrincipal;
import com.zioinfo.kintex.common.ApiResponse;
import com.zioinfo.kintex.common.PageResponse;
import jakarta.validation.Valid;
import org.springframework.http.MediaType;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/** 회의 API (/api/work/meetings). 인증 사용자. 편집·회의록·삭제는 주최자(서비스에서 검증). */
@RestController
@RequestMapping("/api/work/meetings")
public class MeetingController {

    private final MeetingService service;
    private final EventAccessGuard guard;

    public MeetingController(MeetingService service, EventAccessGuard guard) {
        this.service = service;
        this.guard = guard;
    }

    @GetMapping
    public ApiResponse<PageResponse<MeetingDto>> list(@AuthenticationPrincipal KintexPrincipal principal,
                                                      @RequestParam(required = false) String eventId,
                                                      @RequestParam(defaultValue = "0") int page,
                                                      @RequestParam(defaultValue = "20") int size) {
        guard.require(principal);
        return ApiResponse.ok(service.list(eventId, page, size));
    }

    @GetMapping("/{id}")
    public ApiResponse<MeetingDetail> get(@AuthenticationPrincipal KintexPrincipal principal,
                                          @PathVariable String id) {
        guard.require(principal);
        return ApiResponse.ok(service.get(id));
    }

    @PostMapping
    public ApiResponse<MeetingDto> create(@AuthenticationPrincipal KintexPrincipal principal,
                                          @Valid @RequestBody MeetingSaveRequest req) {
        guard.require(principal);
        return ApiResponse.ok(service.create(principal, req));
    }

    @PutMapping("/{id}")
    public ApiResponse<MeetingDto> update(@AuthenticationPrincipal KintexPrincipal principal,
                                          @PathVariable String id,
                                          @Valid @RequestBody MeetingSaveRequest req) {
        guard.require(principal);
        return ApiResponse.ok(service.update(principal, id, req));
    }

    @PutMapping("/{id}/minutes")
    public ApiResponse<Void> minutes(@AuthenticationPrincipal KintexPrincipal principal,
                                     @PathVariable String id, @RequestBody MinutesRequest req) {
        guard.require(principal);
        service.saveMinutes(id, req.minutes(), req.transcript());
        return ApiResponse.ok(null);
    }

    // ── G-06 녹음 STT · AI 회의록 자동작성 ────────────────────────────

    /** 녹음 파일 업로드(multipart, ≤20MB) → audioId 일회성 토큰. */
    @PostMapping(value = "/audio", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ApiResponse<AudioUploadResponse> uploadAudio(@AuthenticationPrincipal KintexPrincipal principal,
                                                        @RequestPart("file") MultipartFile file) {
        guard.require(principal);
        return ApiResponse.ok(service.uploadAudio(file));
    }

    /** STT — audioId 전사 시도(온프레미스). 불가 시 degraded=true·빈 전사(수동 입력 유도). */
    @PostMapping("/stt")
    public ApiResponse<SttResponse> stt(@AuthenticationPrincipal KintexPrincipal principal,
                                        @Valid @RequestBody SttRequest req) {
        guard.require(principal);
        return ApiResponse.ok(service.stt(req.audioId()));
    }

    /** AI 회의록 자동작성 — 전사/수동 텍스트 → 요약·결정·액션(Claude, degraded 폴백). */
    @PostMapping("/minutes/generate")
    public ApiResponse<GeneratedMinutes> generateMinutes(@AuthenticationPrincipal KintexPrincipal principal,
                                                         @Valid @RequestBody MinutesGenerateRequest req) {
        guard.require(principal);
        return ApiResponse.ok(service.generateMinutes(req));
    }

    /** 액션아이템 일괄 저장 — AI 추출분 확인 후 한 번에 등록. 저장된 전체 목록 반환. */
    @PostMapping("/{id}/actions/bulk")
    public ApiResponse<List<MeetingActionDto>> addActionsBulk(@AuthenticationPrincipal KintexPrincipal principal,
                                                              @PathVariable String id,
                                                              @RequestBody List<MinutesActionDraft> items) {
        guard.require(principal);
        return ApiResponse.ok(service.addActionsBulk(id, items));
    }

    @PostMapping("/{id}/actions")
    public ApiResponse<MeetingActionDto> addAction(@AuthenticationPrincipal KintexPrincipal principal,
                                                   @PathVariable String id,
                                                   @Valid @RequestBody MeetingActionRequest req) {
        guard.require(principal);
        return ApiResponse.ok(service.addAction(id, req));
    }

    @PatchMapping("/actions/{actionId}/status")
    public ApiResponse<Void> actionStatus(@AuthenticationPrincipal KintexPrincipal principal,
                                          @PathVariable String actionId, @RequestParam String value) {
        guard.require(principal);
        service.updateActionStatus(actionId, value);
        return ApiResponse.ok(null);
    }

    @DeleteMapping("/{id}")
    public ApiResponse<Void> delete(@AuthenticationPrincipal KintexPrincipal principal,
                                    @PathVariable String id) {
        guard.require(principal);
        service.delete(principal, id);
        return ApiResponse.ok(null);
    }
}
