package com.doctate.watch.presentation

import android.app.Activity
import android.app.RemoteInput
import android.os.Bundle
import android.speech.RecognizerIntent
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
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.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
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.text.font.FontFamily
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.wear.compose.material3.EdgeButton
import androidx.wear.compose.material3.MaterialTheme
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.material3.Text
import androidx.wear.input.RemoteInputIntentHelper
import com.doctate.watch.DoctateApp
import com.doctate.watch.audio.PendingStore
import com.doctate.watch.domain.OnelinerState
import com.doctate.watch.domain.displayText
import com.doctate.watch.domain.isManual
import java.time.Instant
import kotlinx.coroutines.launch
import java.time.LocalDate
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.Locale

private const val ONELINER_INPUT_KEY = "oneliner"

// BCP-47 tag pinned to German so voice input stays in the app's language
// regardless of the watch's system locale. Medical vocabulary needs de-DE
// to produce usable transcripts.
private val VOICE_INPUT_LANGUAGE: String = Locale.GERMANY.toLanguageTag()

private val detailDateFormat = DateTimeFormatter.ofPattern("dd.MM.yy", Locale.getDefault())
private val detailTimeFormat = DateTimeFormatter.ofPattern("HH:mm:ss", Locale.getDefault())

@Composable
fun CaseDetailScreen(
    caseId: String,
    onRecord: () -> Unit,
) {
    val app = LocalContext.current.applicationContext as DoctateApp
    val cases by app.caseStore.casesFlow.collectAsStateWithLifecycle()
    val case = cases.firstOrNull { it.caseId == caseId }
    val coroutineScope = rememberCoroutineScope()

    val editLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartActivityForResult(),
    ) { result ->
        if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
        val text = result.data
            ?.let { RemoteInput.getResultsFromIntent(it) }
            ?.getCharSequence(ONELINER_INPUT_KEY)
            ?.toString()
            ?.trim()
            .orEmpty()
        if (text.isNotEmpty()) {
            coroutineScope.launch {
                // Optimistic local update — UI flips to Manual immediately.
                app.caseStore.setOnelinerLocal(
                    caseId,
                    OnelinerState.Manual(text, setAt = PendingStore.nowRfc3339()),
                )
                // Push the edit to the server. Fire-and-forget: the local
                // state stays even if the network is down. Edits before
                // the case has been uploaded will 404 here — that's
                // logged inside the client and we accept the divergence
                // until the next manual edit lands after upload.
                app.onelinerOverrideClient.put(caseId, text)
            }
        }
    }

    val launchEdit: () -> Unit = {
        val languageExtras = Bundle().apply {
            putString(RecognizerIntent.EXTRA_LANGUAGE, VOICE_INPUT_LANGUAGE)
            putString(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, VOICE_INPUT_LANGUAGE)
        }
        val remoteInput = RemoteInput.Builder(ONELINER_INPUT_KEY)
            .setLabel("OneLiner")
            .setAllowFreeFormInput(true)
            .addExtras(languageExtras)
            .build()
        val intent = RemoteInputIntentHelper.createActionRemoteInputIntent().apply {
            putExtra(RecognizerIntent.EXTRA_LANGUAGE, VOICE_INPUT_LANGUAGE)
            putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, VOICE_INPUT_LANGUAGE)
        }
        RemoteInputIntentHelper.putRemoteInputsExtra(intent, listOf(remoteInput))
        RemoteInputIntentHelper.putTitleExtra(intent, "OneLiner")
        editLauncher.launch(intent)
    }

    ScreenScaffold { contentPadding ->
        if (case == null) {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(contentPadding)
                    .padding(horizontal = 16.dp),
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.Center,
            ) {
                Text(
                    "Fall nicht gefunden",
                    style = MaterialTheme.typography.bodyMedium,
                    textAlign = TextAlign.Center,
                )
            }
        } else {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(contentPadding)
                    .padding(horizontal = 16.dp),
            ) {
                // Top third: date label over HH:mm:ss clock.
                Column(
                    modifier = Modifier.weight(1f).fillMaxWidth(),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.Center,
                ) {
                    Text(
                        text = formatDetailDate(case.createdAt),
                        style = MaterialTheme.typography.bodySmall,
                        color = MaterialTheme.colorScheme.onSurfaceVariant,
                        textAlign = TextAlign.Center,
                    )
                    Text(
                        text = formatDetailTime(case.createdAt),
                        style = MaterialTheme.typography.bodySmall,
                        fontFamily = FontFamily.Monospace,
                        color = MaterialTheme.colorScheme.onSurfaceVariant,
                        textAlign = TextAlign.Center,
                    )
                }
                // Middle third: prominent one-liner. Tap launches the Wear OS
                // system input picker (voice / keyboard / handwriting).
                Column(
                    modifier = Modifier
                        .weight(1f)
                        .fillMaxWidth()
                        .clickable(onClick = launchEdit),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.Center,
                ) {
                    Text(
                        text = case.oneliner.displayText()
                            ?.let { if (case.oneliner.isManual()) "👤 $it" else it }
                            ?: "…",
                        style = MaterialTheme.typography.titleMedium,
                        textAlign = TextAlign.Center,
                        maxLines = 2,
                        overflow = TextOverflow.Ellipsis,
                    )
                }
                // Bottom third: reserved for EdgeButton.
                Spacer(modifier = Modifier.weight(1f))
            }
        }
        EdgeButton(
            onClick = onRecord,
            modifier = Modifier.align(Alignment.BottomCenter),
        ) {
            Box(
                modifier = Modifier
                    .size(20.dp)
                    .background(
                        color = MaterialTheme.colorScheme.error,
                        shape = CircleShape,
                    ),
            )
        }
    }
}

private fun formatDetailDate(epochMs: Long): String {
    val zone = ZoneId.systemDefault()
    val created = Instant.ofEpochMilli(epochMs).atZone(zone).toLocalDate()
    val today = LocalDate.now(zone)
    return when (created) {
        today -> "Heute"
        today.minusDays(1) -> "Gestern"
        else -> created.format(detailDateFormat)
    }
}

private fun formatDetailTime(epochMs: Long): String =
    Instant.ofEpochMilli(epochMs).atZone(ZoneId.systemDefault()).format(detailTimeFormat)
