package cn.citycraft.AuthMe.process.quit;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;

import cn.citycraft.AuthMe.AuthMe;
import cn.citycraft.AuthMe.Utils;
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.cache.limbo.LimboPlayer;
import cn.citycraft.AuthMe.datasource.DataSource;
import cn.citycraft.AuthMe.listener.AuthMePlayerListener;
import cn.citycraft.AuthMe.settings.Settings;

public class AsyncronousQuit {

	private boolean isFlying = false;
	private boolean isKick = false;
	private boolean isOp = false;
	private String name;
	private boolean needToChange = false;
	protected DataSource database;
	protected Player player;
	protected AuthMe plugin;

	public AsyncronousQuit(Player p, AuthMe plugin, DataSource database, boolean isKick) {
		this.player = p;
		this.plugin = plugin;
		this.database = database;
		this.name = p.getName().toLowerCase();
		this.isKick = isKick;
	}

	public void process() {
		if (player == null)
			return;
		if (Utils.isNPC(player) || Utils.isUnrestricted(player)) {
			return;
		}

		String ip = plugin.getIP(player);

		if (PlayerCache.getInstance().isAuthenticated(name)) {
			if (Settings.isSaveQuitLocationEnabled && database.isAuthAvailable(name)) {
				Location loc = player.getLocation();
				PlayerAuth auth = new PlayerAuth(name, loc.getX(), loc.getY(), loc.getZ(), loc.getWorld().getName(), player.getName());
				database.updateQuitLoc(auth);
			}
			PlayerAuth auth = new PlayerAuth(name, ip, System.currentTimeMillis(), player.getName());
			database.updateSession(auth);
		}

		if (LimboCache.getInstance().hasLimboPlayer(name)) {
			LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
			if (limbo.getGroup() != null && !limbo.getGroup().equals(""))
				Utils.addNormal(player, limbo.getGroup());
			needToChange = true;
			isOp = limbo.getOperator();
			isFlying = limbo.isFlying();
			if (limbo.getTimeoutTaskId() != null)
				limbo.getTimeoutTaskId().cancel();
			if (limbo.getMessageTaskId() != null)
				limbo.getMessageTaskId().cancel();
			LimboCache.getInstance().deleteLimboPlayer(name);
		}
		if (Settings.isSessionsEnabled && !isKick) {
			if (Settings.getSessionTimeout != 0) {
				BukkitTask task = plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() {

					@Override
					public void run() {
						PlayerCache.getInstance().removePlayer(name);
						if (database.isLogged(name))
							database.setUnlogged(name);
						plugin.sessions.remove(name);
					}

				}, Settings.getSessionTimeout * 20 * 60);
				plugin.sessions.put(name, task);
			}
		} else {
			PlayerCache.getInstance().removePlayer(name);
			database.setUnlogged(name);
		}

		AuthMePlayerListener.gameMode.remove(name);
		Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new ProcessSyncronousPlayerQuit(plugin, player, isOp, isFlying, needToChange));
	}
}
