// @ts-check

const wait = require('node:timers/promises').setTimeout;
const { MessageActionRow, MessageButton, MessageSelectMenu, Client, CommandInteractionOptionResolver } = require('discord.js');
const { STATE } = require('../db/econ');
const { winGame, getCustomEmoji } = require('./external_game_functions.js');
const { changeTurn } = require('../turnManager.js');
const { game_class_battle } = require('./game_classes');
const { MongoClient } = require('mongodb');
const { convertSnowflakeToDate } = require('../db/addons/snowflake');

//This function is blatantly stolen from https://alialaa.com/blog/tic-tac-toe-js
function isTerminal(board) {
	//Return False if board in empty
    if (board.every(cell => !cell)) return false;
    let nums = [0, 0, 0]

    //Checking Horizontal Wins
    if (board[0] === board[1] && board[0] === board[2] && board[0]) {
        nums = [0, 1, 2];
    	return {'winner': board[0], 'direction': 'H', 'row': 1, 'nums': nums};
    }
    if (board[3] === board[4] && board[3] === board[5] && board[3]) {
        nums = [3, 4, 5];
    	return {'winner': board[3], 'direction': 'H', 'row': 2, 'nums': nums};
    }
    if (board[6] === board[7] && board[6] === board[8] && board[6]) {
        nums = [6, 7, 8];
    	return {'winner': board[6], 'direction': 'H', 'row': 3, 'nums': nums};
    }

    //Checking Vertical Wins
    if (board[0] === board[3] && board[0] === board[6] && board[0]) {
        nums = [0, 3, 6];
    	return {'winner': board[0], 'direction': 'V', 'column': 1, 'nums': nums};
    }
    if (board[1] === board[4] && board[1] === board[7] && board[1]) {
        nums = [1, 4, 7];
    	return {'winner': board[1], 'direction': 'V', 'column': 2, 'nums': nums};
    }
    if (board[2] === board[5] && board[2] === board[8] && board[2]) {
        nums = [2, 5, 8];
    	return {'winner': board[2], 'direction': 'V', 'column': 3, 'nums': nums};
    }

    //Checking Diagonal Wins
    if (board[0] === board[4] && board[0] === board[8] && board[0]) {
        nums = [0, 4, 8];
    	return {'winner': board[0], 'direction': 'D', 'diagonal': 'main', 'nums': nums};
    }
    if (board[2] === board[4] && board[2] === board[6] && board[2]) {
        nums = [2, 4, 6];
    	return {'winner': board[2], 'direction': 'D', 'diagonal': 'counter', 'nums': nums};
    }

    //If no winner but the board is full, then it's a draw
    if (board.every(cell => cell)) {
        return {'winner': 'draw'};
    }

    //return false otherwise
    return false;
}


//I know it's sloppy, but when 'initial' is true, 'interaction' will actually be 'thread'
function postActionBar(interaction, user_dbo, board, won, initial = false) {
    let componentlist = [];
    let newRow = new MessageActionRow();

    for (let i = 0; i < 9; i ++) {
        let button;
        
        if (!won) {
            if (!board[i]) {
                button = new MessageButton()
                .setCustomId(`ttt|${i}`)
                .setLabel('-')
                .setStyle('SUCCESS')
            } else {
                button = new MessageButton()
                .setCustomId(`ttt|${i}`)
                .setLabel(board[i])
                .setStyle('DANGER')
                .setDisabled(true);
            }
        } else {
            if (i in won.nums) {
                button = new MessageButton()
                .setCustomId(`ttt|${i}`)
                .setLabel('W')
                .setStyle('SUCCESS')
            } else {
                button = new MessageButton()
                .setCustomId(`ttt|${i}`)
                .setLabel('F')
                .setStyle('DANGER')
                .setDisabled(true);
            }
        }

        newRow.addComponents(button);
        
        if ((i + 1) % 3 == 0) {
            //Add the row to the list of rows
            componentlist.push(newRow);
            newRow = new MessageActionRow();
        }
    }

    console.log(componentlist);

    if (initial) {
        interaction.send({ content: `Your turn <@${user_dbo.s.namespace.collection}>!`, components: componentlist });
    } else {
        interaction.update({ content: `Your turn <@${user_dbo.s.namespace.collection}>!`, components: componentlist });
    }
}


async function handle(client, db, dbo, other, bot, thread, command, doc, interaction, xp_collection) {
    
    if (command == 'initalize') {
        let board = ["", "", "", "", "", "", "", "", ""];
        postActionBar(thread, dbo, board, false,true);
    } else {
        //Change the board
        let square = Number(interaction.customId.split('|')[1]);
        let symbol = doc.symbols[doc.turn];
        let board = doc.board;
        board[square] = symbol;
        client.db('B|S' + bot.user.id).collection(dbo.s.namespace.db.substr(0, dbo.s.namespace.db.length - 6)).updateOne({'board': {$exists: true}}, {$set: {board: board}});

        //Check if the game is over
        let won = isTerminal(board);
        
        if (!won) {
            changeTurn(client, bot, interaction);
            postActionBar(interaction, other, board, false);
            changeTurn(client, bot, interaction);
        } else {
            postActionBar(interaction, dbo, board, won);
            await wait(7000);
            winGame(client, bot, db, dbo, xp_collection, interaction.message);
        }
    }
}

module.exports = { handle }