package com.isidroid.c23.ui.screen.details.component

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.LinearProgressIndicator
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.isidroid.c23.R
import com.isidroid.c23.domain.dto.PrintJobListItem
import com.isidroid.c23.ui._component.TopAppBarComponent
import com.isidroid.c23.ui.screen.details.JobDetailsContract
import com.isidroid.c23.ui.screen.map.MapContract
import com.isidroid.c23.ui.screen.map._components.TPMapComponent
import com.isidroid.ui.maps.model.MapMarker
import com.isidroid.utils.asCost
import com.isidroid.utils.spaceInCenter
import kotlinx.coroutines.flow.StateFlow
import timber.log.Timber
import java.text.DateFormat

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DetailsV2(
    state: State<JobDetailsContract.State>,
    spotResultStateFlow: StateFlow<List<MapMarker>>,
    onEventSent: (event: JobDetailsContract.Event) -> Unit,
    modifier: Modifier = Modifier,
) {
    val printJob = state.value.printJob ?: return

    Scaffold(modifier = modifier.fillMaxSize(), topBar = {
        TopAppBarComponent(
            text = stringResource(id = R.string.print_job_details),
            colors = TopAppBarDefaults.topAppBarColors(),
            onNavigationClick = { onEventSent(JobDetailsContract.Event.ToBack) }
        )
    }) { paddingValues ->

        Column(
            modifier = Modifier
                .fillMaxWidth()
                .consumeWindowInsets(paddingValues)
                .padding(top = paddingValues.calculateTopPadding())
                .padding(horizontal = 16.dp)
        ) {

            PrintInfoComponent(printJob)

            ProgressComponentState(state)

            HorizontalDivider(Modifier.padding(vertical = 16.dp))
            SpotInfoComponent(
                lat = state.value.lat,
                lng = state.value.lng,
                distance = state.value.distance,
                printJob = printJob,
                spotResultStateFlow = spotResultStateFlow,
                onEventSent = onEventSent,
                paddingBottom = paddingValues.calculateBottomPadding()
            )
        }

        DisplayMapRouteConfirmation(state, onEventSent)
    }
}

@Composable
private fun ProgressComponentState(
    state: State<JobDetailsContract.State>,
    modifier: Modifier = Modifier
) {
    val renderProgress = state.value.renderProgress
    val uploadProgress = state.value.uploadProgress

    val index = renderProgress?.first ?: uploadProgress?.first ?: return
    val total = renderProgress?.second ?: uploadProgress?.second ?: return

    ProgressComponent(index, total, isRender = renderProgress != null, modifier)
}

@Composable
private fun ProgressComponent(
    index: Int,
    total: Int,
    isRender: Boolean,
    modifier: Modifier = Modifier
) {
    val progress = index.toFloat() / total.toFloat()
    val title = if (isRender) R.string.progress_rendering else R.string.progress_uploading

    Timber.i("===> progress=$index/$total, progress=$progress")

    Column(
        modifier = modifier
            .fillMaxWidth()
            .padding(bottom = 16.dp),
        horizontalAlignment = Alignment.End
    ) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 16.dp, bottom = 2.dp)
        ) {
            Text(
                text = stringResource(id = title),
                modifier = Modifier.weight(1f),
                style = MaterialTheme.typography.labelLarge
            )

            Text(
                text = "$index/$total",
                style = MaterialTheme.typography.labelLarge,
                fontWeight = FontWeight.Medium
            )
        }

        LinearProgressIndicator(
            progress = progress,
            modifier = Modifier.fillMaxWidth()
        )
    }
}



@Composable
private fun PrintInfoComponent(printJob: PrintJobListItem) {
    val textStrings = listOfNotNull(
        "PIN code: ${printJob.accessCode.spaceInCenter()}",
        "${printJob.cost.asCost()} | Unpaid",
        "${printJob.profileCost?.asCost()} per page",
        DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT).format(printJob.createdAt),
        "copies: ${printJob.copies}",
        printJob.profileName,
    )

    for (text in textStrings) {
        Text(text = text)
        Spacer(modifier = Modifier.height(8.dp))
    }

    Text(
        text = printJob.statusName,
        fontWeight = FontWeight.W200,
        letterSpacing = .76.sp,
        color = Color.White,
        modifier = Modifier
            .clip(RoundedCornerShape(6.dp))
            .background(printJob.statusColor)
            .padding(horizontal = 6.dp, vertical = 2.dp)
    )
}

@Composable
private fun ColumnScope.SpotInfoComponent(
    lat: Double?,
    lng: Double?,
    distance: String?,
    printJob: PrintJobListItem,
    spotResultStateFlow: StateFlow<List<MapMarker>>,
    onEventSent: (event: JobDetailsContract.Event) -> Unit,
    paddingBottom: Dp
) {
    val textStrings = listOfNotNull(
        "Spot: ${printJob.spotName}",
        "Address: ${printJob.spotAddress}",
        distance?.let { "Distance: $distance" }
    )

    for (text in textStrings) {
        Text(text = text)
        Spacer(modifier = Modifier.height(8.dp))
    }

    Card(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 24.dp)
            .weight(1f),
        shape = RoundedCornerShape(16.dp),
        elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
    ) {
        TPMapComponent(
            modifier = Modifier,
            onEventSent = { event ->
                when (event) {
                    is MapContract.Event.ClickOnMarker -> onEventSent(JobDetailsContract.Event.OpenConfirmationMapRoute)
                    else -> {}
                }
            },
            mapMarkersStateFlow = spotResultStateFlow,
            lat = lat,
            lng = lng
        )
    }

    Button(
        onClick = { onEventSent(JobDetailsContract.Event.OpenConfirmationMapRoute) },
        modifier = Modifier
            .padding(bottom = paddingBottom, top = 16.dp)
            .fillMaxWidth()
    ) {
        Text(text = "Build a route to Print spot")
    }
}