package theorycrafter.ui.settings

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.selection.DisableSelection
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.Divider
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import compose.utils.VSpacer
import compose.widgets.DropdownField
import compose.widgets.SingleLineText
import theorycrafter.*
import theorycrafter.ui.Checkbox
import theorycrafter.ui.TheorycrafterTheme
import theorycrafter.ui.widgets.UrlText


/**
 * The settings pane for updating Theorycrafter.
 */
@Composable
fun SoftwareUpdatesPane() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(TheorycrafterTheme.spacing.edgeMargins)
    ) {
        UpgradeLaneSelector()
        VSpacer(TheorycrafterTheme.spacing.xxlarge)
        Divider()
        VSpacer(TheorycrafterTheme.spacing.xxlarge)
        LatestVersion(
            modifier = Modifier
                .fillMaxWidth()
                .weight(1f)
        )
        Spacer(Modifier.weight(0.5f))
    }
}


/**
 * Displays and allows selecting the user's chosen upgrade lane.
 */
@Composable
private fun UpgradeLaneSelector() {
    Row {
        val releasesSettings = TheorycrafterContext.settings.theorycrafterReleases
        TheorycrafterTheme.Checkbox(
            checked = releasesSettings.notifyOnNewRelease,
            onCheckedChange = { releasesSettings.notifyOnNewRelease = it },
            modifier = Modifier.alignByBaseline()
        )
        Column {
            Row {
                SingleLineText(
                    text = "Notify me when a new ",
                    modifier = Modifier.alignByBaseline()
                )
                DropdownField(
                    items = ReleaseType.entries,
                    selectedItem = releasesSettings.upgradeLane,
                    onItemSelected = { _, lane ->
                        if (releasesSettings.upgradeLane != lane) {
                            releasesSettings.upgradeLane = lane
                            releasesSettings.resetLatestSkippedVersionCode()
                        }
                    },
                    modifier = Modifier
                        .width(120.dp)
                        .alignByBaseline(),
                )
                SingleLineText(
                    text = " version is released",
                    modifier = Modifier.alignByBaseline()
                )
            }

            VSpacer(TheorycrafterTheme.spacing.xxsmall)

            val upgradeLane = releasesSettings.upgradeLane
            Text(
                text = remember(upgradeLane) {
                    buildAnnotatedString {
                        append("You will be notified whenever a ")
                        val underline = SpanStyle(textDecoration = TextDecoration.Underline)
                        val notifiedReleaseTypes = ReleaseType.entries.takeWhile { it <= upgradeLane }
                        for ((index, releaseType) in notifiedReleaseTypes.withIndex()) {
                            withStyle(underline) {
                                append(releaseType.displayName)
                            }
                            if (index == notifiedReleaseTypes.size - 2)
                                append(" or ")
                            else if (index < notifiedReleaseTypes.size - 1)
                                append(", ")
                        }
                        append(" version is released.")
                    }
                },
                style = TheorycrafterTheme.textStyles.detailedText()
            )
        }
    }
}


/**
 * Displays information about the latest version.
 */
@Composable
private fun LatestVersion(modifier: Modifier) {
    Box(
        contentAlignment = Alignment.Center,
        modifier = modifier
    ) {
        SelectionContainer {
            Column(horizontalAlignment = Alignment.CenterHorizontally) {
                SingleLineText(
                    text = "Your Theorycrafter",
                    style = TheorycrafterTheme.textStyles.mediumHeading
                )
                VSpacer(TheorycrafterTheme.spacing.xxxsmall)
                SingleLineText(Theorycrafter.Version)
                VSpacer(TheorycrafterTheme.spacing.xxxsmall)
                SingleLineText(THEORYCRAFTER_RELEASE_DATE_FORMAT.format(Theorycrafter.BuildTimestamp))

                VSpacer(TheorycrafterTheme.spacing.xlarge)

                val info = loadLatestTheorycrafterReleasesAsState().value
                if (info == null) {
                    SingleLineText("Checking for updates")
                } else if (info.isFailure) {
                    Text(info.failure())
                } else {
                    val releases = info.value()
                    val upgradeLane = TheorycrafterContext.settings.theorycrafterReleases.latestUpgradeableReleaseType()
                    val releaseInfo = upgradeLane?.let { releases[it] }
                    if (releaseInfo == null) {
                        val userUpgradeLane = TheorycrafterContext.settings.theorycrafterReleases.upgradeLane
                        SingleLineText("No ${userUpgradeLane.displayName} or better release is available yet")
                    }
                    else if (releaseInfo.versionCode == Theorycrafter.VersionCode)
                        SingleLineText("Theorycrafter is up to date")
                    else {
                        SingleLineText(
                            text = "Latest ${upgradeLane.displayName} Release",
                            style = TheorycrafterTheme.textStyles.mediumHeading
                        )
                        VSpacer(TheorycrafterTheme.spacing.xxxsmall)
                        SingleLineText(releaseInfo.versionName)
                        SingleLineText(releaseInfo.displayReleaseDate)
                        SingleLineText(releaseInfo.releaseNote)
                    }

                    if (releaseInfo != null) {
                        DisableSelection {
                            VSpacer(TheorycrafterTheme.spacing.xxxsmall)
                            UrlText(
                                text = "Release web page",
                                url = releaseInfo.infoUrl
                            )
                        }
                    }
                }
            }
        }
    }
}