import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Iterator;

public class Game {

	private static final int LOGIN_PHASE = 0;
	private static final int GAME_PHASE = 1;
	private static final int END_PHASE = 2;

	WordleServer wordleServer;
	User user;
	static DatabaseConnector databaseConnector;// Datenbankverbindung aufstellen

	private String ip;
	private int port;

	private String wordle;
	private String[] words;
	private int count;
	private int phase;

	private String tempLoginName;

	static {

		databaseConnector = new DatabaseConnector(null, 0, "wordle.db", null, null);

		if (databaseConnector.getErrorMessage() != null) {
			System.err.println(databaseConnector.getErrorMessage());
		}

	}

	public Game(WordleServer wordleServer, String pClientIP, int pClientPort) {

		this.wordleServer = wordleServer;
		this.ip = pClientIP;
		this.port = pClientPort;

		send("+OK Hello there");
	}

	public void processMessage(String msg) {

		msg = msg.toLowerCase().trim();

		if (msg.equals("quit")) {
			send("+OK bye");
			wordleServer.closeConnection(ip, port);
			System.exit(0); // TODO remove: Einfacher zum testen
		}

		switch (phase) {
		case LOGIN_PHASE:
			loginPhase(msg);
			break;
		case GAME_PHASE:
			gamePhase(msg);
			break;
		case END_PHASE:
			endPhase(msg);
			break;
		}
	}

	private void loginPhase(String msg) {

		if (msg.startsWith("user ")) {

			if (msg.length() <= 5) {
				sendUniversalError();
				return;
			}
			String args = msg.substring(5);

			databaseConnector.executeStatement("SELECT * FROM User WHERE name = '" + args + "'");
			QueryResult result = databaseConnector.getCurrentQueryResult();
			if (result != null && result.getData().length > 0) {
				tempLoginName = result.getData()[0][0];
				send("+OK");
			} else {
				send("-ERR User not found.");
			}

		} else if (msg.startsWith("pass ")) {

			if (msg.length() <= 5) {
				sendUniversalError();
				return;
			}
			String args = msg.substring(5);

			int pw = args.hashCode();
			databaseConnector.executeStatement(
					"SELECT * FROM User WHERE password = '" + pw + "' AND name = '" + tempLoginName + "'");
			QueryResult result = databaseConnector.getCurrentQueryResult();
			if (result != null && result.getData().length > 0) {
				user = new User(tempLoginName);
				send("+OK welcome");
			} else {
				send("-ERR login not valid");
			}
		} else if (msg.startsWith("wotd")) {

			databaseConnector.executeStatement("SELECT word FROM words WHERE id = " + getWOTDIndex());
			QueryResult result = databaseConnector.getCurrentQueryResult();
			if (result != null && result.getData().length > 0) {
				wordle = result.getData()[0][0].toLowerCase();
				phase = GAME_PHASE;
				send("+OK game ready");
			} else {
				send("-ERR fatal error: WOTD could not be generated.");
			}

		} else if (msg.startsWith("play")) {

			if (user == null) {
				send("-ERR not logged in.");
			} else {
				databaseConnector.executeStatement("SELECT word FROM words WHERE id = " + (int) (Math.random() * 950));
				QueryResult result = databaseConnector.getCurrentQueryResult();
				if (result != null && result.getData().length > 0) {
					wordle = result.getData()[0][0].toLowerCase();
					phase = GAME_PHASE;
					send("+OK game ready");
				} else {
					send("-ERR fatal error: Wordle could not be generated.");
				}
			}
		} else {
			sendUniversalError();
		}
	}

	private void gamePhase(String msg) {

		if (msg.startsWith("send ")) {

			String args = msg.substring(5);

			if (args.length() == 5) {

				databaseConnector.executeStatement("SELECT word FROM words WHERE word LIKE '" + args + "'");
				QueryResult result = databaseConnector.getCurrentQueryResult();
				if (result.getData().length > 0) {

					String input = result.getData()[0][0].toLowerCase();
					String code = "";

					outer: for (int i = 0; i < input.length(); i++) {
						char c = input.charAt(i);
						if (c == wordle.charAt(i)) {
							code += "2";
						} else {
							for (int j = 0; j < wordle.length(); j++) {
								if (c == wordle.charAt(j)) {
									code += "1";
									continue outer;
								}
							}
							code += "0";
						}
					}

					send(code);
					if (code.equals("22222")) { // und ein wordle ist 5 Buchstaben lang :D
						send("game won");
						if (user != null) {
							phase = END_PHASE;
						} else {
							phase = LOGIN_PHASE;
						}
					} else if (count == 6) {
						send("game lost");
						if (user != null) {
							phase = END_PHASE;
						} else {
							phase = LOGIN_PHASE;
						}
					} else {
						send("game continues");
					}

				} else {
					send("-ERR word not in dictionary.");
				}

			} else {
				send("-ERR wrong format.");
			}

		} else if (msg.startsWith("info")) {

		} else if (msg.startsWith("exit")) {

			if (user != null) {
				phase = END_PHASE;
			} else {
				send("-ERR not logged in.");
			}

		} else {
			sendUniversalError();
		}
	}

	private void endPhase(String msg) {

		if (msg.startsWith("stat")) {

			databaseConnector.executeStatement("SELECT timesPlayed FROM User Where name like " + tempLoginName + "");
			String tP = databaseConnector.getCurrentQueryResult().getData()[0][0];
			send("times Played: " + tP);

			databaseConnector.executeStatement("SELECT winPercentage FROM User Where name like " + tempLoginName + "");
			String wP = databaseConnector.getCurrentQueryResult().getData()[0][0];
			send("win Percentage: " + wP);

			databaseConnector.executeStatement("SELECT currentStreak FROM User Where name like " + tempLoginName + "");
			String cS = databaseConnector.getCurrentQueryResult().getData()[0][0];
			send("current Streak: " + cS);

			databaseConnector.executeStatement("SELECT maxStreak FROM User Where name like " + tempLoginName + "");
			String mS = databaseConnector.getCurrentQueryResult().getData()[0][0];
			send("max Streak: " + mS);

			databaseConnector.executeStatement("SELECT wonInTurn1 FROM User Where name like " + tempLoginName + "");
			String wIT1 = databaseConnector.getCurrentQueryResult().getData()[0][0];
			send("won in Turn1: " + wIT1);

			databaseConnector.executeStatement("SELECT wonInTurn1 FROM User Where name like " + tempLoginName + "");
			String wIT2 = databaseConnector.getCurrentQueryResult().getData()[0][0];
			send("won in Turn2: " + wIT2);

			databaseConnector.executeStatement("SELECT wonInTurn1 FROM User Where name like " + tempLoginName + "");
			String wIT3 = databaseConnector.getCurrentQueryResult().getData()[0][0];
			send("won in Turn3: " + wIT3);

			databaseConnector.executeStatement("SELECT wonInTurn1 FROM User Where name like " + tempLoginName + "");
			String wIT4 = databaseConnector.getCurrentQueryResult().getData()[0][0];
			send("won in Turn4: " + wIT4);

			databaseConnector.executeStatement("SELECT wonInTurn1 FROM User Where name like " + tempLoginName + "");
			String wIT5 = databaseConnector.getCurrentQueryResult().getData()[0][0];
			send("won in Turn5: " + wIT5);

			databaseConnector.executeStatement("SELECT wonInTurn1 FROM User Where name like " + tempLoginName + "");
			String wIT6 = databaseConnector.getCurrentQueryResult().getData()[0][0];
			send("won in Turn6: " + wIT6);

		} else if (msg.startsWith("play")) {

			phase = GAME_PHASE;

		}
	}

	private void send(String msg) {

		wordleServer.send(ip, port, msg);
	}

	private void sendUniversalError() {

		send("-ERR command not valid in this state");
	}

	private int getWOTDIndex() {

		long days = ChronoUnit.DAYS.between(LocalDate.ofEpochDay(0), LocalDate.now());
		int hash = ("" + days).hashCode();
		return hash % 949 + 1;
	}

	public String getIp() {

		return ip;
	}

	public void setIp(String ip) {

		this.ip = ip;
	}

	public int getPort() {

		return port;
	}

	public void setPort(int port) {

		this.port = port;
	}
}
