package fr.Skydust.JdrBot.cmds.playmusic;

import java.util.HashMap;
import java.util.Map;

import fr.Skydust.JdrBot.bases.command.Command;
import fr.Skydust.JdrBot.bases.command.CommandSpec;
import fr.Skydust.JdrBot.jukebox.JukeboxSystem;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;

import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;

import fr.Skydust.JdrBot.audio.GuildMusicManager;

@CommandSpec(
		name = "playmusic|pm",
		description = "(Admin) Demarre le jukebox"
)
public class PlayMusic extends Command {
	private static final AudioPlayerManager playerManager = new DefaultAudioPlayerManager();
	static Map<Long, GuildMusicManager> musicManagers;

	public static HashMap<Long, JukeboxSystem> jukeboxSystems = new HashMap<>();

    public PlayMusic() {
		super();

	    musicManagers = new HashMap<>();
	    AudioSourceManagers.registerRemoteSources(playerManager);
	    AudioSourceManagers.registerLocalSource(playerManager);
    }

	@Override
	public void call(MessageReceivedEvent e) {
    	if(!e.getMember().hasPermission(Permission.ADMINISTRATOR)) {
    		return;
    	}

    	if(getGuildsJukebox(e.getGuild()) != null) {
    		e.getChannel().sendMessage("/!\\ Le lecteur audio est deja present ici ! Pour l'arreter, tapez \"!stopmusic\" !").queue();
    		return;
    	}

		if(!e.getMember().getVoiceState().inAudioChannel()) {
			e.getChannel().sendMessage("/!\\ Vous devez être dans un channel vocal").queue();
			return;
		}

		// Create a new JukeboxSystem for the guild
		JukeboxSystem jukeboxSystem = new JukeboxSystem();
		jukeboxSystems.put(e.getGuild().getIdLong(), jukeboxSystem);

		// Creates a message to be edited by the jukebox system
		e.getGuild().getAudioManager().openAudioConnection(e.getMember().getVoiceState().getChannel());
		e.getChannel().sendMessage("Chargement...").queue(jukeboxSystem::load);
    }

	public static JukeboxSystem getGuildsJukebox(Guild guild) {
		return jukeboxSystems.get(guild.getIdLong());
	}

	public static void loadAndPlay(final Guild guild, final TextChannel channel, final String trackUrl, boolean loop, boolean nomsg) {
		System.out.println(trackUrl);

		GuildMusicManager musicManager = getGuildAudioPlayer(guild);
		playerManager.loadItemOrdered(musicManager, trackUrl, new AudioLoadResultHandler() {
			@Override
			public void trackLoaded(AudioTrack track) {
				if(!nomsg) {
					channel.sendMessage("**Now Playing**: "+track.getInfo().title).queue();
				}
				musicManager.scheduler.play(track, loop);
			}

			@Override
			public void playlistLoaded(AudioPlaylist playlist) {
				AudioTrack firstTrack = playlist.getSelectedTrack();

				if (firstTrack == null) {
					firstTrack = playlist.getTracks().get(0);
				}

				if(!nomsg) {
					channel.sendMessage("**Now Playing**: "+firstTrack.getInfo().title).queue();
				}
				musicManager.scheduler.play(firstTrack, loop);
			}

			@Override
			public void noMatches() {
			}

			@Override
			public void loadFailed(FriendlyException exception) {
				channel.sendMessage(exception.getMessage()).queue();
			}
		});
	}

	public static synchronized GuildMusicManager getGuildAudioPlayer(Guild guild) {
		long guildId = Long.parseLong(guild.getId());
		GuildMusicManager musicManager = musicManagers.get(guildId);

		if (musicManager == null) {
			musicManager = new GuildMusicManager(playerManager, guild.getAudioManager());
			musicManagers.put(guildId, musicManager);
		}

		guild.getAudioManager().setSendingHandler(musicManager.getSendHandler());

		return musicManager;
	}
}
