package com.codenetworkz.blog.web.controllers.dashboard;

import com.codenetworkz.blog.dtos.CategoryDto;
import com.codenetworkz.blog.dtos.TagDto;
import com.codenetworkz.blog.exceptions.InternalServerException;
import com.codenetworkz.blog.exceptions.ResourceNotAvailable;
import com.codenetworkz.blog.mappers.CategoryMapper;
import com.codenetworkz.blog.models.Category;
import com.codenetworkz.blog.services.CategoryService;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;


@Slf4j
@Controller
@RequestMapping("admin/categories")
public class AdminCategoryController {

    private final CategoryService categoryService;
    private final CategoryMapper categoryMapper;

    public AdminCategoryController(CategoryService categoryService,
                                   CategoryMapper categoryMapper){
        this.categoryService=categoryService;
        this.categoryMapper=categoryMapper;
    }

    @GetMapping("save")
    public String saveCategoryPage(@RequestParam(name = "page", defaultValue = "0") Integer page,
                                   @RequestParam(name = "size", defaultValue = "5") Integer size,Model model) throws InternalServerException {
        model.addAttribute("pageTitle", "Add new category");
        CategoryDto categoryDto=new CategoryDto();
        model.addAttribute("categoryDto", categoryDto);
        model.addAttribute("categories",  categoryService.getCategoryWithPagination(page,size));
        return "admin/blog/category/view";
    }

    @PostMapping("save")
    public String saveCategoryDetails(@ModelAttribute("categoryDto") @Valid CategoryDto categoryDto, BindingResult rbindingResult, Model model) throws InternalServerException, ResourceNotAvailable {
        model.addAttribute("pageTitle", "Add new category");
        if (rbindingResult.hasErrors()) {
            return "redirect:/admin/categories/save";
        }
        Optional<CategoryDto> save = categoryService.save(categoryDto.getName(), categoryDto.getDesc());
        if(save.isPresent() && save.get().getCategoryId()!=null) {
            return "redirect:/admin/categories/views";
        }
        return "redirect:/admin/categories/save";
    }


    @GetMapping("views")
    public String viewTags(@RequestParam(name = "page", defaultValue = "0") Integer page,
                           @RequestParam(name = "size", defaultValue = "5") Integer size,Model model) throws InternalServerException {
        model.addAttribute("pageTitle", "List of category");
        CategoryDto categoryDto=new CategoryDto();
        model.addAttribute("categoryDto", categoryDto);
        model.addAttribute("categories", categoryService.getCategoryWithPagination(page,size));
        return "admin/blog/category/view";
    }

    @GetMapping("view/{slug}")
    public String viewTags(@RequestParam(name = "page", defaultValue = "0") Integer page,
                           @RequestParam(name = "size", defaultValue = "5") Integer size,
                           @PathVariable String slug, Model model) throws InternalServerException, ResourceNotAvailable {
        model.addAttribute("pageTitle", "List of category");
        Optional<Category> find = categoryService.findByCategorySlug(slug);
        model.addAttribute("categoryDto", categoryMapper.categoryToCategaryDto(find).get());
        model.addAttribute("categories", categoryService.getCategoryWithPagination(page,size));
        return "admin/blog/category/viewSingleCategory";
    }

    @GetMapping("update/{slug}")
    public String updateTagPage(@RequestParam(name = "page", defaultValue = "0") Integer page,
                                @RequestParam(name = "size", defaultValue = "5") Integer size,
                                @PathVariable String slug, Model model) throws InternalServerException, ResourceNotAvailable {
        model.addAttribute("pageTitle", "Update old category");
        Optional<Category> updated = categoryService.findByCategorySlug(slug);
        model.addAttribute("categoryDto", categoryMapper.categoryToCategaryDto(updated));
        model.addAttribute("categories", categoryService.getCategoryWithPagination(page,size));
        return "admin/blog/category/update";
    }

    @PostMapping("update")
    public String updateTagDetails(@ModelAttribute("categoryDto") @Valid CategoryDto categoryDto, BindingResult rbindingResult, Model model) throws InternalServerException, ResourceNotAvailable {
        if (rbindingResult.hasErrors()) {
            return "redirect:/admin/categories/update";
        }
        Optional<CategoryDto> updated = categoryService.update(categoryDto.getSlug(), categoryDto.getName(), categoryDto.getDesc());
        return "redirect:/admin/categories/views";
    }


    @PostMapping("delete/{slug}")
    public String deleteSingleCategory(@PathVariable String slug, Model model) throws InternalServerException, ResourceNotAvailable {
        String deleted = categoryService.delete(slug);
            return "redirect:/admin/categories/views";
    }

    @GetMapping("list")
    public String viewCategoryList(@RequestParam(name = "page", defaultValue = "0") Integer page,
                                   @RequestParam(name = "size", defaultValue = "10") Integer size,Model model) throws InternalServerException {
        model.addAttribute("pageTitle", "List of Category");
        Page<CategoryDto> list = categoryService.getCategoryWithPagination(page,size);
        model.addAttribute("categories",  list);
        return "admin/blog/category/viewsList";
    }

    @PostMapping("change-status/{slug}")
    public String changeActiveStatus(@PathVariable String slug, Model model) throws InternalServerException, ResourceNotAvailable {
        Optional<CategoryDto> categoryDto = categoryService.changeActivateStatus(slug);
        if(categoryDto.isPresent()){
            model.addAttribute("message", "Successfully changed status category");
            return "redirect:/admin/categories/views";
        }
        return "redirect:/admin/categories/views";
    }

    @PostMapping("admin-approve/{slug}")
    public String approveCategoryCategory(@PathVariable String slug, Model model) throws InternalServerException, ResourceNotAvailable {
        Optional<CategoryDto> categoryDto = categoryService.changeApprovalStatus(slug);
        if(categoryDto.isPresent()){
            model.addAttribute("message", "Successfully changed status category");
            return "redirect:/admin/categories/views";
        }
        return "redirect:/admin/categories/views";
    }
}
