package com.korancrew.brizzi.hce

/** Catatan transaksi log single-entry (payload yang disimpan di card log stack). */
data class BrizziLogRecord(
    val merchantIdHex: String,
    val terminalIdAsciiHex: String,
    val trxDateHex: String,
    val trxTimeHex: String,
    val trxTypeHex: String,
    val amountReversedHex: String,
    val balanceBeforeReversedHex: String,
    val balanceAfterReversedHex: String,
) {
    fun toHex(): String = buildString {
        append(merchantIdHex)
        append(terminalIdAsciiHex)
        append(trxDateHex)
        append(trxTimeHex)
        append(trxTypeHex)
        append(amountReversedHex)
        append(balanceBeforeReversedHex)
        append(balanceAfterReversedHex)
    }
}

/** Model kartu emulated yang dipakai di runtime HCE. */
data class BrizziCard(
    val cardNumberHex: String = "6013501801640532",
    val persoDateHex: String = "070618",
    val issuerCodeHex: String = "3112",
    val cardInfoTailHex: String = "99020631380000",
    val cardStatusHex: String = "6161",
    val uidHex: String = "0489634ADC5A80",
    val versionFrame1Hex: String = "04010101001A05",
    val versionFrame2Hex: String = "04010101041A05",
    val versionFrame3Hex: String = "0489634ADC5A80B90C1755205217",
    val keyCard00Hex: String = "19180F5342630D03",
    val keyCard01Hex: String = "0123456789ABCD12",
    val randomNumberHex: String = "189DFB4D7E42DD33",
    val lastTransactionDateHex: String = "260427",
    val akumDebetHex: String = "00000048",
    val balance: Int = 21_000,
    val logs: List<BrizziLogRecord> = listOf(
        "00000017273400003134323735383637220426155025EB881300906500085200",
        "4E45574252494D4F4E45574252494D4F230426103843EC50C300085200581501",
        "00000019295700603130303835353639230426105640EB803E0001155800D6D8",
        "00000199914095600000000010721822230426105310EB4C1D00D8D6008CB900",
        "00000019988100093130373136343436230426112353EB7C150000B98C00A410",
        "00000019988100083130373136343237230426180344EB7C150000A410008E94",
        "00000199910224000000000010853934230426183111EBCC5B00948E00C83200",
        "4E45574252494D4F4E45574252494D4F270426093435EC204E00C83200E88000",
        "00000017273400143130303937323335270426115241EB881300E88000606D00",
        "00000019992031053130333431363235270426140259EBAC0D00606D00B45F00",
        "00000019992031613130333432383034270426175607EBAC0D00B45F00085200",
    ).map(::parseBrizziLogRecord),
)

/** Snapshot read-only yang dipakai untuk observability/testing. */
data class BrizziCardSnapshot(
    val balance: Int,
    val lastTransactionDateHex: String,
    val akumDebetHex: String,
    val logs: List<BrizziLogRecord>,
    val selectedAid: SelectedAid,
    val authenticated: Boolean,
    val pendingTransaction: PendingTransaction?,
)

/** Parse 32-byte hex log record menjadi struktur [BrizziLogRecord]. */
fun parseBrizziLogRecord(hex: String): BrizziLogRecord {
    require(hex.length >= 64) { "BRIZZI log record must be at least 32 bytes" }
    return BrizziLogRecord(
        merchantIdHex = hex.substring(0, 16),
        terminalIdAsciiHex = hex.substring(16, 32),
        trxDateHex = hex.substring(32, 38),
        trxTimeHex = hex.substring(38, 44),
        trxTypeHex = hex.substring(44, 46),
        amountReversedHex = hex.substring(46, 52),
        balanceBeforeReversedHex = hex.substring(52, 58),
        balanceAfterReversedHex = hex.substring(58, 64),
    )
}
