package theorycrafter.ui

import androidx.compose.foundation.layout.*
import androidx.compose.material.ProvideTextStyle
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.produceState
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import compose.input.KeyShortcut
import compose.utils.EasyTooltipPlacement
import compose.utils.HSpacer
import compose.utils.VerticallyCenteredRow
import compose.widgets.IconButton
import compose.widgets.SingleLineText
import eve.esi.models.GetStatusOk
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import org.jetbrains.skiko.OS
import org.jetbrains.skiko.hostOs
import theorycrafter.LocalTheorycrafterWindowManager
import theorycrafter.TheorycrafterContext
import theorycrafter.esi.StatusApi
import theorycrafter.tournaments.CurrentTournamentDescriptor
import theorycrafter.tournaments.TournamentDescriptorById
import theorycrafter.tournaments.toggleUseCurrentTournamentRules
import theorycrafter.ui.widgets.*
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds


/**
 * The status of Tranquility.
 */
@Composable
private fun tranquilityStatus(): State<Result<GetStatusOk>?> {
    return produceState(initialValue = null) {
        withContext(Dispatchers.IO) {
            delay(2_000)  // Don't interfere with UI startup or class preloading
            while (true) {
                val status = runCatching { StatusApi.getStatus(null, null) }
                value = status
                delay(if (status.isSuccess) 5.minutes else 10.seconds)
            }
        }
    }
}


/**
 * The status bar at the bottom of the main window.
 */
@Composable
fun BottomStatusBar() {
    val tranquilityStatus = tranquilityStatus().value

    val statusText = when {
        tranquilityStatus == null -> "Tranquility status: unknown"
        tranquilityStatus.isFailure ->
            "Failed to retrieve tranquility status: ${tranquilityStatus.exceptionOrNull()!!.message}"
        else -> "Tranquility has ${tranquilityStatus.getOrNull()!!.players} players online"
    }
    VerticallyCenteredRow(
        modifier = Modifier
            .fillMaxWidth()
            .height(TheorycrafterTheme.sizes.statusBarHeight)
            .padding(vertical = TheorycrafterTheme.spacing.xsmall),
    ) {
        Text(
            text = statusText,
            modifier = Modifier
                .padding(start = TheorycrafterTheme.spacing.horizontalEdgeMargin)
        )
        Spacer(Modifier.weight(1f).widthIn(min = TheorycrafterTheme.spacing.xsmall))

        if (CurrentTournamentDescriptor != null) {
            CurrentTournamentMenuButton()
            HSpacer(TheorycrafterTheme.spacing.xsmall)
        }

        val windowManager = LocalTheorycrafterWindowManager.current

        AllTournamentMenuButton()

        StatusBarButton(
            onClick = windowManager::showDoctrinesWindow,
            icon = { Icons.Doctrines("Show Doctrines", modifier = it) },
            tooltipText = "Doctrines",
            shortcut = FitWindowKeyShortcuts.ShowDoctrinesWindow
        )

        StatusBarButton(
            onClick = { windowManager.showGraphsWindow() },
            icon = { Icons.Graphs("Show Graphs", modifier = it) },
            tooltipText = "Graphs",
            shortcut = FitWindowKeyShortcuts.ShowGraphsWindow
        )

        StatusBarButton(
            onClick = windowManager::showMarketTreeWindow,
            icon = { Icons.Market("Show Market Tree", modifier = it) },
            tooltipText = "Market Tree",
            shortcut = FitWindowKeyShortcuts.ShowMarketWindow
        )

        StatusBarButton(
            onClick = windowManager::showSettingsWindow,
            icon = { Icons.Settings("Show Settings", modifier = it) },
            tooltipText = "Settings",
        )

        HSpacer(TheorycrafterTheme.spacing.xsmall)
    }
}


/**
 * A button with an icon placed in the status bar.
 */
@Composable
private fun StatusBarButton(
    onClick: () -> Unit,
    icon: @Composable (Modifier) -> Unit,
    tooltipText: String,
    shortcut: KeyShortcut? = null,
) {
    IconButton(
        onClick = onClick,
        modifier = Modifier
            .tooltip(
                text = tooltipText,
                keyShortcut = shortcut,
                placement = EasyTooltipPlacement.ElementTopCenter
            )
            .fillMaxHeight()
            .focusProperties {
                canFocus = false
            }
    ) {
        icon(
            Modifier.padding(
                vertical = TheorycrafterTheme.spacing.xxsmall,
                horizontal = TheorycrafterTheme.spacing.xsmall
            )
        )
    }
}


/**
 * The button for showing the options for the current tournament.
 */
@Composable
private fun CurrentTournamentMenuButton() {
    val tournament = CurrentTournamentDescriptor!!

    val windowManager = LocalTheorycrafterWindowManager.current
    MenuButton(
        modifier = Modifier
            .tooltip(
                text = tournament.name,
                placement = EasyTooltipPlacement.ElementTopCenter
            )
            .fillMaxHeight(),
        content = { onClick ->
            TheorycrafterTheme.IntegratedButton(onClick = onClick) {
                ProvideTextStyle(
                    // To match the style of the icons
                    TextStyle(fontWeight = if (hostOs == OS.Windows) FontWeight.Bold else FontWeight.SemiBold)
                ) {
                    Checkmark(TheorycrafterContext.tournaments.activeTournamentDescriptor == CurrentTournamentDescriptor)
                    SingleLineText(text = tournament.shortName)
                }
            }
        },
        menuContent = { onCloseMenu ->

            @Composable
            fun menuItem(
                text: String,
                icon: (@Composable () -> Unit)? = EmptyIcon,
                keyShortcut: KeyShortcut? = null,
                action: () -> Unit
            ) {
                MenuItem(
                    text = text,
                    icon = icon,
                    displayedKeyShortcut = keyShortcut,
                    reserveSpaceForKeyShortcut = true,
                    keyShortcutDescriptorWidth = TheorycrafterTheme.sizes.menuItemKeyShortcutWidthMedium,
                    onCloseMenu = onCloseMenu,
                    action = action
                )
            }

            menuItem(
                text = "Use Tournament Rules",
                icon = {
                    Checkmark(checked = TheorycrafterContext.settings.activeTournamentId == tournament.id)
                },
                keyShortcut = FitWindowKeyShortcuts.ToggleUseTournamentRules,
                action = { toggleUseCurrentTournamentRules() },
            )

            menuItem(
                text = "Show Compositions",
                action = { windowManager.showTournamentWindow(tournament) }
            )
        }
    )
}


/**
 * The button to show the tournament window of any past or current tournaments.
 */
@Composable
private fun AllTournamentMenuButton() {
    val windowManager = LocalTheorycrafterWindowManager.current
    MenuButton(
        content = { onClick ->
            StatusBarButton(
                onClick = onClick,
                icon = { modifier -> Icons.Tournaments(modifier) },
                tooltipText = "Tournaments",
            )
        },
        menuContent = { onCloseMenu ->
            MenuItemHeading("Tournaments", extraTopPadding = false)

            for (tournament in TournamentDescriptorById.values) {
                MenuItem(
                    text = tournament.name,
                    onCloseMenu = onCloseMenu,
                    action = {
                        windowManager.showTournamentWindow(tournament)
                    }
                )
            }
        }
    )
}