package gui.menu;

import java.util.Random;
import java.util.concurrent.CancellationException;

import gui.SudokuRenderer;
import imgui.ImGui;
import imgui.ImGuiStyle;
import sudoku.io.SudokuSerializer;
import sudoku.solver.Solver;
import sudoku.structure.MultiDoku;

public class SudokuView extends BaseView {

	private final SudokuRenderer sudokuRenderer;
	private Thread resolveThread;
	private final MultiDoku doku;
	private String lastSavePath = null;

	private boolean resolved = false;

	public SudokuView(StateMachine stateMachine, MultiDoku doku) {
		super(stateMachine);
		this.doku = doku;
		this.sudokuRenderer = new SudokuRenderer(doku);
		this.sudokuRenderer.onResolve.connect(this::onResolve);
	}

	private void onResolve() {
		this.resolved = true;
	}

	private void stopResolve() {
		if (resolveThread != null && resolveThread.isAlive()) {
			resolveThread.interrupt();
			resolveThread = null;
		}
	}

	boolean centeredButton(String label) {
		ImGuiStyle style = ImGui.getStyle();

		float size = ImGui.calcTextSizeX(label) + style.getFramePaddingX() * 2.0f;
		float avail = ImGui.getContentRegionAvailX();

		float off = (avail - size) * 0.5f;
		if (off > 0.0f)
			ImGui.setCursorPosX(ImGui.getCursorPosX() + off);

		return ImGui.button(label);
	}

	private void renderCancelButton() {
		boolean wantsToStop = false;
		if (resolveThread != null && resolveThread.isAlive()) {
			// ImGui.endDisabled();
			if (centeredButton("Annuler")) {
				// we can't stop the Thread right now
				wantsToStop = true;
			}
		}
		if (resolveThread != null && !resolveThread.isAlive()) {
			resolveThread.start();
		}
		if (wantsToStop)
			stopResolve();
	}

	private void renderSolveButton() {
		if (resolveThread != null)
			ImGui.beginDisabled();

		boolean beginSolve = false;

		if (!resolved && centeredButton("Résoudre")) {
			beginSolve = true;
		}
		if (resolveThread != null)
			ImGui.endDisabled();

		if (beginSolve) {
			resolveThread = new Thread(() -> {
				try {
					Random rand = new Random();
					Solver.solveRandom(doku, rand);
					Thread.sleep(200);
				} catch (CancellationException | InterruptedException e) {
					System.out.println("The user is bored !");
				}
				stopResolve();
			});
		}

		if (resolved) {
			ImGui.text("Bravo !");
		}
	}

	private void renderSaveButton() {
		if (ImGui.button("Sauvegarder l'état de la grille")) {
			lastSavePath = SudokuSerializer.saveMultiDoku(doku);
			ImGui.openPopup("saveDone");
		}
		if (ImGui.beginPopup("saveDone")) {
			ImGui.text("Sudoku sauvegardé dans ");
			ImGui.text(lastSavePath);
			ImGui.endPopup();
		}
	}

	@Override
	public void render() {
		sudokuRenderer.render();
		renderSolveButton();
		renderSaveButton();
		renderCancelButton();
		renderReturnButton();
	}

	@Override
	public void closeMenu() {
		super.closeMenu();
		stopResolve();
	}

}
