package de.htwsaar.webshop.controller;

import de.htwsaar.webshop.model.ReviewModel;
import de.htwsaar.webshop.repository.entities.Review;
import de.htwsaar.webshop.service.ArticleService;
import de.htwsaar.webshop.service.ReviewService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.UUID;

import static de.htwsaar.webshop.config.ControllerPathConfig.REVIEW_BASE;
import static de.htwsaar.webshop.config.ControllerPathConfig.REVIEW_GET_ALL;
import static de.htwsaar.webshop.config.ParameterConfig.*;
import static de.htwsaar.webshop.util.LoggerUtil.logRequest;

@RestController
@Slf4j
public class ReviewController {

    private final ReviewService reviewService;
    private final ArticleService articleService;

    @Autowired
    public ReviewController(ReviewService reviewService, ArticleService articleService) {
        this.reviewService = reviewService;
        this.articleService = articleService;
    }

    @RequestMapping(path = REVIEW_GET_ALL, method = RequestMethod.GET, produces = "application/json")
    public ResponseEntity<List<ReviewModel>> getAll(HttpServletRequest request,
                                                    @RequestParam(value = PARAM_UUID) UUID uuid) {
        logRequest(request);
        List<ReviewModel> review = reviewService.getAllByUUID(uuid).stream().map(reviewService::toModel).toList();
        if (review.isEmpty()) {
            return ResponseEntity.noContent().build();
        }
        return ResponseEntity.ok(review);
    }

    @RequestMapping(path = REVIEW_BASE, method = RequestMethod.GET, produces = "application/json")
    public ResponseEntity<Review> get(HttpServletRequest request,
                                      @RequestParam(value = PARAM_ID) Long reviewId) {
        logRequest(request);
        Review review = reviewService.getReviewById(reviewId);
        if (review == null) {
            return ResponseEntity.noContent().build();
        }
        return ResponseEntity.ok(review);
    }

    @RequestMapping(path = REVIEW_BASE, method = RequestMethod.POST, produces = "application/json")
    public ResponseEntity<Boolean> add(HttpServletRequest request,
                                       @RequestParam(value = PARAM_UUID) UUID uuid,
                                       @RequestParam(value = PARAM_RATING) int rating,
                                       @RequestBody String review) {
        logRequest(request);

        if (uuid == null || articleService.findByUUID(uuid) == null
                || rating < 0 || rating > 10) {
            log.warn("[{}] failed Validation, sending bad request", request.getRequestURI());
            return ResponseEntity.badRequest().body(false);
        }

        Review saved = reviewService.save(uuid, rating, review);
        return ResponseEntity.ok(saved != null);
    }

    @RequestMapping(path = REVIEW_BASE, method = RequestMethod.PUT, produces = "application/json")
    public ResponseEntity<Boolean> update(HttpServletRequest request,
                                          @RequestParam(value = PARAM_ID) Long reviewId,
                                          @RequestBody Review review) {
        logRequest(request);
        if (reviewId == null || reviewService.getReviewById(reviewId) == null) {
            return ResponseEntity.badRequest().body(false);
        }
        review.setId(reviewService.getReviewById(reviewId).getId());
        return ResponseEntity.ok(reviewService.save(review) != null);
    }

    @RequestMapping(path = REVIEW_BASE, method = RequestMethod.DELETE, produces = "application/json")
    public ResponseEntity<Boolean> delete(HttpServletRequest request,
                                          @RequestParam(value = PARAM_ID) Long reviewId) {
        logRequest(request);
        if (reviewId == null) {
            log.warn("[{}] got invalid imageId", request.getRequestURI());
            return ResponseEntity.badRequest().body(false);
        }
        if (reviewService.getReviewById(reviewId) != null) {
            log.warn("[{}] got invalid imageId", request.getRequestURI());
            return ResponseEntity.badRequest().body(false);
        }
        reviewService.delete(reviewId);
        return ResponseEntity.ok().build();
    }
}
