package app.voltplan.cable.ui.bom

import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material.icons.outlined.CheckCircle
import androidx.compose.material.icons.outlined.OpenInNew
import androidx.compose.material.icons.outlined.PictureAsPdf
import androidx.compose.material.icons.outlined.RadioButtonUnchecked
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import app.voltplan.cable.CableApplication
import app.voltplan.cable.R
import app.voltplan.cable.data.UnitSystem
import app.voltplan.cable.ui.LocalUnitSettings
import app.voltplan.cable.ui.loads.CalcState
import app.voltplan.cable.pdf.SystemBomPdf
import kotlinx.coroutines.launch

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BillOfMaterialsScreen(systemId: String, onBack: () -> Unit) {
    val context = LocalContext.current
    val app = context.applicationContext as CableApplication
    val vm: BillOfMaterialsViewModel = viewModel(
        key = "bom-$systemId",
        factory = viewModelFactory { initializer { BillOfMaterialsViewModel(app, systemId) } },
    )
    val state by vm.state.collectAsStateWithLifecycle()
    val unit by LocalUnitSettings.current.unitSystem.collectAsStateWithLifecycle()
    val scope = rememberCoroutineScope()

    Scaffold(
        topBar = {
            androidx.compose.material3.TopAppBar(
                navigationIcon = {
                    IconButton(onClick = onBack) { Icon(Icons.AutoMirrored.Outlined.ArrowBack, contentDescription = stringResource(R.string.action_back)) }
                },
                title = { Text(stringResource(R.string.bom_navigation_title)) },
                actions = {
                    IconButton(
                        enabled = state.sections.isNotEmpty(),
                        onClick = {
                            vm.logPdfExported()
                            scope.launch { SystemBomPdf.exportAndShare(context, state, unit) }
                        },
                    ) { Icon(Icons.Outlined.PictureAsPdf, contentDescription = stringResource(R.string.bom_export_pdf_button)) }
                },
            )
        },
    ) { padding ->
        if (state.sections.isEmpty()) {
            Column(Modifier.padding(padding).fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) {
                Text(stringResource(R.string.bom_empty_message), color = MaterialTheme.colorScheme.onSurfaceVariant)
            }
            return@Scaffold
        }
        LazyColumn(Modifier.padding(padding).fillMaxSize(), contentPadding = androidx.compose.foundation.layout.PaddingValues(16.dp)) {
            state.sections.forEach { section ->
                item(key = "header-${section.category}") {
                    Column(Modifier.padding(top = 12.dp, bottom = 4.dp)) {
                        Text(stringResource(section.category.titleRes), style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold)
                        Text(stringResource(section.category.subtitleRes), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
                    }
                }
                items(section.items.size, key = { section.items[it].id }) { idx ->
                    val bomItem = section.items[idx]
                    ChecklistRow(
                        title = bomItem.title,
                        detail = bomItem.detail,
                        metric = bomItem.metricText,
                        completed = vm.isCompleted(bomItem, state.completed),
                        hasLink = bomItem.destination.toUrl() != null,
                        onToggle = { vm.toggle(bomItem) },
                        onOpen = {
                            bomItem.destination.toUrl()?.let { url ->
                                vm.logItemTapped(bomItem)
                                vm.markComplete(bomItem)
                                context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
                            }
                        },
                    )
                }
            }
        }
    }
}

@Composable
fun ChecklistRow(
    title: String,
    detail: String,
    metric: String,
    completed: Boolean,
    hasLink: Boolean,
    onToggle: () -> Unit,
    onOpen: () -> Unit,
) {
    Row(
        Modifier
            .fillMaxWidth()
            .clickable { if (hasLink) onOpen() else onToggle() }
            .padding(vertical = 10.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(12.dp),
    ) {
        IconButton(onClick = onToggle, modifier = Modifier.size(28.dp)) {
            Icon(
                if (completed) Icons.Outlined.CheckCircle else Icons.Outlined.RadioButtonUnchecked,
                contentDescription = null,
                tint = if (completed) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
            )
        }
        Column(Modifier.weight(1f)) {
            Text(
                title,
                style = MaterialTheme.typography.titleSmall,
                textDecoration = if (completed) TextDecoration.LineThrough else null,
            )
            if (detail.isNotBlank()) {
                Text(detail, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
            }
            if (metric.isNotBlank()) {
                Text(metric, style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary)
            }
        }
        if (hasLink) {
            Icon(Icons.Outlined.OpenInNew, contentDescription = null, tint = MaterialTheme.colorScheme.onSurfaceVariant)
        }
    }
}

/** Per-load BOM sheet shown from the calculator's "Review parts" button. */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LoadBillOfMaterialsSheet(state: CalcState, unitSystem: UnitSystem, onDismiss: () -> Unit) {
    val context = LocalContext.current
    val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
    // Build BOM for this single (transient) load.
    val load = app.voltplan.cable.data.model.SavedLoad(
        name = state.loadName,
        voltage = state.voltage,
        current = state.current,
        power = state.power,
        length = state.length,
        crossSection = 1.0,
        iconName = state.iconName,
        colorName = state.colorName,
        isWattMode = state.isWattMode,
        affiliateURLString = state.affiliateURLString,
        affiliateCountryCode = state.affiliateCountryCode,
    )
    val sections = remember(state, unitSystem) {
        BomBuilder.build(context, listOf(load.copy(length = if (load.length > 0) load.length else 1.0)), emptyList(), emptyList(), unitSystem)
    }
    val checked = remember { mutableStateMapOf<String, Boolean>() }

    ModalBottomSheet(onDismissRequest = onDismiss, sheetState = sheetState) {
        Column(Modifier.fillMaxWidth().padding(horizontal = 20.dp).padding(bottom = 24.dp)) {
            Text(stringResource(R.string.bom_navigation_title), style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.SemiBold, modifier = Modifier.padding(vertical = 8.dp))
            sections.forEach { section ->
                Text(stringResource(section.category.titleRes), style = MaterialTheme.typography.titleSmall, modifier = Modifier.padding(top = 8.dp))
                section.items.forEach { bomItem ->
                    ChecklistRow(
                        title = bomItem.title,
                        detail = bomItem.detail,
                        metric = bomItem.metricText,
                        completed = checked[bomItem.id] == true,
                        hasLink = bomItem.destination.toUrl() != null,
                        onToggle = { checked[bomItem.id] = !(checked[bomItem.id] ?: false) },
                        onOpen = {
                            bomItem.destination.toUrl()?.let { url ->
                                checked[bomItem.id] = true
                                context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
                            }
                        },
                    )
                }
            }
            Text(
                stringResource(R.string.affiliate_disclaimer),
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant,
                modifier = Modifier.padding(top = 12.dp),
            )
        }
    }
}
