package cn.citycraft.AuthMe.process.logout;

import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitScheduler;

import cn.citycraft.AuthMe.AuthMe;
import cn.citycraft.AuthMe.Utils;
import cn.citycraft.AuthMe.Utils.GroupType;
import cn.citycraft.AuthMe.cache.auth.PlayerAuth;
import cn.citycraft.AuthMe.cache.auth.PlayerCache;
import cn.citycraft.AuthMe.cache.limbo.LimboCache;
import cn.citycraft.AuthMe.datasource.DataSource;
import cn.citycraft.AuthMe.settings.Messages;
import cn.citycraft.AuthMe.settings.Settings;
import fr.xephi.authme.events.AuthMeTeleportEvent;

public class AsyncronousLogout {

	private Messages m = Messages.getInstance();
	protected boolean canLogout = true;
	protected DataSource database;
	protected String name;
	protected Player player;
	protected AuthMe plugin;

	public AsyncronousLogout(Player player, AuthMe plugin, DataSource database) {
		this.player = player;
		this.plugin = plugin;
		this.database = database;
		this.name = player.getName().toLowerCase();
	}

	public void process() {
		preLogout();
		if (!canLogout)
			return;
		final Player p = player;
		BukkitScheduler sched = p.getServer().getScheduler();
		PlayerAuth auth = PlayerCache.getInstance().getAuth(name);
		database.updateSession(auth);
		auth.setQuitLocX(p.getLocation().getX());
		auth.setQuitLocY(p.getLocation().getY());
		auth.setQuitLocZ(p.getLocation().getZ());
		auth.setWorld(p.getWorld().getName());
		database.updateQuitLoc(auth);

		PlayerCache.getInstance().removePlayer(name);
		database.setUnlogged(name);
		if (Settings.isTeleportToSpawnEnabled && !Settings.noTeleport) {
			Location spawnLoc = plugin.getSpawnLocation(p);
			final AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(p, spawnLoc);
			sched.scheduleSyncDelayedTask(plugin, new Runnable() {

				@Override
				public void run() {
					plugin.getServer().getPluginManager().callEvent(tpEvent);
					if (!tpEvent.isCancelled()) {
						if (tpEvent.getTo() != null)
							p.teleport(tpEvent.getTo());
					}
				}
			});
		}

		if (LimboCache.getInstance().hasLimboPlayer(name))
			LimboCache.getInstance().deleteLimboPlayer(name);
		LimboCache.getInstance().addLimboPlayer(player);
		Utils.setGroup(player, GroupType.NOTLOGGEDIN);

		sched.scheduleSyncDelayedTask(plugin, new ProcessSyncronousPlayerLogout(p, plugin));
	}

	private void preLogout() {
		if (!PlayerCache.getInstance().isAuthenticated(name)) {
			m.send(player, "not_logged_in");
			canLogout = false;
		}
	}
}
