package com.example.Vezba.controller;

import com.example.Vezba.model.*;
import com.example.Vezba.repository.*;
import com.example.Vezba.security.CustomUserDetails;
import com.example.Vezba.service.IPodkategorijaOglasaService;
import com.example.Vezba.service.PodkategorijaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.Query;
import org.springframework.security.core.Authentication;
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.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import static java.lang.Integer.parseInt;

@Controller
public class OglasController {
    @Autowired
    private OglasRepository oglasRepository;

    @Autowired
    private KorisnikRepository korisnikRepository;

    @Autowired
    private LokacijaRepository lokacijaRepository;

    @Autowired
    private KategorijaRepository kategorijaRepository;

    @Autowired
    private IPodkategorijaOglasaService podkategorijaOglasaService;

    @Autowired
    private PodkategorijaService podkategorijaService;

    @Autowired
    private PrijavaRepository prijavaRepository;

    @Autowired
    private LajkRepository lajkRepository;

    @Autowired
    private KomentarRepository komentarRepository;

    @GetMapping("/lista_poslova")
    public String izlistajPoslove(Model model,
                                  @RequestParam MultiValueMap<String,String> parametri
                                    ){

        HashSet<Oglas> skupOglasa = new HashSet(oglasRepository.findAll());

        List<Korisnik> listaPoslodavaca = new ArrayList<>();
        List<Lokacija> listaLokacija = new ArrayList<>();
        List<Kategorija> listaKategorija = new ArrayList<>();

        LinkedMultiValueMap mapaParamatara=new LinkedMultiValueMap(parametri);
        List<String> pretraga=mapaParamatara.get("pretraga");
        List<String> id_kategorije=mapaParamatara.get("oblast");
        List<String> id_lokacije=mapaParamatara.get("lokacija");
        List<String> rad_od_kuce=mapaParamatara.get("radOdKuce");
        List<String> id_podkategorija=mapaParamatara.get("podkategorije");
        List<String> tip_sortiranja=mapaParamatara.get("sortBy");

        if(!(pretraga==null && id_kategorije==null && id_lokacije==null && rad_od_kuce==null)) {
            if(pretraga!=null && !pretraga.get(0).equals("")) {
                skupOglasa.retainAll(oglasRepository.findByNaslovLike("%"+pretraga.get(0)+"%"));
            }
            if(id_kategorije!=null && !id_kategorije.get(0).equals("0")){
                skupOglasa.retainAll(oglasRepository.findByIdKategorije(parseInt(id_kategorije.get(0))));
                if(id_podkategorija!=null){
                    List<Integer> pom=new ArrayList<Integer>(id_podkategorija.size());
                    for(String s:id_podkategorija){
                        pom.add(parseInt(s));
                    }
                    skupOglasa.retainAll(podkategorijaOglasaService.vratiListuOglasaSPodkategorijama(pom));
                }
            }
            if(id_lokacije!=null && !id_lokacije.get(0).equals("0")){
                skupOglasa.retainAll(oglasRepository.findByIdLokacije(parseInt(id_lokacije.get(0))));
            }
            if(rad_od_kuce!=null && !rad_od_kuce.get(0).equals("none")){
                skupOglasa.retainAll(oglasRepository.findByRadOdKuce(rad_od_kuce.get(0).equals("1")));
            }

        }

        List<Oglas> listaOglasa =new ArrayList<Oglas>(skupOglasa);
        if(tip_sortiranja!=null) {
            String sort = tip_sortiranja.get(0);
            switch(sort){
                case "stari":
                    listaOglasa.sort(new AscSortById());
                    break;
                case "lajkovi":
                    listaOglasa.sort(new SortByLikes());
                    break;
                case "pregledi":
                    listaOglasa.sort(new SortByViews());
                    break;
                case "plata":
                    listaOglasa.sort(new SortByPlata());
                    break;
                default:
                    listaOglasa.sort(new DescSortById());
                    break;
            }
        }
        else
            listaOglasa.sort(new DescSortById());

        for (Oglas oglas : listaOglasa) {
            listaPoslodavaca.add(korisnikRepository.findById(oglas.getIdOglasavaca()).get());
            listaLokacija.add(lokacijaRepository.findById(oglas.getIdLokacije()).get());
            listaKategorija.add(kategorijaRepository.findById(oglas.getIdKategorije()).get());
        }

        model.addAttribute("poslovi", listaOglasa);
        model.addAttribute("poslodavci", listaPoslodavaca);
        model.addAttribute("lokacije", listaLokacija);
        model.addAttribute("kategorije", listaKategorija);

        //lista svh kategorija za filter
        List<Kategorija> sveKategorije = kategorijaRepository.findAll();
        model.addAttribute("filterKategorije", sveKategorije);
        //lista svih lokacija za filter
        List<Lokacija> sveLokacije = lokacijaRepository.findAll();
        model.addAttribute("filterLokacije", sveLokacije);
        //lista svih podkategorija
        List<Podkategorija> svePodkategorije=podkategorijaService.findAll();
        model.addAttribute("filterPodkategorije",svePodkategorije);

        return "lista_poslova";
    }


    @GetMapping("/detalji_oglasa")
    public String jobDetails(@RequestParam("id") String id_oglasa, Model model){

        Oglas oglas=oglasRepository.findById(parseInt(id_oglasa)).get();
        Korisnik poslodavac=korisnikRepository.findById(oglas.getIdOglasavaca()).get();
        Lokacija lokacija=lokacijaRepository.findById(oglas.getIdLokacije()).get();
        Kategorija kategorija=kategorijaRepository.findById(oglas.getIdKategorije()).get();
        List<Podkategorija> listaVestina=podkategorijaOglasaService.vratiListuPodkategorijaOglasa(parseInt(id_oglasa));

        oglasRepository.updateBrojPregledaByIdOglasa(oglas.getIdOglasa());

        model.addAttribute("prijava",new Prijava());
        model.addAttribute("oglas",oglas);
        model.addAttribute("listaVestina", listaVestina);
        model.addAttribute("kategorija",kategorija);
        model.addAttribute("lokacija",lokacija);
        model.addAttribute("poslodavac",poslodavac);

        return "detalji_oglasa";
    }




    @PostMapping("/proces_prijava")
    public String procesPrijave(Prijava prijava,Model model,RedirectAttributes ra){
        List<Prijava> result=prijavaRepository.findByIdOglasaByIdKorisnika(prijava.getIdOglasa(),prijava.getIdKorisnika());

        if(result==null || result.size()==0) {
            prijavaRepository.save(prijava);
            oglasRepository.updateBrojPrijavaByIdOglasa(prijava.getIdOglasa());
            ra.addFlashAttribute("message","Uspesno ste se prijavili na oglas");
        }
        else{
            ra.addFlashAttribute("message","Vec ste ste se prijavili na ovaj oglas");
        }

        return "redirect:/detalji_oglasa?id="+prijava.getIdOglasa();
    }


    @PostMapping("/lajk_proces")
    public String lajkuj(Model model,
                         Prijava prijava){
        List<Lajk> temp=lajkRepository.findByIdOglasaByIdKorisnika(prijava.getIdOglasa(),prijava.getIdKorisnika());

        if(temp==null || temp.size()==0) {
            Lajk lajk = new Lajk(prijava.getIdOglasa(), prijava.getIdKorisnika());
            oglasRepository.updateBrojLajkovaByIdOglasa(prijava.getIdOglasa());
            lajkRepository.save(lajk);
        }

        return "redirect:/detalji_oglasa?id="+prijava.getIdOglasa();
    }

    @GetMapping("/moje_prijave")
    public String prikazPrijava(Model model,
                                @RequestParam MultiValueMap<String,String> parametri
                                    ){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();

        HashSet<Prijava> skupPrijava = new HashSet(korisnikRepository.getById(userDetails.getKorisnikId()).getPoslatePrijave());
        HashSet<Oglas> skupOglasa=new HashSet<>();
        for(Prijava p:skupPrijava){
            skupOglasa.add(oglasRepository.findById(p.getIdOglasa()).get());
        }

        List<Korisnik> listaPoslodavaca = new ArrayList<>();
        List<Lokacija> listaLokacija = new ArrayList<>();
        List<Kategorija> listaKategorija = new ArrayList<>();

        LinkedMultiValueMap mapaParamatara=new LinkedMultiValueMap(parametri);
        List<String> pretraga=mapaParamatara.get("pretraga");
        List<String> id_kategorije=mapaParamatara.get("oblast");
        List<String> id_lokacije=mapaParamatara.get("lokacija");
        List<String> rad_od_kuce=mapaParamatara.get("radOdKuce");
        List<String> id_podkategorija=mapaParamatara.get("podkategorije");
        List<String> tip_sortiranja=mapaParamatara.get("sortBy");

        if(!(pretraga==null && id_kategorije==null && id_lokacije==null && rad_od_kuce==null)) {
            if(pretraga!=null && !pretraga.get(0).equals("")) {
                skupOglasa.retainAll(oglasRepository.findByNaslovLike("%"+pretraga.get(0)+"%"));
            }
            if(id_kategorije!=null && !id_kategorije.get(0).equals("0")){
                skupOglasa.retainAll(oglasRepository.findByIdKategorije(parseInt(id_kategorije.get(0))));
                if(id_podkategorija!=null){
                    List<Integer> pom=new ArrayList<Integer>(id_podkategorija.size());
                    for(String s:id_podkategorija){
                        pom.add(parseInt(s));
                    }
                    skupOglasa.retainAll(podkategorijaOglasaService.vratiListuOglasaSPodkategorijama(pom));
                }
            }
            if(id_lokacije!=null && !id_lokacije.get(0).equals("0")){
                skupOglasa.retainAll(oglasRepository.findByIdLokacije(parseInt(id_lokacije.get(0))));
            }
            if(rad_od_kuce!=null && !rad_od_kuce.get(0).equals("none")){
                skupOglasa.retainAll(oglasRepository.findByRadOdKuce(rad_od_kuce.get(0).equals("1")));
            }

        }

        List<Oglas> listaOglasa =new ArrayList<Oglas>(skupOglasa);
        if(tip_sortiranja!=null) {
            String sort = tip_sortiranja.get(0);
            switch(sort){
                case "stari":
                    listaOglasa.sort(new AscSortById());
                    break;
                case "lajkovi":
                    listaOglasa.sort(new SortByLikes());
                    break;
                case "pregledi":
                    listaOglasa.sort(new SortByViews());
                    break;
                default:
                    listaOglasa.sort(new DescSortById());
                    break;
            }
        }

        for (Oglas oglas : listaOglasa) {
            listaPoslodavaca.add(korisnikRepository.findById(oglas.getIdOglasavaca()).get());
            listaLokacija.add(lokacijaRepository.findById(oglas.getIdLokacije()).get());
            listaKategorija.add(kategorijaRepository.findById(oglas.getIdKategorije()).get());
        }

        model.addAttribute("poslovi", listaOglasa);
        model.addAttribute("poslodavci", listaPoslodavaca);
        model.addAttribute("lokacije", listaLokacija);
        model.addAttribute("kategorije", listaKategorija);

        //lista svh kategorija za filter
        List<Kategorija> sveKategorije = kategorijaRepository.findAll();
        model.addAttribute("filterKategorije", sveKategorije);
        //lista svih lokacija za filter
        List<Lokacija> sveLokacije = lokacijaRepository.findAll();
        model.addAttribute("filterLokacije", sveLokacije);
        //lista svih podkategorija
        List<Podkategorija> svePodkategorije=podkategorijaService.findAll();
        model.addAttribute("filterPodkategorije",svePodkategorije);
        return "moje_prijave";
    }

    @GetMapping("/moji_oglasi")
    public String prikazMojihOglasa(Model model,
                                @RequestParam MultiValueMap<String,String> parametri
    ){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();

        HashSet<Oglas> skupOglasa = new HashSet(korisnikRepository.findById(userDetails.getKorisnikId()).get().getPostavljeniOglasi());

        List<Korisnik> listaPoslodavaca = new ArrayList<>();
        List<Lokacija> listaLokacija = new ArrayList<>();
        List<Kategorija> listaKategorija = new ArrayList<>();

        LinkedMultiValueMap mapaParamatara=new LinkedMultiValueMap(parametri);
        List<String> pretraga=mapaParamatara.get("pretraga");
        List<String> id_kategorije=mapaParamatara.get("oblast");
        List<String> id_lokacije=mapaParamatara.get("lokacija");
        List<String> rad_od_kuce=mapaParamatara.get("radOdKuce");
        List<String> id_podkategorija=mapaParamatara.get("podkategorije");
        List<String> tip_sortiranja=mapaParamatara.get("sortBy");

        if(!(pretraga==null && id_kategorije==null && id_lokacije==null && rad_od_kuce==null)) {
            if(pretraga!=null && !pretraga.get(0).equals("")) {
                skupOglasa.retainAll(oglasRepository.findByNaslovLike("%"+pretraga.get(0)+"%"));
            }
            if(id_kategorije!=null && !id_kategorije.get(0).equals("0")){
                skupOglasa.retainAll(oglasRepository.findByIdKategorije(parseInt(id_kategorije.get(0))));
                if(id_podkategorija!=null){
                    List<Integer> pom=new ArrayList<Integer>(id_podkategorija.size());
                    for(String s:id_podkategorija){
                        pom.add(parseInt(s));
                    }
                    skupOglasa.retainAll(podkategorijaOglasaService.vratiListuOglasaSPodkategorijama(pom));
                }
            }
            if(id_lokacije!=null && !id_lokacije.get(0).equals("0")){
                skupOglasa.retainAll(oglasRepository.findByIdLokacije(parseInt(id_lokacije.get(0))));
            }
            if(rad_od_kuce!=null && !rad_od_kuce.get(0).equals("none")){
                skupOglasa.retainAll(oglasRepository.findByRadOdKuce(rad_od_kuce.get(0).equals("1")));
            }

        }

        List<Oglas> listaOglasa =new ArrayList<Oglas>(skupOglasa);
        if(tip_sortiranja!=null) {
            String sort = tip_sortiranja.get(0);
            switch(sort){
                case "stari":
                    listaOglasa.sort(new AscSortById());
                    break;
                case "lajkovi":
                    listaOglasa.sort(new SortByLikes());
                    break;
                case "pregledi":
                    listaOglasa.sort(new SortByViews());
                    break;
                case "prijave":
                    listaOglasa.sort(new SortByPrijave());
                    break;
                case "plata":
                    listaOglasa.sort(new SortByPlata());
                    break;
                default:
                    listaOglasa.sort(new DescSortById());
                    break;
            }
        }
        else{
            listaOglasa.sort(new DescSortById());
        }

        for (Oglas oglas : listaOglasa) {
            listaPoslodavaca.add(korisnikRepository.findById(oglas.getIdOglasavaca()).get());
            listaLokacija.add(lokacijaRepository.findById(oglas.getIdLokacije()).get());
            listaKategorija.add(kategorijaRepository.findById(oglas.getIdKategorije()).get());
        }


        model.addAttribute("poslovi", listaOglasa);
        model.addAttribute("poslodavci", listaPoslodavaca);
        model.addAttribute("lokacije", listaLokacija);
        model.addAttribute("kategorije", listaKategorija);
        model.addAttribute("pregledi",oglasRepository.sumOfViewsByIdOglasavaca(userDetails.getKorisnikId()));
        model.addAttribute("prijave", oglasRepository.sumOfPrijaveByIdOglasavaca(userDetails.getKorisnikId()));
        model.addAttribute("lajkovi", oglasRepository.sumOfLikesByIdOglasavaca(userDetails.getKorisnikId()));
        model.addAttribute("brojOglasa",oglasRepository.countOfOglasByIdOglasavaca(userDetails.getKorisnikId()));


        //lista svh kategorija za filter
        List<Kategorija> sveKategorije = kategorijaRepository.findAll();
        model.addAttribute("filterKategorije", sveKategorije);
        //lista svih lokacija za filter
        List<Lokacija> sveLokacije = lokacijaRepository.findAll();
        model.addAttribute("filterLokacije", sveLokacije);
        //lista svih podkategorija
        List<Podkategorija> svePodkategorije=podkategorijaService.findAll();
        model.addAttribute("filterPodkategorije",svePodkategorije);
        return "moji_oglasi";
    }

    @PostMapping("/proces_postavi_komentar")
    public String postaviKomentar(Model model,
                                  @RequestParam("tekstKomentara") String tekst,
                                  @RequestParam("idOglasa") String idOglasa){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();

        Komentar k=new Komentar(parseInt(idOglasa),tekst,korisnikRepository.findById(userDetails.getKorisnikId()).get());

        komentarRepository.save(k);
        oglasRepository.findById(parseInt(idOglasa)).get().getKomentari().add(k);

        return "redirect:/detalji_oglasa?id="+idOglasa;
    }
}
