package samuelb.capripol.Controllers;

import com.fasterxml.jackson.databind.node.TextNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import samuelb.capripol.*;
import samuelb.capripol.Repositories.*;
import samuelb.capripol.Services.GroupService;
import samuelb.capripol.Services.UserDetailsServiceImpl;

import java.security.Principal;
import java.time.LocalDateTime;
import java.util.*;

@Controller
public class ClaimController {

    @Autowired
    private GroupRepository groupRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private FocusRepository focusRepository;

    @Autowired
    private FrameworkRepository frameworkRepository;

    @Autowired
    private GroupService groupService;

    @Autowired
    private SightingRepository sightingRepository;

    private static Logger logger = LoggerFactory.getLogger(UserDetailsServiceImpl.class);

    @GetMapping("/Claim")
    public ModelAndView claimPage(Principal principal, Model model){
        return new ModelAndView("Claim");
    }

    //User making a claim
    @PostMapping("/SelfClaim")
    public ModelAndView selfClaim(@RequestParam String[] focusName,
                                  @RequestParam("date") @DateTimeFormat(iso=DateTimeFormat.ISO.DATE_TIME) LocalDateTime date,
                                  @RequestParam String clicked, Model model, Principal principal){
        User user = userRepository.findByUserName(principal.getName());
        if(user != null){
            for(String fociName: focusName){
                Focus focus = focusRepository.findByFocusName(fociName);
                if(focus != null){
                    Sighting newSighting = new Sighting();
                    Long sighterID = user.getUserId();
                    newSighting.setFocus(focus);
                    newSighting.setDateSighted(date);
                    newSighting.setSighter(user);
                    newSighting.setSighterUserRatingFocusID(userRepository.getUserRating(user.getRating(focus), sighterID, focus.getFocusId()));
                    newSighting.setSightingValue(sightingRepository.getSightingValue(user.getRating(focus), sighterID, focus.getFocusId()));
                    newSighting.setSightee(user);
                    newSighting.setSighterSighteeRelationship("self");
                    sightingRepository.save(newSighting);
                }else{
                    model.addAttribute("error", "Error, focus: "+fociName+" no longer exists");
                    if(clicked.equals("groupScreen")){
                        return new ModelAndView("Group");
                    }else{
                        return new ModelAndView("Admin");
                    }
                }
            }
        }else{
            model.addAttribute("error", "An error has occured");
            return new ModelAndView("MainMenu");
        }
        return null;
    }

    @PostMapping(value = "/ClaimOther")
    @ResponseBody
    public ResponseEntity<String> claimOther(@RequestParam String[] focusName, @RequestParam String[] selectedUsers,
                                     @RequestParam @DateTimeFormat(iso=DateTimeFormat.ISO.DATE_TIME) LocalDateTime date, Model model, Principal principal){
        User user = userRepository.findByUserName(principal.getName());
        if(user != null){
            for(String foci: focusName){
                Focus focus = focusRepository.findByFocusName(foci);
                if(focus != null){
                    List<Sighting> sightings = new LinkedList<>();
                    for(String selectedUser: selectedUsers){
                        if(userRepository.findByUserName(selectedUser) != null){
                            Sighting newSighting = new Sighting();
                            newSighting.setFocus(focus);
                            newSighting.setDateSighted(date);
                            newSighting.setSighter(user);
                            //newSighting.setLocation(null);
                            newSighting.setSighterUserRatingFocusID(userRepository.getUserRating(user.getRating(focus), user.getUserId(), focus.getFocusId()));
                            newSighting.setSightingValue(sightingRepository.getSightingValue(user.getRating(focus), user.getUserId(), focus.getFocusId()));
                            newSighting.setSightee(userRepository.findByUserName(selectedUser));
                            newSighting.setSighterSighteeRelationship("peer");
                            sightings.add(newSighting);
                        }else{
                            return new ResponseEntity<>("User not found.", HttpStatus.NOT_FOUND);
                        }
                    }
                    for(Sighting sighting: sightings){
                        sightingRepository.save(sighting);
                        logger.info("saved");
                    }
                }else{
                    return new ResponseEntity<>("Foci not found.", HttpStatus.NOT_FOUND);
                }
            }
            return new ResponseEntity<>("Claim(s) successful.", HttpStatus.OK);
        }else{
            return new ResponseEntity<>("An error has occured.", HttpStatus.BAD_REQUEST);
        }
    }

    @GetMapping("/ClaimMembers")
    public ModelAndView claimMembers(Principal principal, Model model){
        User user = userRepository.findByUserName(principal.getName());
        Set<User> members = new HashSet<>();
        for(Group group: user.getGroups()){
            members.addAll(group.getGroupMembers());
        }
        members.remove(user);
        model.addAttribute("members", members);
        model.addAttribute("other", "other");
        return new ModelAndView("ClaimModal");
    }
}
