package com.example.backend.categories.api;

import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.backend.categories.model.CategoryEntity;
import com.example.backend.categories.service.CategoryService;
import com.example.backend.core.configuration.Constants;

import jakarta.validation.Valid;

@Controller
@RequestMapping(CategoryController.URL)
public class CategoryController {
    public static final String URL = Constants.ADMIN_PREFIX + "/category";
    private static final String CATEGORY_VIEW = "category";
    private static final String CATEGORY_EDIT_VIEW = "category-edit";
    private static final String CATEGORY_ATTRIBUTE = "category";

    private final CategoryService categoryService;
    private final ModelMapper modelMapper;

    public CategoryController(CategoryService categoryService, ModelMapper modelMapper) {
        this.categoryService = categoryService;
        this.modelMapper = modelMapper;
    }

    private CategoryDto toDto(CategoryEntity entity) {
        return modelMapper.map(entity, CategoryDto.class);
    }

    private CategoryEntity toEntity(CategoryDto dto) {
        return modelMapper.map(dto, CategoryEntity.class);
    }

    @GetMapping
    public String getAll(Model model) {
        model.addAttribute(
                "categories",
                categoryService.getAll().stream()
                        .map(this::toDto)
                        .toList());
        return CATEGORY_VIEW;
    }

    @GetMapping("/edit/")
    public String create(Model model) {
        model.addAttribute(CATEGORY_ATTRIBUTE, new CategoryDto());
        return CATEGORY_EDIT_VIEW;
    }

    @PostMapping("/edit/")
    public String create(
            @ModelAttribute(name = CATEGORY_ATTRIBUTE) @Valid CategoryDto category,
            BindingResult bindingResult,
            Model model) {
        if (bindingResult.hasErrors()) {
            return CATEGORY_EDIT_VIEW;
        }
        categoryService.create(toEntity(category));
        return Constants.REDIRECT_VIEW + URL;
    }

    @GetMapping("/edit/{id}")
    public String update(
            @PathVariable(name = "id") Long id,
            Model model) {
        if (id <= 0) {
            throw new IllegalArgumentException();
        }
        model.addAttribute(CATEGORY_ATTRIBUTE, toDto(categoryService.get(id)));
        return CATEGORY_EDIT_VIEW;
    }

    @PostMapping("/edit/{id}")
    public String update(
            @PathVariable(name = "id") Long id,
            @ModelAttribute(name = CATEGORY_ATTRIBUTE) @Valid CategoryDto category,
            BindingResult bindingResult,
            Model model) {
        if (bindingResult.hasErrors()) {
            return CATEGORY_EDIT_VIEW;
        }
        if (id <= 0) {
            throw new IllegalArgumentException();
        }
        categoryService.update(id, toEntity(category));
        return Constants.REDIRECT_VIEW + URL;
    }

    @PostMapping("/delete/{id}")
    public String delete(
            @PathVariable(name = "id") Long id) {
        categoryService.delete(id);
        return Constants.REDIRECT_VIEW + URL;
    }
}
