package org.octopus.internal.web.utils

import org.octopus.internal.common.enums.EBusinessException
import org.octopus.internal.common.exceptions.OctopusPlanningException
import org.octopus.internal.web.utils.responses.WebResponse
import org.springframework.http.HttpStatus
import org.springframework.http.converter.HttpMessageNotReadableException
//import org.springframework.security.authorization.AuthorizationDeniedException
import org.springframework.web.HttpRequestMethodNotSupportedException
import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.RestControllerAdvice
import org.springframework.web.context.request.ServletWebRequest
import org.springframework.web.context.request.WebRequest
import org.springframework.web.servlet.resource.NoResourceFoundException

@RestControllerAdvice
class BaseAdvice {

    @ExceptionHandler(OctopusPlanningException::class)
    fun handleLorcaBusinessException(
        ex: OctopusPlanningException,
        request: WebRequest
    ): WebResponse<Unit> {
        return WebResponse.ko(
            deductStatus(ex.ex),
            ex.message
        )
    }

    private fun deductStatus(ex: EBusinessException): HttpStatus {
        return when (ex) {
            EBusinessException.ENTITY_WITH_ID_NOT_FOUND -> HttpStatus.NOT_FOUND
            EBusinessException.STARTING_REPORT_ALREADY_EXISTS -> HttpStatus.CONFLICT
            EBusinessException.REPORT_END_DATE_LE_START_REPORT,
            EBusinessException.REPORT_IS_START_NOT_CLEAR,
            EBusinessException.INVALID_REQUEST -> HttpStatus.BAD_REQUEST
            EBusinessException.STARTING_REPORT_DOESNT_EXIST -> HttpStatus.NOT_ACCEPTABLE
        }
    }

    @ExceptionHandler(NumberFormatException::class)
    fun handleNumberFormatException(
        ex: NumberFormatException,
        request: WebRequest
    ): WebResponse<Unit> {
        return WebResponse.ko(
            HttpStatus.BAD_REQUEST,
            "${HttpStatus.BAD_REQUEST.reasonPhrase}: ${ex.message}"
        )
    }


    @ExceptionHandler(NoResourceFoundException::class)
    fun handleNoResourceFoundException(
        ex: NoResourceFoundException,
        request: WebRequest
    ): WebResponse<Unit> {
        return WebResponse.ko(
            HttpStatus.NOT_FOUND,
            "${HttpStatus.NOT_FOUND.reasonPhrase}: ${(request as ServletWebRequest).request.requestURI}"

        )
    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException::class)
    fun handleHttpRequestMethodNotSupportedException(
        ex: HttpRequestMethodNotSupportedException,
        request: WebRequest
    ): WebResponse<Unit> {
        return WebResponse.ko(
            HttpStatus.METHOD_NOT_ALLOWED,
            "${HttpStatus.METHOD_NOT_ALLOWED.reasonPhrase}: ${(request as ServletWebRequest).request.requestURI}"

        )
    }


    @ExceptionHandler(MethodArgumentNotValidException::class)
    fun handleMethodArgumentNotValidException(
        ex: MethodArgumentNotValidException,
        request: WebRequest
    ): WebResponse<Unit> {
        val errors =
            ex.bindingResult.fieldErrors.map {
                "${it.field} - ${it.defaultMessage}"
            }
        return WebResponse.ko(
            HttpStatus.NOT_ACCEPTABLE,
            errors
        )
    }


    @ExceptionHandler(HttpMessageNotReadableException::class)
    fun handleHttpMessageNotReadableException(
        ex: HttpMessageNotReadableException,
        request: WebRequest
    ): WebResponse<Unit> {
        return WebResponse.ko(
            HttpStatus.NOT_ACCEPTABLE,
            "${HttpStatus.NOT_ACCEPTABLE.reasonPhrase}: JSON parse error. Please verify the body has the correct format.",
        )
    }

//    @ExceptionHandler(AuthorizationDeniedException::class)
//    fun handleAuthorizationDeniedException(
//        ex: AuthorizationDeniedException,
//        request: WebRequest
//    ): WebResponse<Unit> {
//        return WebResponse.ko(
//            HttpStatus.FORBIDDEN,
//            "${HttpStatus.FORBIDDEN.reasonPhrase}: ${ex.message}"
//
//        )
//    }


    @ExceptionHandler(Exception::class)
    fun handleException(
        ex: Exception,
        request: WebRequest
    ): WebResponse<Unit> {
        return WebResponse.ko(
            HttpStatus.INTERNAL_SERVER_ERROR,
            ex.message
        )
    }
}
