package com.example.backend.books.api;

import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.example.backend.books.model.BookEntity;
import com.example.backend.books.service.BookService;
import com.example.backend.core.api.PageAttributesMapper;
import com.example.backend.core.configuration.Constants;
import com.example.backend.core.session.SessionCart;
import com.example.backend.orders.api.BookCountDto;

@Controller
@RequestMapping(SearchController.URL)
public class SearchController {
    public static final String URL = "/search";
    private static final String SEARCH_VIEW = "search";

    private static final String PAGE_ATTRIBUTE = "page";
    private static final String SEARCH_ATTRIBUTE = "searchInfo";
    private static final String SORT_ATTRIBUTE = "filter";
    private static final String CART_ATTRIBUTE = "cart";
    private static final String BOOKID_ATTRIBUTE = "bookId";

    private final BookService bookService;
    private final ModelMapper modelMapper;
    private final SessionCart cart;

    public SearchController(BookService bookService, ModelMapper modelMapper, SessionCart cart) {
        this.bookService = bookService;
        this.modelMapper = modelMapper;
        this.cart = cart;
    }

    private BookDto toBookDto(BookEntity entity) {
        return modelMapper.map(entity, BookDto.class);
    }

    @GetMapping
    public String search(
            @RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
            @RequestParam(name = SORT_ATTRIBUTE, defaultValue = "new") String filter,
            @RequestParam(name = SEARCH_ATTRIBUTE, defaultValue = "") String searchInfo,
            Model model) {
        model.addAttribute(CART_ATTRIBUTE, cart);
        model.addAttribute(PAGE_ATTRIBUTE, page);
        model.addAttribute(SEARCH_ATTRIBUTE, searchInfo);
        model.addAttribute(SORT_ATTRIBUTE, filter);
        model.addAllAttributes(PageAttributesMapper.toAttributes(
                bookService.getAllByFilters(0, page, Constants.DEFAULT_PAGE_SIZE, filter, searchInfo),
                this::toBookDto));
        return SEARCH_VIEW;
    }

    @PostMapping
    public String addCartItem(
            @RequestParam(name = BOOKID_ATTRIBUTE) Long bookId,
            @RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
            @RequestParam(name = SORT_ATTRIBUTE, defaultValue = "new") String filter,
            @RequestParam(name = SEARCH_ATTRIBUTE, defaultValue = "") String searchInfo,
            Model model,
            RedirectAttributes redirectAttributes) {
        BookEntity book = bookService.get(bookId);
        BookCountDto bookCountDto = new BookCountDto();
        bookCountDto.setBook(toBookDto(book));
        bookCountDto.setCount(1);
        cart.put(bookId, bookCountDto);

        redirectAttributes.addAttribute(SEARCH_ATTRIBUTE, searchInfo);
        redirectAttributes.addAttribute(PAGE_ATTRIBUTE, page);
        redirectAttributes.addAttribute(SORT_ATTRIBUTE, filter);

        return Constants.REDIRECT_VIEW + URL;
    }
}
