package com.zioinfo.kintex.auth;

import com.zioinfo.kintex.auth.dto.ChangePasswordRequest;
import com.zioinfo.kintex.auth.dto.MeResponse;
import com.zioinfo.kintex.auth.dto.NotificationPrefsDto;
import com.zioinfo.kintex.auth.dto.ProfileUpdateRequest;
import com.zioinfo.kintex.common.ApiResponse;
import com.zioinfo.kintex.common.audit.Audited;
import jakarta.validation.Valid;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

/**
 * 마이페이지(SCR-48) 계정 설정 API — 프로필 수정·비밀번호 변경·알림 설정(GAP G-08).
 * <ul>
 *   <li>{@code PUT  /api/auth/me}                    — 프로필 수정(displayName·phone 화이트리스트) → {@link MeResponse}</li>
 *   <li>{@code POST /api/auth/me/password}           — 비밀번호 변경(현재 비밀번호 검증)</li>
 *   <li>{@code GET  /api/auth/me/notification-prefs} — 알림 설정 조회</li>
 *   <li>{@code PUT  /api/auth/me/notification-prefs} — 알림 설정 저장(멱등)</li>
 * </ul>
 * 대상은 항상 인증 principal 본인이다(요청 본문/경로로 userId 미수용). {@code GET /api/auth/me} 는
 * 기존 {@link AuthController} 소관(회귀 0) — 여기서는 <b>변경(mutation)</b>만 담당한다.
 */
@RestController
@RequestMapping("/api/auth/me")
public class AccountSettingsController {

    private final AccountSettingsService service;
    private final EventAccessGuard guard;

    public AccountSettingsController(AccountSettingsService service, EventAccessGuard guard) {
        this.service = service;
        this.guard = guard;
    }

    /** 프로필 수정 — 본인만. email·role·dept 는 이 경로로 변경 불가(서버 화이트리스트). */
    @Audited(action = "PROFILE_UPDATE", targetType = "app_user")
    @PutMapping
    public ApiResponse<MeResponse> updateProfile(@AuthenticationPrincipal KintexPrincipal principal,
                                                 @Valid @RequestBody ProfileUpdateRequest req) {
        guard.require(principal);
        return ApiResponse.ok(service.updateProfile(principal, req));
    }

    /** 비밀번호 변경 — 현재 비밀번호 검증 후 갱신. 본문(원문)은 감사/로그 미기록(계약 §0-3). */
    @Audited(action = "PASSWORD_CHANGE", targetType = "app_user")
    @PostMapping("/password")
    public ApiResponse<Void> changePassword(@AuthenticationPrincipal KintexPrincipal principal,
                                            @Valid @RequestBody ChangePasswordRequest req) {
        guard.require(principal);
        service.changePassword(principal, req);
        return ApiResponse.ok(null);
    }

    /** 알림 설정 조회 — 미설정 시 서버 기본값. */
    @GetMapping("/notification-prefs")
    public ApiResponse<NotificationPrefsDto> getNotificationPrefs(
            @AuthenticationPrincipal KintexPrincipal principal) {
        guard.require(principal);
        return ApiResponse.ok(service.getNotificationPrefs(principal));
    }

    /** 알림 설정 저장(멱등) — 저장값 반환. */
    @Audited(action = "NOTIFICATION_PREF_SAVE", targetType = "app_user")
    @PutMapping("/notification-prefs")
    public ApiResponse<NotificationPrefsDto> saveNotificationPrefs(
            @AuthenticationPrincipal KintexPrincipal principal,
            @Valid @RequestBody NotificationPrefsDto req) {
        guard.require(principal);
        return ApiResponse.ok(service.saveNotificationPrefs(principal, req));
    }
}
