package com.example.backend.users.api;

import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.example.backend.core.configuration.Constants;
import com.example.backend.core.security.UserPrincipal;
import com.example.backend.core.session.SessionCart;
import com.example.backend.core.utils.NumMorph;
import com.example.backend.orders.api.BookCountDto;
import com.example.backend.orders.model.OrderEntity;
import com.example.backend.orders.service.OrderService;

@Controller
@RequestMapping(UserCartController.URL)
public class UserCartController {
    public static final String URL = "/cart";

    private static final String CART_VIEW = "cart";
    private static final String CART_ATTRIBUTE = "cart";

    private final OrderService orderService;
    private final SessionCart cart;

    public UserCartController(
            OrderService orderService,
            SessionCart cart) {
        this.orderService = orderService;
        this.cart = cart;
    }

    @GetMapping
    public String getCart(Model model) {
        model.addAttribute(CART_ATTRIBUTE, cart.values());
        model.addAttribute("count", cart.getCount());
        model.addAttribute("sum", cart.getSum());
        model.addAttribute("linesText", NumMorph.numMorph(cart.getCount(), "товар", "товара", "товаров"));
        return CART_VIEW;
    }

    @PostMapping("/clear")
    public String clearCart(
            @RequestParam(name = "bookId", defaultValue = "0") long bookId,
            Model model) {
        if (bookId <= 0) {
            cart.clear();
        } else {
            cart.remove(bookId);
        }
        return Constants.REDIRECT_VIEW + URL;
    }

    @PostMapping("/increase")
    public String increaseCartCount(
            @RequestParam(name = "bookId") long bookId) {
        BookCountDto book = cart.get(bookId);
        if (book != null) {
            book.setCount(book.getCount() + 1);
        }
        return Constants.REDIRECT_VIEW + URL;
    }

    @PostMapping("/decrease")
    public String decreaseCartCount(
            @RequestParam(name = "bookId") long bookId) {
        BookCountDto book = cart.get(bookId);
        if (book != null) {
            book.setCount(book.getCount() - 1);
        }
        final Map<Long, BookCountDto> filteredCart = cart.entrySet()
                .stream()
                .filter(item -> item.getValue().getCount() > 0)
                .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
        cart.clear();
        cart.putAll(filteredCart);
        return Constants.REDIRECT_VIEW + URL;
    }

    @PostMapping("/save")
    public String saveCart(
            Model model,
            @AuthenticationPrincipal UserPrincipal principal) {
        Map<Long, Integer> orderMap = cart.entrySet()
                .stream()
                .collect(Collectors.toMap(
                        Entry::getKey,
                        entry -> entry.getValue().getCount()));
        orderService.create(principal.getId(), new OrderEntity(), orderMap);
        cart.clear();
        return Constants.REDIRECT_VIEW + URL;
    }

}
