package com.sonymusic.dx.dxuiservice.exception;

import jakarta.persistence.EntityNotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * Global exception handler.
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * Error response record.
     */
    public record ErrorResponse(String message) {}

    /**
     * Handles MissingServletRequestParameterException.
     *
     * @param ex the MissingServletRequestParameterException.
     * @return ResponseEntity with an error message and HTTP status BAD_REQUEST.
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public ResponseEntity<ErrorResponse> handleAuthorisationException(
            MissingServletRequestParameterException ex) {
        log.error("Missing request parameter: ", ex);

        return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.BAD_REQUEST);
    }

    /**
     * Handles MethodArgumentNotValidException.
     *
     * @param ex the MethodArgumentNotValidException.
     * @return ResponseEntity with an error message and HTTP status BAD_REQUEST.
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(
            MethodArgumentNotValidException ex) {
        log.error("Validation error: ", ex);

        return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.BAD_REQUEST);
    }

    /**
     * Handles HttpMessageConversionException.
     *
     * @param ex the HttpMessageConversionException.
     * @return ResponseEntity with an error message and HTTP status BAD_REQUEST.
     */
    @ExceptionHandler(HttpMessageConversionException.class)
    public ResponseEntity<ErrorResponse> handleHttpMessageConversionException(
            HttpMessageConversionException ex) {
        log.error("Message conversion error: ", ex);

        return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.BAD_REQUEST);
    }

    /**
     * Handles BadRequestException.
     *
     * @param ex the BadRequestException.
     * @return ResponseEntity with an error message and HTTP status BAD_REQUEST.
     */
    @ExceptionHandler(BadRequestException.class)
    public ResponseEntity<ErrorResponse> handleBadRequestException(
            BadRequestException ex) {
        log.error("Bad request: ", ex);

        return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.BAD_REQUEST);
    }

    /**
     * Handles EntityNotFoundException.
     *
     * @param ex the EntityNotFoundException.
     * @return ResponseEntity with an error message and HTTP status BAD_REQUEST.
     */
    @ExceptionHandler(EntityNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleEntityNotFoundException(
            EntityNotFoundException ex) {
        log.error("Entity not found: ", ex);

        return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.NOT_FOUND);
    }

    /**
     * Handles NotFoundRequestException.
     *
     * @param ex the NotFoundRequestException.
     * @return ResponseEntity with an error message and HTTP status NOT_FOUND.
     */
    @ExceptionHandler(NotFoundRequestException.class)
    public ResponseEntity<ErrorResponse> handleEntityNotFoundException(NotFoundRequestException ex) {
        return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.NOT_FOUND);
    }

}
