package linea;

import java.awt.GridLayout;
import java.util.List;
import javax.swing.ButtonGroup;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.UIManager;

public class LineaAppli {

	private static class SelectionJeu {
		final int idCompte;
		final boolean modeCampagne;

		SelectionJeu(int idCompte, boolean modeCampagne) {
			this.idCompte = idCompte;
			this.modeCampagne = modeCampagne;
		}
	}

	private static String choisirPseudo(DatabaseConnection db, String message, int messageType) {
		List<String> pseudos = db.getPseudos();
		if (pseudos.isEmpty()) {
			JOptionPane.showMessageDialog(null, "Aucun compte disponible.");
			return null;
		}

		return (String) JOptionPane.showInputDialog(
				null,
				message,
				"Comptes",
				messageType,
				null,
				pseudos.toArray(String[]::new),
				pseudos.get(0)
		);
	}

	private static int choisirNiveau() {
		// Générer les niveaux dynamiquement jusqu'à 100
		String[] niveaux = new String[100];
		for (int i = 1; i <= 100; i++) {
			niveaux[i - 1] = genererLabelNiveau(i);
		}
		
		JList<String> list = new JList<>(niveaux);
		list.setSelectedIndex(0);
		list.setVisibleRowCount(15);
		JScrollPane scrollPane = new JScrollPane(list);
		scrollPane.setPreferredSize(new java.awt.Dimension(350, 350));
		
		int result = JOptionPane.showConfirmDialog(
				null,
				scrollPane,
				"🎮 Sélection du Niveau - Linea",
				JOptionPane.OK_CANCEL_OPTION,
				JOptionPane.QUESTION_MESSAGE
		);
		
		if (result == JOptionPane.OK_OPTION) {
			return list.getSelectedIndex() + 1;
		}
		return -1;
	}

	private static int choisirNiveauCampagne(DatabaseConnection db, int idCompte) {
		int niveauMaxDebloque = db.getNiveauDebloqueCampagne(idCompte);
		if (niveauMaxDebloque < 1) {
			niveauMaxDebloque = 1;
		}

		String[] niveaux = new String[niveauMaxDebloque];
		for (int i = 1; i <= niveauMaxDebloque; i++) {
			niveaux[i - 1] = genererLabelNiveau(i);
		}

		JList<String> list = new JList<>(niveaux);
		list.setSelectedIndex(niveauMaxDebloque - 1);
		list.setVisibleRowCount(15);
		JScrollPane scrollPane = new JScrollPane(list);
		scrollPane.setPreferredSize(new java.awt.Dimension(350, 350));

		int result = JOptionPane.showConfirmDialog(
				null,
				scrollPane,
				"🏆 Campagne - Niveaux débloqués (1 à " + niveauMaxDebloque + ")",
				JOptionPane.OK_CANCEL_OPTION,
				JOptionPane.QUESTION_MESSAGE
		);

		if (result == JOptionPane.OK_OPTION) {
			return list.getSelectedIndex() + 1;
		}
		return -1;
	}
	
	private static String genererLabelNiveau(int niveau) {
		if (niveau <= 2) {
			return "⭐ Niveau " + niveau + " - Facile" + (niveau == 2 ? "+" : "");
		} else if (niveau <= 4) {
			return "⭐⭐ Niveau " + niveau + " - Moyen" + (niveau == 4 ? "+" : "");
		} else if (niveau <= 6) {
			return "⭐⭐⭐ Niveau " + niveau + " - Difficile" + (niveau == 6 ? "+" : "");
		} else if (niveau <= 8) {
			return "⭐⭐⭐⭐ Niveau " + niveau + " - Très Difficile" + (niveau == 8 ? "+" : "");
		} else if (niveau <= 10) {
			return "⭐⭐⭐⭐⭐ Niveau " + niveau + " - Expert" + (niveau == 10 ? "+" : "");
		} else if (niveau <= 12) {
			return "🔥 Niveau " + niveau + " - Cauchemar" + (niveau == 12 ? "+" : "");
		} else if (niveau <= 14) {
			return "🔥 Niveau " + niveau + " - Chaos" + (niveau == 14 ? "+" : "");
		} else if (niveau <= 16) {
			return "💀 Niveau " + niveau + " - Infernal" + (niveau == 16 ? "+" : "");
		} else if (niveau <= 18) {
			return "💀 Niveau " + niveau + " - Apocalypse" + (niveau == 18 ? "+" : "");
		} else if (niveau <= 20) {
			return "⚡ Niveau " + niveau + " - Extrême" + (niveau == 20 ? "+" : "");
		} else if (niveau <= 30) {
			return "⚡ Niveau " + niveau + " - Infini";
		} else if (niveau <= 50) {
			return "∞ Niveau " + niveau + " - Au-delà";
		} else {
			return "🌌 Niveau " + niveau + " - Cosmos";
		}
	}

	private static Integer menuComptes(DatabaseConnection db) {
		while (true) {
			Object[] options = {"Sélectionner", "Créer", "Supprimer", "Retour"};
			int choix = JOptionPane.showOptionDialog(
					null,
					"Gestion des comptes :",
					"Comptes",
					JOptionPane.DEFAULT_OPTION,
					JOptionPane.QUESTION_MESSAGE,
					null,
					options,
					options[0]
			);

			if (choix == JOptionPane.CLOSED_OPTION || choix == 3) return null;

			switch (choix) {
				case 0 -> {
					String pseudo = choisirPseudo(db, "Sélectionnez un compte :", JOptionPane.QUESTION_MESSAGE);
					if (pseudo != null) return db.getIdParPseudo(pseudo);
				}
				case 1 -> {
					String pseudo = JOptionPane.showInputDialog(null, "Nouveau pseudo :");
					if (pseudo == null || pseudo.trim().isEmpty()) continue;
					pseudo = pseudo.trim();
					int id = db.getIdParPseudo(pseudo);
					return id > 0 ? id : db.creerCompte(pseudo);
				}
				case 2 -> {
					String pseudo = choisirPseudo(db, "Sélectionnez le compte à supprimer :", JOptionPane.WARNING_MESSAGE);
					if (pseudo == null) continue;
					int confirm = JOptionPane.showConfirmDialog(
							null,
							"Supprimer le compte \"" + pseudo + "\" et toute sa progression ?",
							"Confirmation",
							JOptionPane.YES_NO_OPTION
					);
					if (confirm == JOptionPane.YES_OPTION) {
						int id = db.getIdParPseudo(pseudo);
						if (id > 0) db.supprimerCompte(id);
					}
				}
			}
		}
	}

	private static SelectionJeu choisirCompteEtModeRapide(DatabaseConnection db) {
		while (true) {
			List<String> pseudos = db.getPseudos();

			JPanel panel = new JPanel(new GridLayout(0, 1, 8, 8));
			panel.add(new JLabel("Compte :"));

			String[] optionsCompte = new String[pseudos.size() + 2];
			optionsCompte[0] = "Sans compte";
			for (int i = 0; i < pseudos.size(); i++) {
				optionsCompte[i + 1] = pseudos.get(i);
			}
			optionsCompte[optionsCompte.length - 1] = "Gérer les comptes...";

			JComboBox<String> comboCompte = new JComboBox<>(optionsCompte);
			panel.add(comboCompte);

			panel.add(new JLabel("Mode :"));
			JRadioButton modeClassique = new JRadioButton("Classique", true);
			JRadioButton modeCampagne = new JRadioButton("Campagne");
			ButtonGroup group = new ButtonGroup();
			group.add(modeClassique);
			group.add(modeCampagne);

			JPanel panelMode = new JPanel(new GridLayout(1, 2, 8, 0));
			panelMode.add(modeClassique);
			panelMode.add(modeCampagne);
			panel.add(panelMode);

			int result = JOptionPane.showConfirmDialog(
					null,
					panel,
					"Jouer rapidement",
					JOptionPane.OK_CANCEL_OPTION,
					JOptionPane.QUESTION_MESSAGE
			);

			if (result != JOptionPane.OK_OPTION) {
				return null;
			}

			String choixCompte = (String) comboCompte.getSelectedItem();
			if (choixCompte == null) {
				return null;
			}

			if ("Gérer les comptes...".equals(choixCompte)) {
				menuComptes(db);
				continue;
			}

			int idCompte = "Sans compte".equals(choixCompte) ? -1 : db.getIdParPseudo(choixCompte);
			boolean campagne = modeCampagne.isSelected();
			return new SelectionJeu(idCompte, campagne);
		}
	}

	//-------------------------------------------------------------------------
	// Classe de base de l'application, rien à modifier ici
	//-------------------------------------------------------------------------	
	public static void main(String[] arg) {
		UIManager.put("OptionPane.yesButtonText", "Oui");
		UIManager.put("OptionPane.noButtonText", "Non");
		UIManager.put("OptionPane.cancelButtonText", "Retour");

		DatabaseConnection db = new DatabaseConnection();
		db.connect();
		db.createTables();

		while (true) {
			SelectionJeu selection = choisirCompteEtModeRapide(db);
			if (selection == null) {
				return;
			}

			if (!selection.modeCampagne) {
				int niveau = choisirNiveau();
				if (niveau > 0) {
					new Jeu(db, selection.idCompte, niveau).demarrer();
					return;
				}
				continue;
			}

			if (selection.idCompte > 0) {
				int niveau = choisirNiveauCampagne(db, selection.idCompte);
				if (niveau > 0) {
					new Jeu(db, selection.idCompte, niveau, true).demarrer();
					return;
				}
				continue;
			}

			JOptionPane.showMessageDialog(
					null,
					"Campagne sans compte : progression non sauvegardée.",
					"Campagne",
					JOptionPane.INFORMATION_MESSAGE
			);
			new Jeu(db, -1, 1, true).demarrer();
			return;
		}
	}
}
