import SetConfig from "./set_config_class.js";
import $ from "./jquery.module.js";
import * as dialog from "./dialog.js";
import {ItemPlacement} from "./item_placement_class.js";
import {searchItems} from "../../blocks/search_game/searchItemsConfig.js";

let itemDisplay;
let searchInventory;
let useTimer = false;
let timeLimit;
let timeLeft;
let timeInterval

/* This section passes the information in the config file to the js file */
let config;
let config_ui = null;

let setConfigHandler = new SetConfig();
let text_beg ; // Beginning text in dialog and instructions ;
let text_end ; // Ending text in dialog and instructions ;
let decoy_text2 ;
function setConfig(config) {
    setConfigHandler.setConfig(config);
}

/* End config section */

// Gets all items of searchItem type and shows those when the document is ready ;
function initializeSearchModule(config) {
    $("#search-background-img").attr("src", config.options.backgroundImage) ;
    // insert class names for different search types for use by ItemPlacement
    for (const item of config.searchItems) {
        switch(item.searchType) {
            case "searchItem":
                item.itemDivClass = "search-item-type";
                break;
            case "blockerItem":
                item.itemDivClass = "blocker-item-type";
                break;
            case "staticItem":
                item.itemDivClass = "static-item-type";
                break;
            case "decoyItem":
                item.itemDivClass = "decoy-item-type";
                break;
            default:
                // Don't add itemDivClass
                break;
        }
    }
    config.itemPlacementConfig.clickHandler = searchClickHandler;

    let itemPlacementConfig = config.itemPlacementConfig;
    itemPlacementConfig.backgroundDivID = "main";   // ID of div containing background image
    itemPlacementConfig.itemDivClass    = "search-item"; // Class assigned to each displayed item (for styling)
    itemPlacementConfig.displayItems    = searchItems;
    itemDisplay = new ItemPlacement(config.itemPlacementConfig);

    searchInventory = config.searchItems.filter(item => item.searchType === "searchItem");
    for (let i =0; i < config.searchItems.length ; i++){
        config.searchItems[i].description =  config.searchItems[i].itemName ;

    }
    itemDisplay.onDocumentReady();
}

/*  When an item is clicked, if it has SearchItem type, hides it and removes it from the list of items needed
    If it has blockerItem type, it moves it
 */

function searchClickHandler(evt) {

    let itemData = evt.data;
    switch(itemData?.searchType) {
        case "searchItem":
            $(this).css("visibility", "hidden");
            removeItemFromSearchInventory(itemData);
            let dialogText = itemData?.foundText;
            if (dialogText) {
                // Postpone check for search complete until dialog is dismissed
                dialog.showDialog(dialogText, checkForSearchComplete);
            }
            else {
                // No dialog, so just check right away
                checkForSearchComplete();
            }
            break;
        case "blockerItem":
            itemDisplay.translateItemWithAnimation(itemData);
            break;
        case "decoyItem":
            let decoyText =  itemData?.foundText;
            let dialogText2 = decoyText ?? "You don't need that.";
            dialog.showDialog(dialogText2);
            break;
        case "staticItem":
            break;
        default:
            console.log(`Could not find searchType for item ${itemData.displayItemID ?? "unknown"}`);
            break;
    }
}

/* Takes search item out of the list when it is clicked */
function removeItemFromSearchInventory(item) {
    let newInventory = [];
    for(const listItem of searchInventory) {
        if (listItem.displayItemID !== item.displayItemID) {
            newInventory.push(listItem);
        }
    }
    searchInventory = newInventory;
}

function getSearchInventoryNames() {
    return searchInventory.map((item) => item.itemName);
}

function checkForSearchComplete() {
    if (searchInventory.length === 0) {  // All items have been found
        dialog.showDialogAsync(config.options.finishText).then(() => finishFunction() );
    }
}

async function finishFunction({showSuccessDialog} = {showSuccessDialog: true}) {
    $(".dialog7gen").css("border-radius", "20px");
    if (showSuccessDialog) {
        await dialog.showDialogAsync("<h1> Success! Proceed to the next page.</h1>");
    }
    if (config_ui && config_ui?.reloadWindowAtEnd) {
        window.location.reload();
    } else if (config.options.completionURL) {
        if (config.options?.sendCompletionToParent) {
            parent.postMessage({
                action: "goto",
                destination: config.options.completionURL
            });
        } else {
            window.location.href = config.options.completionURL;
        }
    }
}

function itemsLeftList() {
    let itemsLeft = "";
    for (const item of searchInventory) {
        itemsLeft += `<li>${item.itemName}</li>`;
    }
    return itemsLeft;
}

async function showItemsLeft() {
    await dialog.showDialogAsync(`<p>Looking for items:<br/>(You may need to move some items to find what you need.)</p><ul>` + itemsLeftList() + '</ul>');
}

function setHintButton(hintBtnID) {
    $(`#${hintBtnID}`).on("click", (evt) => showItemsLeft());
}

function startTimer() {
    $("#timer").text(`Time left: ${timeLeft} seconds`);
    timeInterval = setInterval(timer, 1000)
}

function timer() {
    --timeLeft;
    if (timeLeft <= 0) {
        timerExpired();
    }
    else {
        $("#timer").text(`Time left: ${timeLeft} seconds`);
    }
}

async function timerExpired() {
    clearInterval(timeInterval);
    const choice = await dialog.showChoiceDialogAsync("You have run out of time.", ["Restart Game", "Proceed"]);
    switch (choice) {
        case "Restart Game":
            restartGame();
            break;

        case "Proceed":
            await finishFunction({showSuccessDialog: false});
            break;
    }
}

function restartGame() {
    window.location.reload();
}

$(async () => {
    config = await setConfigHandler.getConfigAsync();
    config_ui = config?.ui_params;

    initializeSearchModule(config);
    setHintButton(config.options.hintButtonID);
    getSearchInventoryNames() ;

    useTimer = config.options?.timeLimitInSeconds !== undefined;
    if (useTimer) {
        timeLimit = config.options?.timeLimitInSeconds;
        timeLeft = timeLimit;
        await dialog.showDialogAsync(`You have ${timeLimit} seconds to find all the items.`);
    }

    if (config.options?.showListAtStart) {
        await showItemsLeft();
    }

    if (useTimer) {
        startTimer();
    }

    text_beg = '<p><span class="language1">Looking for items:</span><span class="language2 d-none">Buscando artículos:</span></p>' ;
    text_end = '<p><span class="language1">(You may need to move some things to find what you need.)</span><span class="language2 d-none">(Es posible que tengas que mover algunas cosas para encontrar lo que necesitas.)</span>';
    decoy_text2 = "You don't need that." ;
    if(config.options.language2) {
        text_beg = '<p><span class="language1 d-none">Looking for items:</span><span class="language2">Buscando artículos:</span></p>' ;
        text_end = '<p><span class="language1 d-none">(You may need to move some things to find what you need.)</span><span class="language2">(Es posible que tengas que mover algunas cosas para encontrar lo que necesitas.)</span>';
        decoy_text2 = "No necesitas eso."
    }
    $("#instructionsText").html('<p>' + text_beg + '</p><ul>' + itemsLeftList() + '</ul><p>' + text_end + '</p>')
    $("#play").on("click",function(){
        $("#layer2").remove();
        $("#instructions1").hide() ;
    })

});


export {setHintButton, setConfig};