package sudoku;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import sudoku.core.Console;

public class Grille {
    private final int taille;
    private final Case[][] cases;
    private final ArrayList<Bloc> blocs;
    private ArrayList<Symbole> symbolesPossibles;
    
        public Grille(int taille) {
            this.taille = taille;
            this.cases = new Case[taille][taille];
            this.blocs = new ArrayList<>();
            this.symbolesPossibles = new ArrayList<>();
    
            // Initialiser les cases
            for (int i = 0; i < taille; i++) {
                for (int j = 0; j < taille; j++) {
                    cases[i][j] = new Case(i, j, null);
                }
            }
        }
    
        public void setCase(int ligne, int colonne, Symbole symbole) {
            try {
                if (symbole != null && !symbolesPossibles.contains(symbole)) {
                    throw new IllegalArgumentException("Symbole non autorisé : " + symbole);
                }
                cases[ligne][colonne].setSymbole(symbole);
            } catch (Exception e) {
                Console.errorln(e.getMessage());
            }
            
        }
    
        public Case getCase(int ligne, int colonne) {
            return cases[ligne][colonne];
        }
    
        /**
         * Crée un bloc à partir des positions spécifiées
            
            Exemple :
            sudoku.getGrille().createBloc(Arrays.asList(
            new int[] { 0, 0 },
            new int[] { 0, 1 },
            new int[] { 0, 2 },
            new int[] { 1, 0 },
            new int[] { 1, 1 },
            new int[] { 1, 2 },
            new int[] { 2, 0 },
            new int[] { 2, 1 },
            new int[] { 2, 2 }));
         * @param positions
         * @return
         */
        public Bloc createBloc(List<int[]> positions) {
            Bloc bloc = new Bloc();
            for (int[] pos : positions) {
                bloc.addCase(cases[pos[0]][pos[1]]);
            }
            blocs.add(bloc);
            return bloc;
        }
    
        public void createSquareBlocs() {
            try {
                int blocSize = (int) Math.sqrt(taille);
                if (blocSize * blocSize != taille) {
                    throw new IllegalArgumentException("La taille de la grille doit être un carré parfait.");
                }
                for (int i = 0; i < taille; i += blocSize) {
                    for (int j = 0; j < taille; j += blocSize) {
                        List<int[]> positions = new ArrayList<>();
                        for (int k = 0; k < blocSize; k++) {
                            for (int l = 0; l < blocSize; l++) {
                                positions.add(new int[] { i + k, j + l });
                            }
                        }
                        createBloc(positions);
                    }
                }
            } catch (IllegalArgumentException e) {
                Console.errorln(e.getMessage());
            }
        }
    
        // TO MOVE TO FUTUR CONSTRAINTS
        // public boolean isValid() {
        //     for (Bloc bloc : blocs) {
        //         if (!bloc.isValid()) {
        //             return false;
        //         }
        //     }
        //     return true;
        // }
    
        public void printBlocs() {
            for (Bloc bloc : blocs) {
                System.out.println(bloc.toString());
            }
        }
    
        public void askSetSymbolesPossibles() {
            try (Scanner scanner = new Scanner(System.in)) {
                System.out.println(("Choisissez le type de symboles :"));
                System.out.println(("1. Nombres"));
                System.out.println(("2. Caractères"));
                System.out.println(("3. Texte/Emoji"));
    
                int choix = 0;
                try {
                    choix = Integer.parseInt(scanner.nextLine());
                } catch (NumberFormatException e) {
                    Console.errorln("Choix invalide");
                    return;
                }
    
                for (int i = 0; i < taille; i++) {
                    System.out.println(("Entrez le symbole " + (i + 1) + "/" + taille + " :"));
                    String input = scanner.nextLine();
    
                    switch (choix) {
                        case 1: // Nombres
                            try {
                                symbolesPossibles.add(Symbole.of(Integer.parseInt(input)));
                            } catch (NumberFormatException e) {
                                Console.errorln("Veuillez entrer un nombre valide");
                                i--;
                            }
                            break;
    
                        case 2: // Caractères
                            if (input.length() == 1) {
                                symbolesPossibles.add(Symbole.of(input.charAt(0)));
                            } else {
                                Console.errorln("Veuillez entrer un seul caractère");
                                i--;
                            }
                            break;
    
                        case 3: // Texte/Emoji
                            if (!input.isEmpty()) {
                                symbolesPossibles.add(Symbole.of(input));
                            } else {
                                Console.errorln("Le symbole ne peut pas être vide");
                                i--;
                            }
                            break;
    
                        default:
                            Console.errorln("Type non supporté");
                            return;
                    }
                }
            }
        }
    
        public List<Symbole> getSymbolesPossibles() {
            return symbolesPossibles;
        }
    
        public void setSymbolesPossibles(ArrayList<Symbole> symbolesPossibles) {
            this.symbolesPossibles = symbolesPossibles;
    }

    public void printSymbolesPossibles() {
        StringBuilder sb = new StringBuilder();
        for (Symbole symbole : symbolesPossibles) {
            sb.append(symbole.toString()).append(" ");
        }
        System.out.println(sb.toString());
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < taille; i++) {
            for (int j = 0; j < taille; j++) {
                sb.append(cases[i][j].toString()).append(" ");
            }
            sb.append("\n");
        }
        return sb.toString();
    }
}
