let products = []

i18next
    .use(i18nextHttpBackend)
    .init({
        lng: "fr",
        fallbackLng: "fr",
        backend: {
            loadPath: "./assets/locales/{{lng}}.json",
        }
    }, (err, t) => {
        updatePageContent()
    })

function updatePageContent() {
    document.querySelectorAll("[data-i18n]").forEach(el => {
        let key = el.getAttribute("data-i18n")
        
        if (key.startsWith("[")) {
            const parts = key.split("]")
            const attr = parts[0].substring(1)
            const actualKey = parts[1]
            el.setAttribute(attr, i18next.t(actualKey))
        } else {
            el.innerText = i18next.t(key)
        }
    })
}

async function chooseLanguage(dropdownSelector, option) {
    const select = document.querySelector(`details.${dropdownSelector}`)
    await choose(dropdownSelector, option)
    i18next.changeLanguage(select.getAttribute("value"), () => {
        updatePageContent()
    })
}

async function fetchProducts() {
    const result = await system.call("network::fetch", {
        url: "https://brik.azures.fr/products/",
        method: "GET",
        headers: {
            "Accept": "application/json"
        }
    })
    if (!result.success) {
        return console.error("[N::F>(GP)] Error !")
    }

    const data = JSON.parse(result.data)

    for (const productName of data) {
        products.push({
            name: productName,
            ...await fetchInstallerResourcesFor(productName)
        })
    }

    await makeProductList()
}

async function fetchInstallerResourcesFor(productName) {
    const result = await system.call("network::fetch", {
        url: `https://brik.azures.fr/products/${productName}/installerResource`,
        method: "GET",
        headers: {
            "Accept": "application/json"
        }
    })
    if (!result.success) {
        return console.error("[N::F>(GIR)] Error !")
    }

    return JSON.parse(result.data)
}

async function makeProductList() {
    const productDropdown = document.querySelector("details.product")
    const ul = document.createElement("ul")
    for (const product of products) {
        const index = products.indexOf(product)
        const li = document.createElement("li")
        const radio = document.createElement("input")
        const label = document.createElement("label")
        const logo = document.createElement("img")
        const title = document.createElement("span")

        radio.setAttribute("type", "radio")
        radio.setAttribute("name", "radio")
        radio.setAttribute("value", index)
        radio.setAttribute("id", `box_soft_${index}`)
        radio.setAttribute("onclick", "choose('product', this)")
        
        logo.setAttribute("src", product.logo)
        
        title.innerText = product.name

        label.setAttribute("for", `box_soft_${index}`)
        label.appendChild(logo)
        label.appendChild(title)

        li.appendChild(radio)
        li.appendChild(label)

        ul.appendChild(li)
    }
    const options = productDropdown.querySelector("section.options > ul")
    options.innerHTML = ul.innerHTML
}

function clearLogIntoRequirementConsole() {
    const logsContainer = document.querySelector("article.frame.requirements > div.console")
    logsContainer.innerHTML = ""
}

function putLogIntoRequirementConsole(log) {
    const logsContainer = document.querySelector("article.frame.requirements > div.console")
    const code = document.createElement("code")
    code.innerHTML = log 
    logsContainer.appendChild(code)
    logsContainer.innerHTML += "<br>"
}

function showFrameExtraButtons() {
    document.querySelector("article.frame:not([hidden]) > section.extra_buttons").removeAttribute("hidden")
}

function hideFrameExtraButtons() {
    document.querySelector("article.frame:not([hidden]) > section.extra_buttons").setAttribute("hidden", "")
}

function getSelectedSoftware() {
    const productDropdown = document.querySelector("details.product")
    const productIndex = productDropdown.getAttribute("value") + 1
    const productName = productDropdown.querySelector(`li:nth-of-type(${productIndex})`).children[1].innerText
    return productName
}

function filterProductArray(productName) {
    products = products.filter(product => product.name == productName)
}

function writeEula(eula) {
    const eulaContainer = document.querySelector("article.frame.eula > div.console")
    const pre = document.createElement("pre")
    pre.innerText = eula 
    eulaContainer.appendChild(pre)
}

function clearEula() {
    const eulaContainer = document.querySelector("article.frame.eula > div.console")
    eulaContainer.innerHTML = ""
}

async function fetchEula() {
    const eulaUrl = products[0].eula
    const result = await system.call("network::fetch", {
        url: eulaUrl,
        method: "GET",
        headers: {
            "Accept": "application/json"
        }
    })
    if (!result.success) {
        return console.error("[N::F>(GE)] Error !")
    }
    return result
}

async function openEULA() {
    await system.call("browser::open", { url: products[0].eula })
}

async function selectDirectory() {
    const productName = getSelectedSoftware()
    const result = await system.call("dialog::selectDirectory")
    if (result.path != null) {
        if (!result.path.endsWith(productName)) {
            result.path = result.path + separator + productName
        }
        installationPath.setAttribute("value", result.path)
    }
}

async function checkInstallationPath(path) {
    const result = await system.call("installer::testInstallationPath", { path })
    if (result.success) {
        showFrameNavigationButtons()
    }
}

async function quit() {
    const finishState = {
        createShortcut: createShortcut["checked"],
        launchAfterExit: launchAfterExit["checked"]
    }
    const finalized = await system.call("installer::finalize", finishState)
    if (!finalized.success) {
        alert("Erreur")
        await sleep(1000)
    }
    await system.call("installer::kill")
}

function setSourceLogo(url) {
    const sourceSection = document.querySelector("section.source")
    const sourceLogo = sourceSection.querySelector("img")
    sourceLogo.src = url
}

function setSourceName(name) {
    const sourceSection = document.querySelector("section.source")
    const sourceName = sourceSection.querySelector("p")
    sourceName.innerText = name
}

async function setupMetadata() {
    const metadata = await system.call("brik::metadata")
    if (metadata.success) {
        try {
            const parsed = JSON.parse(metadata.content)
            setSourceName(parsed.name)
            setSourceLogo(parsed.logo)
        } catch (error) {
            console.error(error)
        }
    }
}

onFrameShowed("onboarding", async () => {
    await setupMetadata()
    const languageDropdown = document.querySelector("details.language")
    if (languageDropdown.getAttribute("value") == null) {
        hideFrameNavigationButtons()
    }
})

onFrameShowed("chooseProduct", () => {
    const productsDropdown = document.querySelector("details.product")
    const productIndex = productsDropdown.getAttribute("value")
    if (productIndex != null) {    
        const product = productsDropdown.querySelector(`li:nth-of-type(${productIndex + 1})`).children[0]    
        choose("product", product)
    } else {
        hideFrameNavigationButtons()
        showFrameExtraButtons()
    }
})

onFrameShowed("requirements", async () => {
    const productName = getSelectedSoftware()
    clearLogIntoRequirementConsole()
    hideFrameNavigationButtons()
    hideFrameExtraButtons()
    showLoadingBar()
    filterProductArray(productName)
    await system.call("check::requirements", { soft: productName })
})

onFrameShowed("eula", async () => {
    clearEula()
    const eula = await fetchEula()
    writeEula(eula.data)
})

onFrameShowed("choosePath", async () => {
    hideFrameNavigationButtons()
    const result = await system.call("installer::defaultInstallPath", { soft: getSelectedSoftware() })
    if (result.success) {
        installationPath.setAttribute("value", result.path)
        installationPath.onchange()
    }
})

onFrameShowed("download", async () => {
    hideFrameExtraButtons()
    hideFrameNavigationButtons()
    showLoadingBar()
    const result = await system.call("installer::install", { soft: getSelectedSoftware(), path: installationPath.getAttribute("value") })
    hideLoadingBar()
    if (result.success) {
        showFrame("end")
    } else {
        showFrameExtraButtons()
    }
})

onSelected("language", () => {
    showFrameNavigationButtons()
})

onSelected("product", () => {
    hideFrameExtraButtons()
    showFrameNavigationButtons()
})

system.result("requirement::log", (data) => {
    putLogIntoRequirementConsole(data.message)
    updatePageContent()
})

system.result("requirement::failed", () => {
    hideLoadingBar()
    showFrameExtraButtons()
})

system.result("requirement::success", () => {
    hideLoadingBar()
    showFrameNavigationButtons()
})

showFrame("onboarding")
fetchProducts()