package com.webproglabs.lab1.mvc;

import com.webproglabs.lab1.dto.CommentDto;
import com.webproglabs.lab1.dto.PostDto;
import com.webproglabs.lab1.dto.TopicDto;
import com.webproglabs.lab1.dto.UserDto;
import com.webproglabs.lab1.services.CommentService;
import com.webproglabs.lab1.services.PostService;
import com.webproglabs.lab1.services.TopicService;
import com.webproglabs.lab1.services.UserService;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("/feed")
public class FeedMvcController {
    private final UserService userService;
    private final PostService postService;
    private final CommentService commentService;
    private final TopicService topicService;

    public FeedMvcController(UserService userService, PostService postService, CommentService commentService, TopicService topicService) {
        this.userService = userService;
        this.postService = postService;
        this.commentService = commentService;
        this.topicService = topicService;
    }

    @GetMapping
    public String getFeedPage(Model model) {
        model.addAttribute("topics", topicService.findAllTopics().stream().map(TopicDto::new).toList());
        return "feed";
    }

    @GetMapping(value = {"/{id}"})
    public String getFeedPageWithTopic(@PathVariable Long id, Model model) {
        model.addAttribute("profiles", userService.findAllUsers().stream().map(UserDto::new).toList());
        model.addAttribute("posts", topicService.findTopicById(id).getPosts().stream().map(PostDto::new).toList());
        model.addAttribute("topics", topicService.findAllTopics().stream().map(TopicDto::new).toList());

        UserDetails principal = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        var user = userService.findUserByLogin(principal.getUsername());
        model.addAttribute("selectedProfile", new UserDto(userService.findUserById(user.getId())));

        model.addAttribute("selectedTopic", new TopicDto(topicService.findTopicById(id)));

        return "feedPosts";
    }

    @GetMapping(value= {"/filter/{id}/"})
    public String getFeedPageFiltered(@PathVariable Long id, @RequestParam(value="searchField") String searchField, Model model) {
        model.addAttribute("profiles", userService.findAllUsers().stream().map(UserDto::new).toList());
        model.addAttribute("topics", topicService.findAllTopics().stream().map(TopicDto::new).toList());
        UserDetails principal = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        var user = userService.findUserByLogin(principal.getUsername());
        model.addAttribute("selectedProfile", new UserDto(userService.findUserById(user.getId())));
        model.addAttribute("selectedTopic", new TopicDto(topicService.findTopicById(id)));

        model.addAttribute("posts", postService.findPostsInTopicByText(searchField, id).stream().map(PostDto::new).toList());

        return "feedPosts";
    }

    @PostMapping(value={"/{topicId}/post/{id}/"})
    public String createPost(@PathVariable Long topicId, @PathVariable Long id, @RequestParam(value="postInputField") String postInputField) {
        postService.addPost(postInputField, id, topicId);
        return "redirect:/feed/" + topicId.toString();
    }

    @PostMapping(value = {"/deletePost/{id}/{topicId}"})
    public String deletePost(@PathVariable Long id, @PathVariable Long topicId) {
        postService.deletePost(id);
        return "redirect:/feed/" + topicId.toString();
    }

    @GetMapping(value = {"postModal/{id}/{topicId}"})
    public String getPostEditModal(@PathVariable Long id,@PathVariable Long topicId, Model model) {
        model.addAttribute("selectedPost", new PostDto(postService.findPostById(id)));
        model.addAttribute("profiles", userService.findAllUsers().stream().map(UserDto::new).toList());
        model.addAttribute("posts", topicService.findTopicById(topicId).getPosts().stream().map(PostDto::new).toList());

        UserDetails principal = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        var user = userService.findUserByLogin(principal.getUsername());
        model.addAttribute("selectedProfile", new UserDto(userService.findUserById(user.getId())));
        model.addAttribute("selectedTopic", new TopicDto(topicService.findTopicById(topicId)));
        return "editPostModal";
    }

    @PostMapping(value = {"editPost/{id}/{topicId}/"})
    public String editPost(@PathVariable Long id, @PathVariable Long topicId, @RequestParam(value="postEditField") String postEditField) {
        postService.updatePost(id, postEditField);
        return "redirect:/feed/" + topicId.toString();
    }

    @GetMapping(value = {"commentModal/{topicId}/{postId}"})
    public String getCommentModal(@PathVariable Long topicId,@PathVariable Long postId, Model model) {
        model.addAttribute("selectedPost", new PostDto(postService.findPostById(postId)));
        model.addAttribute("profiles", userService.findAllUsers().stream().map(UserDto::new).toList());
        model.addAttribute("posts", topicService.findTopicById(topicId).getPosts().stream().map(PostDto::new).toList());

        UserDetails principal = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        var user = userService.findUserByLogin(principal.getUsername());
        model.addAttribute("selectedProfile", new UserDto(userService.findUserById(user.getId())));
        model.addAttribute("selectedTopic", new TopicDto(topicService.findTopicById(topicId)));
        return "commentModal";
    }

    @PostMapping(value = {"comment/{authorId}/{topicId}/{postId}/"})
    public String createComment(@PathVariable Long authorId, @PathVariable Long topicId, @PathVariable Long postId, @RequestParam(value="commentInputField") String commentInputField) {
        commentService.addComment(commentInputField, authorId, postId);
        return "redirect:/feed/" + topicId.toString();
    }

    @PostMapping(value = {"/deleteComment/{id}/{topicId}"})
    public String deleteComment(@PathVariable Long id, @PathVariable Long topicId) {
        commentService.deleteComment(id);
        return "redirect:/feed/" + topicId.toString();
    }

    @GetMapping(value = {"commentEditModal/{id}/{topicId}"})
    public String getCommentEditModal(@PathVariable Long id,@PathVariable Long topicId, Model model) {
        model.addAttribute("selectedComment", new CommentDto(commentService.findCommentById(id)));
        model.addAttribute("profiles", userService.findAllUsers().stream().map(UserDto::new).toList());
        model.addAttribute("posts", topicService.findTopicById(topicId).getPosts().stream().map(PostDto::new).toList());

        UserDetails principal = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        var user = userService.findUserByLogin(principal.getUsername());
        model.addAttribute("selectedProfile", new UserDto(userService.findUserById(user.getId())));
        model.addAttribute("selectedTopic", new TopicDto(topicService.findTopicById(topicId)));
        return "editCommentModal";
    }

    @PostMapping(value = {"editComment/{topicId}/{commentId}/"})
    public String editComment(@PathVariable Long topicId,@PathVariable Long commentId, @RequestParam(value="commentEditField") String commentEditField) {
        commentService.updateComment(commentId, commentEditField);
        return "redirect:/feed/" + topicId.toString();
    }

}