package dev.privacyllc.period.feature.common

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextOverflow
import dev.privacyllc.period.R

/**
 * The chrome every screen below a tab shares: a bar naming the row the user
 * tapped, and an arrow back to it.
 *
 * ## Why this exists as a component rather than three copies
 *
 * Until this file, no screen in the app had a top bar, a back arrow, or any
 * navigation-controller call at all — a grep for `TopAppBar`, `navigationIcon`
 * and `popBackStack` across the whole tree returned nothing. Every settings
 * child relied on the system gesture, and App lock *looked* like it had a bar
 * (a full-bleed Surface with a headline `Text` at the top) without having one.
 * A user who reaches for the affordance she can see finds it is a label.
 *
 * Three copies of a bar would drift: one would get the ellipsis for long titles
 * at font scale 2.0 and the others would wrap mid-word, which is the defect the
 * tab labels already shipped once. One component cannot drift.
 *
 * ## Insets
 *
 * The bar declines window insets deliberately. `PeriodApp`'s `Scaffold` already
 * pads its content region for the status bar and hands that down as
 * `innerPadding`, so a bar that added `TopAppBarDefaults.windowInsets` here
 * would pad it a second time and float below a gap. That makes this composable
 * dependent on its host, which is worth saying out loud: it belongs inside that
 * Scaffold, and putting it on a full-screen route would tuck the arrow under
 * the status bar.
 */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsSubpage(
    title: String,
    onBack: () -> Unit,
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit,
) {
    Surface(modifier = modifier.fillMaxSize()) {
        Column(Modifier.fillMaxSize()) {
            TopAppBar(
                title = {
                    Text(
                        title,
                        maxLines = 1,
                        // Same reasoning as the tab labels: at the largest
                        // accessibility font scale Compose wraps mid-word, and
                        // "App loc / k" is worse than "App lock".
                        overflow = TextOverflow.Ellipsis,
                        // A screen reader can then jump to it, which is how
                        // somebody using one finds out where they are.
                        modifier = Modifier.semantics { heading() },
                    )
                },
                navigationIcon = {
                    IconButton(onClick = onBack) {
                        Icon(
                            Icons.AutoMirrored.Filled.ArrowBack,
                            // AutoMirrored so the arrow turns around in a
                            // right-to-left layout rather than pointing the
                            // wrong way.
                            contentDescription = stringResource(R.string.action_back),
                        )
                    }
                },
                windowInsets = WindowInsets(0),
            )
            Box(Modifier.weight(1f).fillMaxWidth()) { content() }
        }
    }
}
