package com.fabledsword.minstrel.shared.widgets

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import kotlinx.coroutines.launch

/**
 * Wraps [content] in a Material3 PullToRefreshBox so the user can
 * swipe-down to trigger [onRefresh]. The wrapper manages the
 * `isRefreshing` indicator while [onRefresh] is in flight. Every pull also
 * fires a /healthz recheck (via [PullRefreshNetworkViewModel]) so a stale
 * connection banner clears promptly on a deliberate user refresh.
 *
 * [onRefresh] is suspend: pass `{ viewModel.refresh().join() }` so the
 * indicator hides exactly when the underlying coroutine completes,
 * not on a heuristic delay. ViewModels whose existing `refresh()`
 * launched into viewModelScope just need to start returning the Job
 * (`fun refresh(): Job = viewModelScope.launch { ... }`).
 *
 * Mirrors the Flutter `RefreshIndicator` wrapping that every list +
 * grid has in the web/mobile client — Android v1 was missing this
 * everywhere (audit #8).
 */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PullToRefreshScaffold(
    onRefresh: suspend () -> Unit,
    modifier: Modifier = Modifier,
    netVm: PullRefreshNetworkViewModel = hiltViewModel(),
    content: @Composable () -> Unit,
) {
    var isRefreshing by remember { mutableStateOf(false) }
    val scope = rememberCoroutineScope()
    PullToRefreshBox(
        isRefreshing = isRefreshing,
        onRefresh = {
            scope.launch {
                isRefreshing = true
                try {
                    netVm.recheck() // deliberate pull → re-probe the server now
                    onRefresh()
                } finally {
                    isRefreshing = false
                }
            }
        },
        modifier = modifier.fillMaxSize(),
    ) {
        content()
    }
}
