package com.example.demo.department.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.demo.core.configuration.Constants;
import com.example.demo.department.model.DepartmentEntity;
import com.example.demo.department.service.DepartmentService;

import jakarta.validation.Valid;

@Controller
@RequestMapping(DepartmentController.URL)
public class DepartmentController {
    public static final String URL = "/departments";
    private static final String DEPARTMENTS_VIEW = "departments";
    private static final String DEPARTMENTS_EDIT_VIEW = "department-edit";
    private static final String DEPARTMENTS_ATTRIBUTE = "departments";
    private final DepartmentService departmentService;
    private final ModelMapper modelMapper;

    public DepartmentController(DepartmentService departmentService, ModelMapper modelMapper) {
        this.departmentService = departmentService;
        this.modelMapper = modelMapper;
    }

    private DepartmentDto toDto(DepartmentEntity entity) {
        return modelMapper.map(entity, DepartmentDto.class);
    }

    private DepartmentEntity toEntity(DepartmentDto dto) {
        return modelMapper.map(dto, DepartmentEntity.class);
    }

    @GetMapping
    public String getAll(Model model) {
        model.addAttribute(DEPARTMENTS_ATTRIBUTE, 
            departmentService.getAll().stream().map(this::toDto).toList());
        return DEPARTMENTS_VIEW;
    }

    @GetMapping("/edit/")
    public String create(
        Model model) {
        model.addAttribute(DEPARTMENTS_ATTRIBUTE, new DepartmentDto());
        return DEPARTMENTS_EDIT_VIEW;
    }

    @PostMapping("/edit/")
    public String create(
        Model model,
        @ModelAttribute(name = DEPARTMENTS_ATTRIBUTE) @Valid DepartmentDto department,
        BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return DEPARTMENTS_EDIT_VIEW;
        }
        departmentService.create(toEntity(department));
        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(DEPARTMENTS_ATTRIBUTE, toDto(departmentService.get(id)));
        return DEPARTMENTS_EDIT_VIEW;
    }

    @PostMapping("/edit/{id}")
    public String update(
            @PathVariable(name = "id") Long id,
            @ModelAttribute(name = DEPARTMENTS_ATTRIBUTE) @Valid DepartmentDto department,
            BindingResult bindingResult,
            Model model) {
        if (bindingResult.hasErrors()) {
            return DEPARTMENTS_EDIT_VIEW;
        }
        if (id <= 0) {
            throw new IllegalArgumentException();
        }
        departmentService.update(id, toEntity(department));
        return Constants.REDIRECT_VIEW + URL;
    }

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