package net.shyshkin.study.fullstack.supportportal.backend.controller;


import net.shyshkin.study.fullstack.supportportal.backend.domain.Post;
import net.shyshkin.study.fullstack.supportportal.backend.domain.Professor;
import net.shyshkin.study.fullstack.supportportal.backend.domain.dto.PostDto;
import net.shyshkin.study.fullstack.supportportal.backend.repository.PostRepository;
import net.shyshkin.study.fullstack.supportportal.backend.repository.ProfessorRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import com.amazonaws.services.secretsmanager.model.ResourceNotFoundException;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/posts")
public class PostController {

    @Autowired
    private PostRepository postRepository;


      // Get all posts where isPosted is true
    @GetMapping("/posted")
    public ResponseEntity<List<Post>> getAllPostedPosts() {
        try {
            List<Post> posts = postRepository.findAllByIsPostedTrue();
            return ResponseEntity.ok(posts);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    // Get all unique tags with count
    @GetMapping("/tags/count")
    public ResponseEntity<Map<String, Long>> getTagsWithCount() {
        try {
            List<Object[]> tagCounts = postRepository.findTagsWithCount();
            Map<String, Long> tagCountMap = new HashMap<>();
            for (Object[] tagCount : tagCounts) {
                tagCountMap.put((String) tagCount[0], (Long) tagCount[1]);
            }
            return ResponseEntity.ok(tagCountMap);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    // Get all posts associated with a specific tag where isPosted is true
    @GetMapping("/tag/{tag}")
    public ResponseEntity<List<Post>> getPostsByTag(@PathVariable String tag) {
        try {
            List<Post> posts = postRepository.findAllByTagAndIsPostedTrue(tag);
            return ResponseEntity.ok(posts);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    // Get all posts
    @GetMapping
    public List<Post> getAllPosts() {
        return postRepository.findAll();
    }

    // Get a single post by ID
    @GetMapping("/{id}")
    public ResponseEntity<Post> getPostById(@PathVariable Long id) {
        return postRepository.findById(id)
                .map(post -> ResponseEntity.ok(post))
                .orElse(ResponseEntity.notFound().build());
    }


    @Autowired
    private ProfessorRepository professorRepository;

   @PostMapping
    public ResponseEntity<?> createPost(@RequestBody PostDto postDto) {
        Post post = new Post();
        post.setTitle(postDto.getTitle());
        post.setContent(postDto.getContent());
        post.setPosted(postDto.isPosted());

        // Fetch professors from IDs, filter out null IDs
        List<Long> validProfessorIds = postDto.getProfessors().stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        List<Professor> professors = professorRepository.findAllById(validProfessorIds);
        post.setProfessors(professors);

        // Set tags
        post.setTags(postDto.getTags());

        // Save the post
        postRepository.save(post);
        return ResponseEntity.status(HttpStatus.CREATED).build();
    }

    @PutMapping("/{id}")
    public ResponseEntity<?> updatePost(@PathVariable Long id, @RequestBody PostDto postDto) {
        Post post = postRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Post not found"));

        post.setTitle(postDto.getTitle());
        post.setContent(postDto.getContent());
        post.setPosted(postDto.isPosted());

        // Fetch professors from IDs, filter out null IDs
        List<Long> validProfessorIds = postDto.getProfessors().stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        List<Professor> professors = professorRepository.findAllById(validProfessorIds);
        post.setProfessors(professors);

        // Set tags
        post.setTags(postDto.getTags());

        // Save the updated post
        postRepository.save(post);
        return ResponseEntity.ok().build();
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deletePost(@PathVariable Long id) {
        return postRepository.findById(id)
                .map(post -> {
                    postRepository.delete(post);
                    return ResponseEntity.noContent().<Void>build();  // Explicitly specify the type parameter
                })
                .orElse(ResponseEntity.notFound().build());
    }
    
}
