package hozza.network.crons.twitch;


import java.net.URL;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;

import com.fasterxml.jackson.databind.ObjectMapper;

import hozza.network.models.twitch.entities.MariaPerson;
import hozza.network.models.twitch.entities.MariaStreamer;
import hozza.network.models.twitch.entities.MariaWatching;
import hozza.network.models.twitch.repositories.MariaPersonRepository;
import hozza.network.models.pojo.twitch.Root;

public class TwitchServiceCallable implements Callable<Boolean> {
    private final MariaPersonRepository personRepository;
    private final MariaStreamer streamer;
    private final List<MariaPerson> viewers;
    private final ZonedDateTime cronStarted;
    private final List<MariaWatching> watchingToSave;
    private final AtomicInteger possibleEntries;

    public TwitchServiceCallable(MariaStreamer streamer, List<MariaPerson> viewers, ZonedDateTime cronStarted, MariaPersonRepository personRepository, List<MariaWatching> watchingToSave, AtomicInteger possibleEntries) {
        this.streamer = streamer;
        this.viewers = viewers;
        this.cronStarted = cronStarted;
        this.personRepository = personRepository;
        this.watchingToSave = watchingToSave;
        this.possibleEntries = possibleEntries;
    }

    @Override
    public Boolean call() throws Exception {
        String url = "https://tmi.twitch.tv/group/user/" + streamer.getChannel().toLowerCase() + "/chatters";
        ObjectMapper mapper = new ObjectMapper();
        Root root = mapper.readValue(new URL(url), Root.class);
        synchronized (possibleEntries)
        {
            this.possibleEntries.addAndGet(root.chatters.viewers.size());
        }
        root.chatters.viewers.forEach(viewer -> {
            synchronized (this.viewers) 
            {
                MariaPerson person = this.viewers.stream().filter(v -> v.getName().equals(viewer)).findFirst().orElse(null);
                if(person == null)
                {
                    person = new MariaPerson(viewer, this.cronStarted.toLocalDate());
                    this.personRepository.save(person);
                    this.viewers.add(person);
                }

                MariaWatching watching = new MariaWatching(this.cronStarted.toLocalDateTime(), this.streamer, person);
                synchronized(this.watchingToSave)
                {
                    this.watchingToSave.add(watching);
                }
            }
        });
        return true;
    }
}