package de.softwareapp_hb.privateqrscanner.ui.screens

import androidx.compose.foundation.clickable
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Wifi
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import de.softwareapp_hb.privateqrscanner.R
import de.softwareapp_hb.privateqrscanner.domain.ScanResult
import de.softwareapp_hb.privateqrscanner.ui.theme.PrivateQrColors
import de.softwareapp_hb.privateqrscanner.util.ParsedContact
import de.softwareapp_hb.privateqrscanner.util.ScanContentParsers
import de.softwareapp_hb.privateqrscanner.util.UrlRiskScorer
import java.text.DateFormat
import java.util.Date

private data class ResultField(
    val label: String,
    val value: String
)

@Composable
internal fun ResultVisualCard(
    result: ScanResult,
    onOpenUrl: ((String) -> Unit)? = null,
    modifier: Modifier = Modifier
) {
    val context = LocalContext.current
    val contact = remember(result) {
        if (result.isBase64Encoded) null else ScanContentParsers.parseContact(result.content)
    }
    if (!result.isBase64Encoded && (contact != null || result.type == "Contact")) {
        ContactVisualCard(
            contact = contact,
            rawContent = result.content,
            modifier = modifier
        )
        return
    }

    val fields = remember(result) { buildResultFields(result) }
    Card(
        modifier = modifier.fillMaxWidth(),
        colors = CardDefaults.cardColors(containerColor = PrivateQrColors.SoftSurface),
        shape = RoundedCornerShape(26.dp)
    ) {
        Column(
            modifier = Modifier.padding(22.dp),
            verticalArrangement = Arrangement.spacedBy(14.dp)
        ) {
            if (!result.isBase64Encoded && result.type == "WiFi") {
                Row(
                    horizontalArrangement = Arrangement.spacedBy(10.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Icon(
                        imageVector = Icons.Default.Wifi,
                        contentDescription = null,
                        tint = PrivateQrColors.Teal700
                    )
                    Text(
                        text = result.localizedDisplayType(context),
                        style = MaterialTheme.typography.headlineSmall
                    )
                }
            } else {
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.spacedBy(10.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Text(
                        text = result.localizedDisplayType(context),
                        style = MaterialTheme.typography.headlineSmall,
                        color = PrivateQrColors.TextPrimary
                    )
                    if (!result.isBase64Encoded && result.type == "URL") {
                        Text(
                            text = stringResource(R.string.result_local_check),
                            color = PrivateQrColors.Teal700,
                            style = MaterialTheme.typography.labelLarge,
                            modifier = Modifier
                                .background(
                                    color = PrivateQrColors.Mint,
                                    shape = RoundedCornerShape(50)
                                )
                                .padding(horizontal = 12.dp, vertical = 6.dp)
                        )
                    }
                }
            }
            if (result.isBase64Encoded) {
                Text(
                    text = stringResource(R.string.base64_encoded_notice),
                    style = MaterialTheme.typography.bodySmall,
                    color = PrivateQrColors.TextSecondary
                )
            }
            if (fields.isEmpty()) {
                Text(
                    text = result.content,
                    style = MaterialTheme.typography.bodyMedium
                )
            } else {
                fields.forEach { field ->
                    Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
                        Text(
                            text = field.label,
                            style = MaterialTheme.typography.labelMedium,
                            color = PrivateQrColors.TextSecondary
                        )
                        val isClickableUrl = result.type == "URL" &&
                            field.label == "Link" &&
                            onOpenUrl != null
                        Text(
                            text = field.value,
                            style = MaterialTheme.typography.bodyMedium,
                            color = if (isClickableUrl) Color(0xFF1D4ED8) else PrivateQrColors.TextPrimary,
                            textDecoration = if (isClickableUrl) TextDecoration.Underline else null,
                            modifier = if (isClickableUrl) {
                                Modifier.clickable { onOpenUrl(field.value) }
                            } else {
                                Modifier
                            },
                            maxLines = 3,
                            overflow = TextOverflow.Ellipsis
                        )
                    }
                }
            }
            if (!result.isBase64Encoded && result.type == "URL") {
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .background(
                            color = Color(0xFFECFDF5),
                            shape = RoundedCornerShape(18.dp)
                        )
                        .padding(horizontal = 14.dp, vertical = 12.dp),
                    horizontalArrangement = Arrangement.spacedBy(10.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Text(
                        text = "✓",
                        color = PrivateQrColors.Teal700,
                        style = MaterialTheme.typography.titleMedium
                    )
                    Text(
                        text = stringResource(R.string.result_checked_on_device),
                        color = PrivateQrColors.Teal700,
                        style = MaterialTheme.typography.labelLarge
                    )
                }
            }
        }
    }
}

private enum class ContactCardTemplate {
    Minimal,
    Corporate,
    Playful
}

@Composable
private fun ContactVisualCard(
    contact: ParsedContact?,
    rawContent: String,
    modifier: Modifier = Modifier
) {
    val template = remember(contact, rawContent) { selectContactTemplate(contact, rawContent) }
    val background = when (template) {
        ContactCardTemplate.Corporate -> Brush.linearGradient(
            listOf(Color(0xFF081C3B), Color(0xFF0F2E58), Color(0xFF134B73))
        )
        ContactCardTemplate.Playful -> Brush.linearGradient(
            listOf(Color(0xFFFFF9EC), Color(0xFFF8F1FF), Color(0xFFEFF6FF))
        )
        ContactCardTemplate.Minimal -> Brush.linearGradient(
            listOf(Color(0xFFF9FAFC), Color(0xFFF1F5F9))
        )
    }
    val accentColor = when (template) {
        ContactCardTemplate.Corporate -> Color(0xFF7AF7CF)
        ContactCardTemplate.Playful -> Color(0xFF304FFE)
        ContactCardTemplate.Minimal -> Color(0xFF1E293B)
    }
    val textPrimary = when (template) {
        ContactCardTemplate.Corporate -> Color.White
        ContactCardTemplate.Playful -> Color(0xFF16181D)
        ContactCardTemplate.Minimal -> Color(0xFF0F172A)
    }
    val textMuted = when (template) {
        ContactCardTemplate.Corporate -> Color(0xFFC7D6E8)
        ContactCardTemplate.Playful -> Color(0xFF55657B)
        ContactCardTemplate.Minimal -> Color(0xFF475569)
    }
    val fallbackName = stringResource(R.string.scan_type_contact)
    val name = contact?.fullName ?: fallbackName
    val subtitle = listOfNotNull(contact?.title, contact?.organization).distinct().joinToString(" • ")
    val initials = remember(name) { initialsFromName(name) }

    Card(
        modifier = modifier.fillMaxWidth(),
        colors = CardDefaults.cardColors(containerColor = Color.Transparent),
        shape = RoundedCornerShape(16.dp)
    ) {
        Column(
            modifier = Modifier
                .background(background)
                .padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(10.dp)
        ) {
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.spacedBy(12.dp),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Box(
                    modifier = Modifier
                        .background(
                            color = accentColor.copy(
                                alpha = when (template) {
                                    ContactCardTemplate.Corporate -> 0.18f
                                    ContactCardTemplate.Playful -> 0.15f
                                    ContactCardTemplate.Minimal -> 0.12f
                                }
                            ),
                            shape = RoundedCornerShape(12.dp)
                        )
                        .padding(horizontal = 12.dp, vertical = 10.dp),
                    contentAlignment = Alignment.Center
                ) {
                    Text(
                        text = initials,
                        color = accentColor,
                        style = MaterialTheme.typography.titleMedium
                    )
                }
                Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
                    Text(
                        text = name,
                        color = textPrimary,
                        style = MaterialTheme.typography.headlineSmall
                    )
                    if (subtitle.isNotBlank()) {
                        Text(
                            text = subtitle,
                            color = textMuted,
                            style = MaterialTheme.typography.bodyMedium
                        )
                    }
                }
            }

            ContactLine("Phone", contact?.phones?.firstOrNull(), textPrimary, textMuted)
            ContactLine("Email", contact?.emails?.firstOrNull(), textPrimary, textMuted)
            ContactLine("Address", contact?.address, textPrimary, textMuted)
            ContactLine("Note", contact?.note, textPrimary, textMuted)
            if (contact == null) {
                ContactLine("Raw", rawContent, textPrimary, textMuted)
            }
        }
    }
}

private fun initialsFromName(name: String): String {
    val parts = name.trim().split(Regex("\\s+")).filter { it.isNotBlank() }
    if (parts.isEmpty()) return "?"
    return parts.take(2)
        .mapNotNull { it.firstOrNull()?.uppercaseChar() }
        .joinToString("")
        .ifBlank { "?" }
}

@Composable
private fun ContactLine(
    label: String,
    value: String?,
    textPrimary: Color,
    textMuted: Color
) {
    if (value.isNullOrBlank()) return
    Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
        Text(
            text = label,
            color = textMuted,
            style = MaterialTheme.typography.labelSmall
        )
        Text(
            text = value,
            color = textPrimary,
            style = MaterialTheme.typography.bodyMedium,
            maxLines = 2,
            overflow = TextOverflow.Ellipsis
        )
    }
}

private fun selectContactTemplate(contact: ParsedContact?, rawContent: String): ContactCardTemplate {
    val isCardPayload = rawContent.contains("BEGIN:VCARD", ignoreCase = true) ||
        rawContent.startsWith("MECARD:", ignoreCase = true)
    val looksCorporate = !contact?.organization.isNullOrBlank() ||
        !contact?.title.isNullOrBlank()
    val denseStructuredData = listOf(
        contact?.phones?.firstOrNull(),
        contact?.emails?.firstOrNull(),
        contact?.address,
        contact?.note
    ).count { !it.isNullOrBlank() } >= 3

    return when {
        looksCorporate || isCardPayload -> ContactCardTemplate.Corporate
        denseStructuredData -> ContactCardTemplate.Minimal
        else -> ContactCardTemplate.Playful
    }
}

private fun buildResultFields(result: ScanResult): List<ResultField> {
    if (result.isBase64Encoded) {
        return listOf(ResultField("Encoded data", result.content))
    }
    return when (result.type) {
        "Contact" -> {
            val contact = ScanContentParsers.parseContact(result.content)
            listOfNotNull(
                contact?.fullName?.let { ResultField("Name", it) },
                contact?.organization?.let { ResultField("Company", it) },
                contact?.title?.let { ResultField("Title", it) },
                contact?.phones?.firstOrNull()?.let { ResultField("Phone", it) },
                contact?.emails?.firstOrNull()?.let { ResultField("Email", it) },
                contact?.address?.let { ResultField("Address", it) }
            )
        }
        "Calendar" -> {
            val event = ScanContentParsers.parseCalendarEvent(result.content)
            val dateTime = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT)
            listOfNotNull(
                event?.title?.let { ResultField("Title", it) },
                event?.location?.let { ResultField("Location", it) },
                event?.startMillis?.let { ResultField("Start", dateTime.format(Date(it))) },
                event?.endMillis?.let { ResultField("End", dateTime.format(Date(it))) },
                event?.description?.let { ResultField("Details", it) }
            )
        }
        "WiFi" -> {
            val map = parseWifiFields(result.content)
            listOfNotNull(
                map["S"]?.takeIf { it.isNotBlank() }?.let { ResultField("SSID", it) },
                map["T"]?.takeIf { it.isNotBlank() }?.let { ResultField("Security", it) },
                map["P"]?.takeIf { it.isNotBlank() }?.let { ResultField("Password", it) }
            )
        }
        "URL" -> {
            val score = UrlRiskScorer.score(result.content)
            listOf(
                ResultField("Link", result.content),
                ResultField("Risk score", score.score.toString())
            )
        }
        "SMS" -> {
            val (number, body) = ScanContentParsers.parseSms(result.content)
            listOfNotNull(
                number.takeIf { it.isNotBlank() }?.let { ResultField("To", it) },
                body?.takeIf { it.isNotBlank() }?.let { ResultField("Message", it) }
            )
        }
        "Email" -> {
            val email = ScanContentParsers.extractEmail(result.content)
            listOf(ResultField("Email", email))
        }
        "Phone" -> {
            val phone = ScanContentParsers.extractPhoneNumber(result.content)
            listOf(ResultField("Phone", phone))
        }
        else -> emptyList()
    }
}

private fun parseWifiFields(raw: String): Map<String, String> {
    val cleaned = raw.trim()
    if (!cleaned.startsWith("WIFI:", ignoreCase = true)) return emptyMap()
    val payload = cleaned.substringAfter("WIFI:", "").trim().trimEnd(';')
    val values = mutableMapOf<String, String>()
    payload.split(';').forEach { token ->
        val key = token.substringBefore(':', "").trim()
        if (key.isBlank()) return@forEach
        val value = token.substringAfter(':', "").trim()
        values[key] = value
    }
    return values
}
