let solution = [];let history = [];
let GridSizeArray=[4,6,9];
let rulesArray=["Fill the grid with the digits 1-4.","Fill the grid with the digits 1-6.","Fill the grid with the digits 1-9"];
let GridCounter=0;
let lifecounter=4;
let mobileDeviceFlag=false;
var Utils={};
Utils.Path='';
$(document).ready(function () {
    $(".se-pre-con").fadeOut("slow");
    if ((navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) && !(window.location.href.includes('http')))
        mobileDeviceFlag = true;
        setimages();
});
function setimages()
{
    $('body').css('background-image', 'url("images/mainpagebig.png")');
    document.getElementById('home').src=Utils.Path+"images/Home.png";
    document.getElementById('logo').src=Utils.Path+"images/logo.png";       
    document.getElementById('playbutton').src=Utils.Path+"images/Play.png";
    document.getElementById('rulesbutton').src=Utils.Path+"images/Play.png";
    document.getElementById('replaybutton').src=Utils.Path+"images/playAgain.png";
    document.getElementById('nextbutton').src=Utils.Path+"images/Next.png";
    document.getElementById("GamePage").style.display = "none";
    document.getElementById("endpage").style.display = "none";
    document.getElementById("rulespage").style.visibility = "hidden";
    document.getElementById("home").style.visibility = "hidden";
    document.getElementById("nextbutton").style.visibility = "hidden";
}
function showRules()
{
    document.getElementById("rulespage").style.visibility = "visible";
}
function selectLevel()
{
    document.getElementById("homelogodiv").classList.add("homelogodivcls");
    document.getElementById("rulespage").style.display = "none";
    showrules();
    size=GridSizeArray[GridCounter];
    if (size === 4) {
        document.getElementById("numpad").style.maxWidth = "500px";
      } else if (size === 6) {
        document.getElementById("numpad").style.maxWidth = "568px";
      } else {
        document.getElementById("numpad").style.maxWidth = "800px";}
    createStar();
    createGrid(size);
    createNumpad(size);
}
function createStar()
{
    const container = document.getElementById('sudokulife');
    container.innerHTML = ''; 
    for (let i = 0; i < 5; i++) {
    const starImg = document.createElement('img');
    starImg.id = `star-${i}`; 
    starImg.src = 'images/star2.png'; 
    starImg.alt = 'star';
    starImg.style.width = '44px';    
    starImg.style.height = '44px';
    starImg.style.marginRight = '6px';
    container.appendChild(starImg);
    }
}
function createGrid(size) {
    document.getElementById("rulesbutton").style.display = "none";
    document.getElementById("playbutton").style.display = "none";
    document.getElementById("GamePage").style.display = "block";
    document.getElementById("home").style.visibility = "visible";
    const container = document.getElementById("sudoku");
    container.innerHTML = '';  
    gridSize = size;
    container.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
    solution = generateSolution(size);
    container.dataset.size = gridSize;  
   // const subGridSize = gridSize === 9 ? 3 : gridSize === 6 ? 2 : 2;  
    const clues = gridSize === 4 ? 0.5 : gridSize === 6 ? 0.35 : 0.25;
    console.log(clues);
    let subGridRows, subGridCols;
    if (gridSize === 9) {
        subGridRows = 3;
        subGridCols = 3;
    } else if (gridSize === 6) {
        subGridRows = 2;
        subGridCols = 3;
    } else if (gridSize === 4) {
        subGridRows = 2;
        subGridCols = 2;
    }
    const forcedClues = new Set();
    const rowClues = Array(size).fill(0);
    const colClues = Array(size).fill(0);
    const maxCluesPerRow = size - 1;  // Avoid full rows
    const maxCluesPerCol = size - 1;  // Avoid full cols
    for (let subRow = 0; subRow < gridSize; subRow += subGridRows) {
        for (let subCol = 0; subCol < gridSize; subCol += subGridCols) {
            let placed = false;
            let attempts = 0;
            while (!placed && attempts < 100) {
                const randRow = subRow + Math.floor(Math.random() * subGridRows);
                const randCol = subCol + Math.floor(Math.random() * subGridCols);
                if (
                    rowClues[randRow] < maxCluesPerRow &&
                    colClues[randCol] < maxCluesPerCol
                ) {
                    const key = `${randRow},${randCol}`;
                    forcedClues.add(key);
                    rowClues[randRow]++;
                    colClues[randCol]++;
                    placed = true;
                }
                attempts++;
            }
        }
    }
    for (let row = 0; row < size; row++) {
        for (let col = 0; col < size; col++) {
            const input = document.createElement("input");
            input.type = "text";
            input.classList.add(
                gridSize === 4 ? "sudoku-4X4cell" :
                gridSize === 6 ? "sudoku-6X6cell" :
                "sudoku-cell"
            );
            input.dataset.row = row;
            input.dataset.col = col;
           // input.maxLength = "1";
    
            if ((col + 1) % subGridCols === 0 && col !== gridSize - 1) {
                input.classList.add("thick-right");
            }
            if ((row + 1) % subGridRows === 0 && row !== gridSize - 1) {
                input.classList.add("thick-bottom");
            }
    
            const cellKey = `${row},${col}`;
            const canPlaceRandomClue = (
                Math.random() < clues &&
                !forcedClues.has(cellKey) &&
                rowClues[row] < maxCluesPerRow &&
                colClues[col] < maxCluesPerCol
            );
    
            if (forcedClues.has(cellKey) || canPlaceRandomClue) {
                input.value = solution[row][col];
                input.style.pointerEvents = 'none';
                input.dataset.clue = "true";
                input.data = "clues";
                input.style.background = "#beb6b6";
                rowClues[row]++;
                colClues[col]++;
            } //else {
                input.addEventListener('input', (e) => {
                    const cell = e.target;
                    const row = parseInt(cell.dataset.row);
                    const col = parseInt(cell.dataset.col);
                    const inputValue = e.target.value;
                    if (inputValue.length > 1) {
                        e.target.value = inputValue.slice(-1);
                    }
                    const value = parseInt(e.target.value);
                    if (isNaN(value) || value < 1 || value > gridSize) {
                        e.target.value = "";
                        return;
                    }
                    if ( value != solution[row][col]){
                        if(lifecounter==0)
                            {
                                setTimeout(() => {
                                document.getElementById("playSound").src=Utils.Path+"sounds/incomplete puzzle.mp3";
                                document.getElementById("playSound").play();
                                }, 1 * 1000);  
                                setTimeout(() => {
                                document.getElementById("GamePage").style.display = "none";
                                document.getElementById("endpage").style.display = "block";
                                $("#endmessage").text("GAME OVER");
                                }, 2 * 1000);  
                            }
                        document.getElementById("star-"+lifecounter).classList.add("image");
                       // document.getElementById("star-"+lifecounter).src = 'images/star1.png';  
                        lifecounter--;
                    }
                    validateGrid();
                    setTimeout(() => {
                        shakeDuplicates(row, col, value, gridSize);
                    }, 500);
                });
            //}
            input.addEventListener("click", () => {
                const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
                if (isMobile) {
                    input.setAttribute('readonly', true);
                    input.addEventListener('focus', () => {
                    input.blur(); 
                    });
                }
            input.style.border = '3px solid rgb(247, 176, 46)';
            const inputs = document.querySelectorAll(".sudoku-4X4cell, .sudoku-6X6cell, .sudoku-cell");
            inputs.forEach(input => {
            input.addEventListener("focus", () => {
                inputs.forEach(i => {
                if (i.style.border === "3px solid rgb(247, 176, 46)") {
                    i.style.border = "";
                }
                });
                input.style.border = "3px solid rgb(247, 176, 46)";
            });
            });
            highlightRowAndColumn(row, col);
            });
            container.appendChild(input);
        }
    }
    
}
function shakeDuplicates(row, col, value, gridSize, solutionGrid) {
    const cells = document.querySelectorAll('.sudoku-cell, .sudoku-4X4cell ,.sudoku-6X6cell');
    cells.forEach(cell => cell.classList.remove("shake"));
    const subGridSize = gridSize === 9 ? { rows: 3, cols: 3 }
                        : gridSize === 6 ? { rows: 2, cols: 3 }
                        : { rows: 2, cols: 2 };
    let isDuplicate = false;
    let isWrongAnswer = solutionGrid && solutionGrid[row] && solutionGrid[row][col] !== value;
    for (let i = 0; i < gridSize; i++) {
        const rowCell = document.querySelector(`.sudoku-cell[data-row="${row}"][data-col="${i}"], .sudoku-4X4cell[data-row="${row}"][data-col="${i}"], .sudoku-6X6cell[data-row="${row}"][data-col="${i}"]`);
        const colCell = document.querySelector(`.sudoku-cell[data-row="${i}"][data-col="${col}"], .sudoku-4X4cell[data-row="${i}"][data-col="${col}"], .sudoku-6X6cell[data-row="${i}"][data-col="${col}"]`);       
        if (rowCell && parseInt(rowCell.value) === value && i !== col) {
            rowCell.classList.add("shake");
            isDuplicate = true;
        }
        if (colCell && parseInt(colCell.value) === value && i !== row) {
            colCell.classList.add("shake");
            isDuplicate = true;
        }
    }
    const subRowStart = Math.floor(row / subGridSize.rows) * subGridSize.rows;
    const subColStart = Math.floor(col / subGridSize.cols) * subGridSize.cols;
    for (let i = 0; i < subGridSize.rows; i++) {
        for (let j = 0; j < subGridSize.cols; j++) {
            const subCell = document.querySelector(`.sudoku-cell[data-row="${subRowStart + i}"][data-col="${subColStart + j}"],
                                                    .sudoku-4X4cell[data-row="${subRowStart + i}"][data-col="${subColStart + j}"],
                                                    .sudoku-6X6cell[data-row="${subRowStart + i}"][data-col="${subColStart + j}"]`);
            if (subCell && parseInt(subCell.value) === value && (subRowStart + i !== row || subColStart + j !== col)) {
                subCell.classList.add("shake");
                isDuplicate = true;
            }
        }
    }
    const currentCell = document.querySelector(`.sudoku-cell[data-row="${row}"][data-col="${col}"], .sudoku-4X4cell[data-row="${row}"][data-col="${col}"],.sudoku-6X6cell[data-row="${row}"][data-col="${col}"]`);
    if (currentCell && (isDuplicate || isWrongAnswer)) {
        currentCell.classList.add("shake");
        document.getElementById("playSound").src=Utils.Path+"sounds/incorrect answer.mp3";
        document.getElementById("playSound").play();
    }
    setTimeout(() => {
        document.querySelectorAll('.shake').forEach(cell => cell.classList.remove("shake"));
    }, 600);
}
function createNumpad(gridSize) {
    const numpad = document.getElementById("numpad");
    numpad.innerHTML = "";  
    const numpadSize = gridSize === 4 ? 4 : gridSize === 6 ? 6 : 9;
    for (let i = 1; i <= numpadSize; i++) {
        const button = document.createElement("button");
        button.textContent = i;
        button.classList.add("numpad-btn");
        button.addEventListener("click", () => {
            const activeCell = document.querySelector(".sudoku-cell.active, .sudoku-4X4cell.active, .sudoku-6X6cell.active");
            if (activeCell) {
                activeCell.value = i;  
            }
            const value = parseInt(activeCell.value) || 0;
            const row = parseInt(activeCell.dataset.row);
            const col = parseInt(activeCell.dataset.col);
            if ( value != solution[row][col]){
                if(lifecounter==0)
                    {
                        setTimeout(() => {
                            document.getElementById("playSound").src=Utils.Path+"sounds/incomplete puzzle.mp3";
                            document.getElementById("playSound").play();
                            }, 1 * 1000);  
                            setTimeout(() => {
                            document.getElementById("GamePage").style.display = "none";
                            document.getElementById("endpage").style.display = "block";
                            $("#endmessage").text("GAME OVER");
                            }, 2 * 1000);    
                    }
                document.getElementById("star-"+lifecounter).classList.add("image");
                //document.getElementById("star-"+lifecounter).src = 'images/star1.png';  
                lifecounter--;
            }
            validateGrid();
            if (value !== 0) {
                setTimeout(() => {
                    shakeDuplicates(row, col, value,gridSize);
                }, 500);
            }
        });
        numpad.appendChild(button);
    }
    const clearBtn = document.createElement("button");
    clearBtn.textContent = "C";
    clearBtn.classList.add("numpad-btn", "clear-btn");
    clearBtn.addEventListener("click", () => {
        const activeCell = document.querySelector(".sudoku-cell.active, .sudoku-4X4cell.active,.sudoku-6X6cell.active");
        if (activeCell) {
            activeCell.classList.remove("wrong");
            activeCell.value = "";  
            //activeCell.classList.remove("active");
        }
    });
    numpad.appendChild(clearBtn);
}
document.addEventListener("click", (event) => {
    if (event.target.classList.contains("sudoku-cell") || event.target.classList.contains("sudoku-4X4cell") || event.target.classList.contains("sudoku-6X6cell")) {
        document.querySelectorAll(".sudoku-cell, .sudoku-4X4cell , .sudoku-6X6cell").forEach(cell => {
            cell.classList.remove("active");
        });
        event.target.classList.add("active");
    }
});
function generateSolution(size) {
    const grid = Array.from({ length: size }, () => Array(size).fill(0));
    function isValid(grid, row, col, num) 
    {
        const subGridRows = size === 6 ? 2 : Math.sqrt(size);
        const subGridCols = size === 6 ? 3 : Math.sqrt(size);
       for (let x = 0; x < size; x++) {
            if (grid[row][x] === num || grid[x][col] === num) return false;
        }
        const startRow = Math.floor(row / subGridRows) * subGridRows;
        const startCol = Math.floor(col / subGridCols) * subGridCols;
        for (let r = 0; r < subGridRows; r++) {
            for (let c = 0; c < subGridCols; c++) {
                if (grid[startRow + r][startCol + c] === num) return false;
            }
        }
        return true;
    }
    function fillGrid() {
        for (let row = 0; row < size; row++) {
            for (let col = 0; col < size; col++) {
                if (grid[row][col] === 0) {
                    const nums = [...Array(size).keys()].map(n => n + 1).sort(() => Math.random() - 0.5);

                    for (const num of nums) {
                        if (isValid(grid, row, col, num)) {
                            grid[row][col] = num;
                            if (fillGrid()) return true;
                            grid[row][col] = 0;
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }
    fillGrid();
    return grid;
}
function validateGrid() {
    const cells = document.querySelectorAll('.sudoku-cell, .sudoku-4X4cell,.sudoku-6X6cell');
    const gridSize = parseInt(document.getElementById("sudoku").dataset.size);
    const subGridSize = gridSize === 9 ? { rows: 3, cols: 3 }
                        : gridSize === 6 ? { rows: 3, cols: 2 }
                        : { rows: 2, cols: 2 };
    let solved = true;
    function isRowOrColComplete(index, isRow = true) {
    for (let i = 0; i < gridSize; i++) {
        const selector = isRow 
            ? `.sudoku-cell[data-row="${index}"][data-col="${i}"], .sudoku-4X4cell[data-row="${index}"][data-col="${i}"], .sudoku-6X6cell[data-row="${index}"][data-col="${i}"]`
            : `.sudoku-cell[data-row="${i}"][data-col="${index}"], .sudoku-4X4cell[data-row="${i}"][data-col="${index}"],.sudoku-6X6cell[data-row="${i}"][data-col="${index}"]`;
        
        const cell = document.querySelector(selector);
        if (!cell || !cell.value) {
            return false;  
        }
    }
    return true;  
    }
    for (const cell of cells) {
       // cell.classList.remove("wrong");
        const row = parseInt(cell.dataset.row);
        const col = parseInt(cell.dataset.col);
        const value = parseInt(cell.value) || 0;
        if (cell.data=="clues") {
            continue;  
        }
        const rowComplete = isRowOrColComplete(row, true);
        const colComplete = isRowOrColComplete(col, false);
        let subGridSize;
        if (gridSize === 4) {
            subGridSize = { rows: 2, cols: 2 };
        } else if (gridSize === 6) {
            subGridSize = { rows: 2, cols: 3 };
        } else if (gridSize === 9) {
            subGridSize = { rows: 3, cols: 3 };
        }
        const subGridValid = isSubGridValid(row, col, subGridSize);
       if (rowComplete || colComplete || subGridValid)
        {
            if (value === solution[row][col]) {
                cell.classList.remove("wrong");
                cell.classList.add("correct");
                setTimeout(() => {
                document.getElementById("playSound").src=Utils.Path+"sounds/correct answer.mp3";
                document.getElementById("playSound").play();
                }, 0.5 * 1000); 
            } else if (value !== 0 ) {//&& value != solution[row][col]
                cell.classList.remove("correct");
                cell.classList.add("wrong");
                solved = false;
            }
        }
        else {
            solved = false;  
        }
    }
    if (solved) {
        setTimeout(() => {
            document.getElementById("nextbutton").style.visibility = "visible";
            document.getElementById("nextbutton").classList.add("blink-fade");
            document.getElementById("playSound").src=Utils.Path+"sounds/puzzle completion.mp3";
            document.getElementById("playSound").play();
            }, 1 * 1000); 
    } 
}
function isSubGridValid(row, col, subGridSize) {
    const seen = new Set();
    const startRow = Math.floor(row / subGridSize.rows) * subGridSize.rows;
    const startCol = Math.floor(col / subGridSize.cols) * subGridSize.cols;

    for (let r = startRow; r < startRow + subGridSize.rows; r++) {
        for (let c = startCol; c < startCol + subGridSize.cols; c++) {
            const cell = document.querySelector(`input[data-row="${r}"][data-col="${c}"]`);
            if (!cell) continue;

            const value = parseInt(cell.value, 10);
            if (isNaN(value)) return false; // empty or invalid
           // if (seen.has(value)) return false; // duplicate
            seen.add(value);
        }
    }
    return true;
}
function highlightRowAndColumn(row, col) {
    document.querySelectorAll(".highlight-row, .highlight-col").forEach(el => {
        el.classList.remove("highlight-row", "highlight-col");
    });
    document.querySelectorAll(`input[data-row='${row}']`).forEach(cell => {
        cell.classList.add("highlight-row");
    });
    document.querySelectorAll(`input[data-col='${col}']`).forEach(cell => {
        cell.classList.add("highlight-col");
    });
}
function callhome()
{
	location.reload();
}
function ReplayGame()
{
    document.getElementById("nextbutton").style.visibility = "hidden";
    document.getElementById("nextbutton").classList.remove("blink-fade");
    createGrid(size);
}
function nextLevel()
{
    document.getElementById("nextbutton").classList.remove("blink-fade");
   document.getElementById("nextbutton").style.visibility = "hidden";
    if(GridCounter<2){
        GridCounter++;
        lifecounter=4;
        showrules();
        selectLevel();
    }else{
        document.getElementById("GamePage").style.display = "none";
        document.getElementById("endpage").style.display = "block";
        $("#endmessage").text("GAME OVER");
    }
}
function showrules()
{
    const modal = document.getElementById("rulesModal");
    const span = document.querySelector(".close");
    modal.classList.add("show");
    document.getElementById("rulesmessage").innerHTML=rulesArray[GridCounter];
    span.onclick = function () {
        modal.classList.remove("show");
    }
    setTimeout(() => {
        modal.classList.remove("show");
    }, 5 * 1000); 

}
function showCredits(){
	//$('#acknowledgementDiv').show();
};
function playAgain()
{
	//$('#endpage').hide();
};