package com.example.backend.orders.api;

import java.util.Map;

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.PathVariable;
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.api.BookDto;
import com.example.backend.books.model.BookEntity;
import com.example.backend.core.api.PageAttributesMapper;
import com.example.backend.core.configuration.Constants;
import com.example.backend.core.utils.Formatter;
import com.example.backend.orders.model.OrderEntity;
import com.example.backend.orders.service.OrderService;

@Controller
@RequestMapping(OrderController.URL)
public class OrderController {
    public static final String URL = Constants.ADMIN_PREFIX + "/order";
    private static final String ORDER_VIEW = "order";
    private static final String ORDER_CHECK_VIEW = "order-check";
    private static final String ORDER_ATTRIBUTE = "order";
    private static final String PAGE_ATTRIBUTE = "page";

    private final OrderService orderService;
    private final ModelMapper modelMapper;

    public OrderController(OrderService orderService, ModelMapper modelMapper) {
        this.orderService = orderService;
        this.modelMapper = modelMapper;
    }

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

    private OrderDto toDto(OrderEntity entity) {
        final OrderDto dto = modelMapper.map(entity, OrderDto.class);
        dto.setDate(Formatter.format(entity.getDate()));
        dto.setSum(orderService.getSum(entity.getUser().getId(), entity.getId()));
        dto.setCount(orderService.getFullCount(entity.getUser().getId(), entity.getId()));
        dto.setBooks(orderService.getOrderBooks(entity.getUser().getId(), entity
                .getId()).stream()
                .map(orderBook -> {
                    BookCountDto bookCountDto = new BookCountDto();
                    bookCountDto.setBook(toBookDto(orderBook.getBook()));
                    bookCountDto.setCount(orderBook.getCount());
                    return bookCountDto;
                })
                .toList());
        return dto;
    }

    @GetMapping
    public String getAll(
            @RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
            Model model) {
        final Map<String, Object> attributes = PageAttributesMapper
                .toAttributes(orderService.getAll(0L, page, Constants.DEFAULT_PAGE_SIZE),
                        this::toDto);
        model.addAllAttributes(attributes);
        model.addAttribute(PAGE_ATTRIBUTE, page);
        return ORDER_VIEW;
    }

    @GetMapping("/check/{id}")
    public String checkOrder(
            @PathVariable(name = "id") Long id,
            @RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
            Model model) {
        model.addAttribute(ORDER_ATTRIBUTE, toDto(orderService.get(0L, id)));
        model.addAttribute(PAGE_ATTRIBUTE, page);
        return ORDER_CHECK_VIEW;
    }

    @PostMapping("/delete/{id}")
    public String delete(
            @PathVariable(name = "id") Long id,
            @RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
            RedirectAttributes redirectAttributes) {
        redirectAttributes.addAttribute(PAGE_ATTRIBUTE, page);
        orderService.delete(0L, id);
        return Constants.REDIRECT_VIEW + URL;
    }
}