package de.softwareapp_hb.privateqrscanner.ui.screens

import android.content.Context
import androidx.annotation.StringRes
import de.softwareapp_hb.privateqrscanner.R
import de.softwareapp_hb.privateqrscanner.domain.ScanRecord
import de.softwareapp_hb.privateqrscanner.domain.ScanResult

private const val DUPLICATE_TICKET_PREFIX = "Duplicate ticket ("
private const val UNREGISTERED_TICKET_PREFIX = "Unregistered ticket ("
private val base64SuffixRegex = Regex("""\s*\(Base64\)\s*$""", RegexOption.IGNORE_CASE)

internal fun ScanResult.localizedDisplayType(context: Context): String {
    return localizedScanType(
        context = context,
        type = type,
        isBase64Encoded = isBase64Encoded
    )
}

internal fun ScanRecord.localizedDisplayType(context: Context): String {
    return localizedStoredScanType(context, type)
}

private fun localizedStoredScanType(context: Context, rawType: String): String {
    val trimmed = rawType.trim()
    extractWrappedType(trimmed, DUPLICATE_TICKET_PREFIX)?.let { innerType ->
        return context.getString(
            R.string.scan_type_duplicate_ticket,
            localizedStoredScanType(context, innerType)
        )
    }
    extractWrappedType(trimmed, UNREGISTERED_TICKET_PREFIX)?.let { innerType ->
        return context.getString(
            R.string.scan_type_unregistered_ticket,
            localizedStoredScanType(context, innerType)
        )
    }
    if (base64SuffixRegex.containsMatchIn(trimmed)) {
        val innerType = base64SuffixRegex.replace(trimmed, "").trim()
        return context.getString(
            R.string.scan_type_base64_suffix,
            localizedCanonicalScanType(context, innerType)
        )
    }
    return localizedCanonicalScanType(context, trimmed)
}

private fun localizedScanType(
    context: Context,
    type: String,
    isBase64Encoded: Boolean
): String {
    val baseType = localizedCanonicalScanType(context, type)
    return if (isBase64Encoded && !type.contains("base64", ignoreCase = true)) {
        context.getString(R.string.scan_type_base64_suffix, baseType)
    } else {
        baseType
    }
}

private fun localizedCanonicalScanType(context: Context, type: String): String {
    val stringRes = scanTypeStringRes(type)
    return if (stringRes != null) {
        context.getString(stringRes)
    } else {
        type.ifBlank { context.getString(R.string.scan_type_unknown) }
    }
}

private fun extractWrappedType(type: String, prefix: String): String? {
    return if (type.startsWith(prefix, ignoreCase = true) && type.endsWith(")")) {
        type.substring(prefix.length, type.length - 1)
    } else {
        null
    }
}

@StringRes
private fun scanTypeStringRes(type: String): Int? = when (type.trim().lowercase()) {
    "contact" -> R.string.scan_type_contact
    "url" -> R.string.scan_type_url
    "wifi", "wi-fi" -> R.string.scan_type_wifi
    "phone" -> R.string.scan_type_phone
    "sms" -> R.string.scan_type_sms
    "email", "e-mail" -> R.string.scan_type_email
    "calendar" -> R.string.scan_type_calendar
    "isbn" -> R.string.scan_type_isbn
    "product" -> R.string.scan_type_product
    "text" -> R.string.scan_type_text
    "geo" -> R.string.scan_type_geo
    "driver license", "driver licence" -> R.string.scan_type_driver_license
    "unknown" -> R.string.scan_type_unknown
    else -> null
}
