package theorycrafter.ui

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.text.selection.DisableSelection
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalUriHandler
import compose.utils.LocalWindow
import compose.utils.VSpacer
import compose.widgets.FlatButtonWithText
import compose.widgets.SingleLineText
import theorycrafter.*
import theorycrafter.tournaments.CurrentTournamentDescriptor
import theorycrafter.tournaments.TournamentDescriptor
import theorycrafter.ui.settings.SettingsPane
import theorycrafter.ui.widgets.CheckboxedText
import theorycrafter.ui.widgets.ClickableText
import theorycrafter.ui.widgets.InnerDialog


/**
 * Possibly shows one of the dialogs we want to display on app startup.
 */
@Composable
fun OnStartupDialogs() {
    var showDeactivateNonCurrentTournamentDialog by remember { mutableStateOf(false) }
    val activeTournament = TheorycrafterContext.tournaments.activeTournamentDescriptor
    if (showDeactivateNonCurrentTournamentDialog && (activeTournament != null)) {
        DeactivateNonCurrentTournamentDialog(
            activeTournament = activeTournament,
            onDismiss = { showDeactivateNonCurrentTournamentDialog = false },
        )
    }

    var newTheorycrafterReleaseDialogUpgradeReleaseType: ReleaseType? by remember { mutableStateOf(null) }
    newTheorycrafterReleaseDialogUpgradeReleaseType?.let {
        NewTheorycrafterReleaseDialog(
            upgradeReleaseType = it,
            onDismiss = { newTheorycrafterReleaseDialogUpgradeReleaseType = null },
        )
    }

    var showAnalyticsConsentDialog by remember { mutableStateOf(false) }
    if (showAnalyticsConsentDialog) {
        AnalyticsConsentDialog(
            onDismiss = { showAnalyticsConsentDialog = false },
        )
    }

    val settings = TheorycrafterContext.settings

    // Only show one dialog, and only at startup
    val window = LocalWindow.current
    LaunchedEffect(Unit) {
        // AnalyticsConsentDialog - show first if user hasn't made a decision yet
        if (settings.analytics.consent == AnalyticsConsent.Undecided) {
            showAnalyticsConsentDialog = true
            window?.toFront()
            return@LaunchedEffect  // Don't show any other on-startup dialogs
        }

        // DeactivateNonCurrentTournamentDialog
        if ((activeTournament != null)
            && (activeTournament != CurrentTournamentDescriptor)
            && !settings.doNotAskAboutNonCurrentButActiveTournament.value
        ) {
            showDeactivateNonCurrentTournamentDialog = true
            window?.toFront()
            return@LaunchedEffect  // Don't show any other on-startup dialogs
        }

        // NewTheorycrafterReleaseDialog
        val upgradeReleaseTypeAndVersionCode = settings.theorycrafterReleases.latestUpgradeableReleaseTypeAndVersionCode()
        val upgradeVersionCode = upgradeReleaseTypeAndVersionCode?.second
        if ((upgradeVersionCode != null)
            && (upgradeVersionCode > Theorycrafter.VersionCode)
            && (upgradeVersionCode > settings.theorycrafterReleases.latestSkippedVersionCode)
        ) {
            newTheorycrafterReleaseDialogUpgradeReleaseType = upgradeReleaseTypeAndVersionCode.first
            window?.toFront()
            return@LaunchedEffect  // Don't show any other on-startup dialogs
        }
    }
}


/**
 * Dialog asking for user consent for analytics tracking.
 */
@Composable
private fun AnalyticsConsentDialog(
    onDismiss: () -> Unit
) {
    val settings = TheorycrafterContext.settings.analytics

    InnerDialog(
        title = "Allow analytics tracking of your use of ${Theorycrafter.AppName}?",
        confirmText = null,
        dismissText = null,
        extraButtons = {
            FlatButtonWithText(
                text = "Consent",
                onClick = {
                    settings.consent = AnalyticsConsent.Yes
                    onDismiss()
                }
            )
            FlatButtonWithText(
                text = "Decline",
                onClick = {
                    settings.consent = AnalyticsConsent.No
                    onDismiss()
                }
            )
            FlatButtonWithText(
                text = "Decide Later",
                onClick = onDismiss
            )
        },
        onDismiss = onDismiss
    ) {
        Column(
            verticalArrangement = Arrangement.spacedBy(TheorycrafterTheme.spacing.medium),
        ) {
            CollectedInformationDescription()

            Text("You can change this decision any time in the Settings window.")
        }
    }
}


/**
 * When a tournament is over, but is still active for the user, asks about deactivating it.
 */
@Composable
private fun DeactivateNonCurrentTournamentDialog(
    activeTournament: TournamentDescriptor,
    onDismiss: () -> Unit
) {
    InnerDialog(
        confirmText = "Deactivate ${activeTournament.shortName}",
        dismissText = "Close",
        onConfirm = {
            TheorycrafterContext.settings.activeTournamentId = null
        },
        onDismiss = onDismiss
    ) {
        Column {
            Text(
                """
                   ${activeTournament.name} is over. Congratulations to ${activeTournament.winner}!
                   Would you like to stop using the rules for ${activeTournament.shortName} now?
                """.trimIndent()
            )
            VSpacer(TheorycrafterTheme.spacing.larger)
            CheckboxedText(
                text = "Don't ask again",
                state = TheorycrafterContext.settings.doNotAskAboutNonCurrentButActiveTournament
            )
            VSpacer(TheorycrafterTheme.spacing.xsmall)
            Text(
                style = TheorycrafterTheme.textStyles.detailedText(),
                text = "You can change the active tournament any time in Settings→Tournaments"
            )
        }
    }
}


/**
 * The dialog for notifying the user of a new Theorycrafter release.
 */
@Composable
private fun NewTheorycrafterReleaseDialog(
    upgradeReleaseType: ReleaseType,
    onDismiss: () -> Unit
) {
    val urlHandler = LocalUriHandler.current
    val releases = loadLatestTheorycrafterReleasesAsState().value
    val releaseInfo = releases?.valueOrNull()?.get(upgradeReleaseType)
    val windowManager = LocalTheorycrafterWindowManager.current

    InnerDialog(
        title = "New ${Theorycrafter.AppName} Release Available",
        confirmText = null,
        onConfirm = null,
        extraButtons = {
            FlatButtonWithText(
                text = "Visit webpage",
                enabled = releaseInfo != null,
                onClick = {
                    val infoUrl = releaseInfo?.infoUrl
                    if (infoUrl != null)
                        urlHandler.openUri(infoUrl)
                }
            )
            FlatButtonWithText(
                text = "Skip this release",
                enabled = releaseInfo != null,
                onClick = {
                    TheorycrafterContext.settings.theorycrafterReleases.latestSkippedVersionCode = releaseInfo!!.versionCode
                    onDismiss()
                }
            )
            FlatButtonWithText(
                text = "Remind me later",
                onClick = onDismiss
            )
        },
        dismissText = null,
        onDismiss = onDismiss,
    ) {
        if (releases == null) {
            SingleLineText("Fetching latest version metadata")
        } else if (releases.isFailure) {
            Text(releases.failure())
        } else {
            if (releaseInfo == null) {
                // This shouldn't really happen, but just in case...
                SingleLineText("Something is fishy...")
                SingleLineText("No ${upgradeReleaseType.displayName} release is available yet")
            } else {
                SelectionContainer {
                    Column {
                        SingleLineText("Version ${releaseInfo.versionName}")
                        SingleLineText("Released on ${releaseInfo.displayReleaseDate}")
                        SingleLineText(releaseInfo.releaseNote)
                        DisableSelection {
                            VSpacer(TheorycrafterTheme.spacing.small)
                            ClickableText(
                                text = "Change release notification settings",
                                onClick = {
                                    windowManager.showSettingsWindow(SettingsPane.SoftwareUpdates)
                                    onDismiss()
                                }
                            )
                        }
                    }
                }
            }
        }

    }
}