package org.micord.exceptions;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.naming.ServiceUnavailableException;
import java.io.FileNotFoundException;
import java.nio.file.AccessDeniedException;
import java.sql.SQLException;
import java.util.Map;
import java.util.NoSuchElementException;

@RestControllerAdvice
public class GlobalExceptionHandler {

	private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

	@ExceptionHandler(SQLException.class)
	public ResponseEntity<?> handleSQLException(SQLException e) {
		return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of(
			"message", "Database error occurred",
			"details", e.getMessage()
		));
	}

	@ExceptionHandler(Exception.class)
	public ResponseEntity<?> handleGeneralException(Exception e) {
		return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of(
			"message", "Unexpected error occurred",
			"details", e.getMessage()
		));
	}

	@ExceptionHandler(ValidationException.class)
	public ResponseEntity<?> handleValidationException(ValidationException e) {
		return ResponseEntity.badRequest().body(Map.of(
			"message", "Validation error occurred",
			"details", e.getValidationDetails()
		));
	}

	@ExceptionHandler(IllegalStateException.class)
	public ResponseEntity<?> handleIllegalStateException(IllegalStateException e) {
		return ResponseEntity.status(HttpStatus.CONFLICT).body(Map.of(
			"message", "Operation cannot be performed due to an invalid state",
			"details", e.getMessage()
		));
	}

	@ExceptionHandler(AccessDeniedException.class)
	public ResponseEntity<?> handleAccessDeniedException(AccessDeniedException e) {
		return ResponseEntity.status(HttpStatus.FORBIDDEN).body(Map.of(
			"message", "Access denied",
			"details", e.getMessage()
		));
	}

	@ExceptionHandler(ServiceUnavailableException.class)
	public ResponseEntity<?> handleServiceUnavailableException(ServiceUnavailableException e) {
		return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(Map.of(
			"message", "Service is temporarily unavailable",
			"details", e.getMessage()
		));
	}

	@ExceptionHandler(FileNotFoundException.class)
	public ResponseEntity<?> handleFileNotFoundException(FileNotFoundException e) {
		return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Map.of(
			"message", "File not found",
			"details", e.getMessage()
		));
	}

	@ExceptionHandler(IllegalArgumentException.class)
	public ResponseEntity<?> handleIllegalArgumentException(IllegalArgumentException e) {
		return ResponseEntity.badRequest().body(Map.of(
			"message", "Invalid input provided",
			"details", e.getMessage()
		));
	}

	@ExceptionHandler(IllegalRequestParametersException.class)
	public ResponseEntity<?> handleIllegalRequestParametersException(IllegalRequestParametersException e) {
		return ResponseEntity.badRequest().body(Map.of(
			"message", "Произошла ошибка ввода данных. Проверьте правильность заполнения полей",
			"details", e.getMessage()
		));
	}

	@ExceptionHandler(NoSuchElementException.class)
	public ResponseEntity<?> handleNoSuchElementException(NoSuchElementException e) {
		logger.error("Resource not found: {}", e.getMessage());
		return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Map.of(
			"message", "Requested resource not found",
			"details", e.getMessage()
		));
	}

	@ExceptionHandler(RuntimeException.class)
	public ResponseEntity<?> handleRuntimeException(RuntimeException e) {
		logger.error("Unexpected error occurred: {}", e.getMessage(), e);
		return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of(
			"message", "Internal server error",
			"details", e.getMessage()
		));
	}

	@ExceptionHandler(NoDownloadReportRecordsException.class)
	public ResponseEntity<?> handleNoDownloadReportRecordsException(NoDownloadReportRecordsException e) {
		logger.error("Unexpected error occurred: {}", e.getMessage(), e);
		return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of(
			"message", e.getMessage(),
			"details", e.getMessage()
		));
	}



}
