package com.zioinfo.kintex.auth.profile;

import com.zioinfo.kintex.auth.EventAccessGuard;
import com.zioinfo.kintex.auth.KintexPrincipal;
import com.zioinfo.kintex.auth.profile.dto.PhotoBase64Request;
import com.zioinfo.kintex.auth.profile.dto.PhotoUploadResponse;
import com.zioinfo.kintex.common.ApiResponse;
import com.zioinfo.kintex.common.audit.Audited;
import jakarta.validation.Valid;
import org.springframework.http.CacheControl;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.time.Duration;

/**
 * 프로필 사진 API — 모바일 내정보(SCR-M) 아바타 계약(단일 창구).
 * <ul>
 *   <li>업로드: {@code POST /api/auth/profile/photo} (본인 · multipart {@code file} 또는 base64 JSON) → {@code { photoUrl }}</li>
 *   <li>서빙:   {@code GET  /api/auth/users/{userId}/photo} (인증 · 없으면 404) — 바이트 스트림 + 캐시 헤더</li>
 * </ul>
 * 인증 경로는 SecurityConfig 의 {@code anyRequest().authenticated()} 로 보호된다(별도 permitAll 없음).
 */
@RestController
@RequestMapping("/api/auth")
public class ProfilePhotoController {

    private final ProfilePhotoService service;
    private final EventAccessGuard guard;

    public ProfilePhotoController(ProfilePhotoService service, EventAccessGuard guard) {
        this.service = service;
        this.guard = guard;
    }

    /** 업로드(멀티파트) — 본인 사진만. userId 는 항상 principal 에서 온다(경로/폼 파라미터 미수용). */
    @Audited(action = "PROFILE_PHOTO_UPLOAD", targetType = "app_user")
    @PostMapping(value = "/profile/photo", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ApiResponse<PhotoUploadResponse> upload(@AuthenticationPrincipal KintexPrincipal principal,
                                                   @RequestPart("file") MultipartFile file) {
        guard.require(principal);
        String url = service.upload(principal.userId(), file);
        return ApiResponse.ok(new PhotoUploadResponse(url));
    }

    /** 업로드(base64 JSON 대체안) — 멀티파트 곤란 단말용. */
    @Audited(action = "PROFILE_PHOTO_UPLOAD", targetType = "app_user")
    @PostMapping(value = "/profile/photo", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ApiResponse<PhotoUploadResponse> uploadBase64(@AuthenticationPrincipal KintexPrincipal principal,
                                                         @Valid @RequestBody PhotoBase64Request req) {
        guard.require(principal);
        String url = service.uploadBase64(principal.userId(), req.base64(), req.mimeType());
        return ApiResponse.ok(new PhotoUploadResponse(url));
    }

    /** 서빙 — 인증 사용자면 조회 가능(멤버 목록·아바타 표시). 없으면 404(이니셜 폴백). */
    @GetMapping("/users/{userId}/photo")
    public ResponseEntity<byte[]> photo(@AuthenticationPrincipal KintexPrincipal principal,
                                        @PathVariable String userId) {
        guard.require(principal);
        ProfilePhotoService.StoredPhoto photo = service.load(userId);
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(photo.contentType()))
                .cacheControl(CacheControl.maxAge(Duration.ofHours(1)).cachePrivate())
                .body(photo.bytes());
    }
}
