package kr.itn.itnhub.config;

import kr.itn.itnhub.seed.SeedParseException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 운영자의 흔한 실수를 서버 장애(500)가 아니라 4xx로 돌려준다.
 *
 * <p>{@link IllegalArgumentException}은 {@code OrganizationService.updateContact}와
 * {@code ChannelProvisionService.provision}이 존재하지 않는 기관 id에 대해 던진다 -
 * URL에 오타가 있는 것뿐이므로 404가 맞다.</p>
 *
 * <p>{@link SeedParseException}은 비어 있거나, 형식이 틀렸거나, 시트가 잘못된 업로드에
 * 대해 던진다 - 흔한 사용자 실수이므로 400과 함께 무엇이 잘못됐는지 알려줘야 한다.</p>
 *
 * <p>예외 메시지는 각 예외가 만든 그대로 내려준다(새로 지어내지 않는다) - 스택트레이스,
 * SQL, 파일 경로는 어차피 이 메시지들에 담기지 않으므로 그대로 노출해도 안전하다.
 * {@code server.error.include-message=NEVER} 기본값은 건드리지 않는다 - 여기서 직접
 * {@link ApiError} 본문을 만들어 반환하므로 그 설정과는 무관하게 동작한다.</p>
 *
 * <p><b>여기에 {@code Exception.class} catch-all을 추가하지 말 것.</b> 예상하지 못한
 * 예외까지 4xx로 감싸버리면 진짜 버그가 조용히 묻힌다. 예상 밖 예외는 기본 500 처리
 * 그대로 두는 것이 의도다.</p>
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<ApiError> handleNotFound(IllegalArgumentException e) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiError(e.getMessage()));
    }

    @ExceptionHandler(SeedParseException.class)
    public ResponseEntity<ApiError> handleSeedParse(SeedParseException e) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiError(e.getMessage()));
    }
}
