package com.zioinfo.kintex.cms;

import com.zioinfo.kintex.auth.EventAccessGuard;
import com.zioinfo.kintex.auth.KintexPrincipal;
import com.zioinfo.kintex.cms.dto.CmsContentCreateRequest;
import com.zioinfo.kintex.cms.dto.CmsContentDto;
import com.zioinfo.kintex.cms.dto.CmsContentUpdateRequest;
import com.zioinfo.kintex.cms.dto.CmsAiTranslateResult;
import com.zioinfo.kintex.cms.dto.CmsContentVersionDto;
import com.zioinfo.kintex.cms.dto.CmsTranslationDto;
import com.zioinfo.kintex.cms.dto.CmsTranslationSaveRequest;
import com.zioinfo.kintex.common.ApiResponse;
import com.zioinfo.kintex.common.PageResponse;
import com.zioinfo.kintex.common.audit.Audited;
import jakarta.validation.Valid;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * M17 CMS 콘텐츠 API (SCR-35·37). 인증 필수.
 * <ul>
 *   <li>GET/POST /api/cms/contents — 목록/신규(초안)</li>
 *   <li>GET/PUT /api/cms/contents/&#123;id&#125; — 상세/본문 저장(sanitize·버전 스냅샷)</li>
 *   <li>PATCH /api/cms/contents/&#123;id&#125;/status?value= — 게시 전이(전진만·역전이 400, 승인/게시는 매니저↑)</li>
 *   <li>GET /api/cms/contents/&#123;id&#125;/versions · POST …/rollback?versionNo= — 버전 이력/롤백(매니저↑)</li>
 *   <li>GET/PUT /api/cms/contents/&#123;id&#125;/translations · POST …/translations/ai?lang= — 번역 upsert / AI 초벌(실배선·degraded 폴백)</li>
 * </ul>
 */
@RestController
@RequestMapping("/api/cms/contents")
public class CmsContentController {

    private final CmsService service;
    private final EventAccessGuard guard;

    public CmsContentController(CmsService service, EventAccessGuard guard) {
        this.service = service;
        this.guard = guard;
    }

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

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

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

    /** 본문/제목/예약 저장 — sanitize(XSS N2) + 버전 스냅샷. */
    @Audited(action = "CMS_CONTENT_EDIT", targetType = "cms_content")
    @PutMapping("/{id}")
    public ApiResponse<CmsContentDto> update(@AuthenticationPrincipal KintexPrincipal principal,
                                             @PathVariable String id,
                                             @Valid @RequestBody CmsContentUpdateRequest req) {
        guard.require(principal);
        return ApiResponse.ok(service.update(principal, id, req));
    }

    /** 게시 상태 전이. value=draft|review|approved|published(전진만). 역전이/무효 → 400. */
    @Audited(action = "CMS_CONTENT_TRANSITION", targetType = "cms_content")
    @PatchMapping("/{id}/status")
    public ApiResponse<CmsContentDto> transition(@AuthenticationPrincipal KintexPrincipal principal,
                                                 @PathVariable String id,
                                                 @RequestParam String value) {
        guard.require(principal);
        return ApiResponse.ok(service.transition(principal, id, value));
    }

    /** 버전 이력(최신순). */
    @GetMapping("/{id}/versions")
    public ApiResponse<List<CmsContentVersionDto>> versions(
            @AuthenticationPrincipal KintexPrincipal principal,
            @PathVariable String id) {
        guard.require(principal);
        return ApiResponse.ok(service.versions(id));
    }

    /** 특정 버전으로 롤백(매니저↑). 복원 후 롤백 스냅샷을 새 버전으로 남긴다. */
    @Audited(action = "CMS_CONTENT_ROLLBACK", targetType = "cms_content")
    @PostMapping("/{id}/rollback")
    public ApiResponse<CmsContentDto> rollback(@AuthenticationPrincipal KintexPrincipal principal,
                                               @PathVariable String id,
                                               @RequestParam int versionNo) {
        guard.require(principal);
        return ApiResponse.ok(service.rollback(principal, id, versionNo));
    }

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

    @PutMapping("/{id}/translations")
    public ApiResponse<List<CmsTranslationDto>> saveTranslation(
            @AuthenticationPrincipal KintexPrincipal principal,
            @PathVariable String id,
            @Valid @RequestBody CmsTranslationSaveRequest req) {
        guard.require(principal);
        return ApiResponse.ok(service.saveTranslation(id, req));
    }

    /**
     * AI 자동 번역(초벌) — AiTextRouter 로 원문→대상언어(en/zh/ja) 번역, trans_status='ai' 저장(매니저↑).
     * AI 미가용/파싱 실패 시 500 대신 {@code degraded=true} 결과(HTTP 200) — 프론트는 "AI 준비 중"으로 처리
     * (환각 없이 저장 안 함). 대상 언어 화이트리스트·입력 길이 상한은 서버가 강제(초과 시 400).
     */
    @Audited(action = "CMS_AI_TRANSLATE", targetType = "cms_translation")
    @PostMapping("/{id}/translations/ai")
    public ApiResponse<CmsAiTranslateResult> aiTranslate(
            @AuthenticationPrincipal KintexPrincipal principal,
            @PathVariable String id,
            @RequestParam String lang) {
        guard.require(principal);
        return ApiResponse.ok(service.aiTranslate(principal, id, lang));
    }
}
