package com.korancrew.brizzi

import android.content.pm.ApplicationInfo
import android.content.ComponentName
import android.os.Bundle
import android.nfc.NfcAdapter
import android.nfc.cardemulation.CardEmulation
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import android.widget.Button
import android.widget.TextView
import com.korancrew.brizzi.hce.BrizziSecurityMetrics
import java.io.File

/**
 * Entry point UI aplikasi.
 *
 * Peran utama:
 * - Menampilkan status sederhana metrik keamanan (hanya mode debug).
 * - Menyediakan action helper via adb untuk dump/reset metrik runtime.
 *
 * Catatan:
 * - Semua metrik dan status sensitif tidak dimasukkan ke UI produksi.
 * - FLAG_SECURE dipasang agar layar tidak bisa di-screenshot / screen-record dengan mudah.
 */
class MainActivity : AppCompatActivity() {
    private val uiHandler = Handler(Looper.getMainLooper())
    private var apduLogRefreshRunnable: Runnable? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
        setContentView(R.layout.activity_main)

        handleDebugIntent(intent)

        val clearApduButton = findViewById<Button>(R.id.clearApduLogButton)
        clearApduButton.setOnClickListener {
            clearApduLogFile()
            refreshApduLog()
            findViewById<TextView>(R.id.messageView).text = "APDU log cleared"
        }
    }

    override fun onResume() {
        super.onResume()
        setPreferredPaymentService()
        if (isDebuggable()) {
            refreshApduLog()
            scheduleApduLogRefresh()
        }
    }

    override fun onPause() {
        super.onPause()
        clearPreferredPaymentService()
        stopApduLogRefresh()
    }

    override fun onNewIntent(intent: android.content.Intent) {
        super.onNewIntent(intent)
        handleDebugIntent(intent)
    }

    private fun handleDebugIntent(intent: android.content.Intent?) {
        val messageView = findViewById<TextView>(R.id.messageView)
        val action = intent?.action
        val debugPrefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE)
        if (isDebuggable()) {
            when (action) {
                ACTION_DUMP_METRICS -> {
                    // Dump metrik runtime ke UI untuk cepat verifikasi health/incident saat QA.
                    val metrics = BrizziSecurityMetrics(this)
                    val output = buildString {
                        append("Health: ").append(metrics.exportHealthSnapshot()).append('\n')
                        append("Incidents: ").append(metrics.incidentSummary()).append('\n')
                        append("Snapshot: ").append(metrics.snapshot()).append('\n')
                        append("MetricsJson: ").append(metrics.reportJson())
                    }
                    messageView.text = output
                }
                ACTION_RESET_METRICS -> {
                    // Reset seluruh counter metrik dan hapus export file terakhir.
                    BrizziSecurityMetrics(this).reset()
                    runCatching { File(filesDir, "security_metrics_report.txt").delete() }
                    messageView.text = "Security metrics reset"
                }
                ACTION_ENABLE_TEST_MODE -> {
                    debugPrefs.edit().putBoolean(KEY_TEST_MODE_ENABLED, true).apply()
                    messageView.text = "HCE TEST MODE: ENABLED"
                }
                ACTION_DISABLE_TEST_MODE -> {
                    debugPrefs.edit().putBoolean(KEY_TEST_MODE_ENABLED, false).apply()
                    messageView.text = "HCE TEST MODE: DISABLED"
                }
                ACTION_SET_PREFERRED_PAYMENT -> {
                    val ok = setPreferredPaymentService()
                    messageView.text = if (ok) "Preferred payment service: SET" else "Preferred payment service: FAILED"
                }
                ACTION_CLEAR_PREFERRED_PAYMENT -> {
                    val ok = clearPreferredPaymentService()
                    messageView.text = if (ok) "Preferred payment service: CLEARED" else "Preferred payment service: CLEAR FAILED"
                }
                ACTION_DUMP_APDU_LOG -> {
                    refreshApduLog()
                    messageView.text = "APDU log loaded"
                }
                ACTION_CLEAR_APDU_LOG -> {
                    clearApduLogFile()
                    messageView.text = "APDU log cleared"
                }
            }
            val isTestMode = debugPrefs.getBoolean(KEY_TEST_MODE_ENABLED, false)
            if (messageView.text.isBlank() || messageView.text == resources.getText(R.string.main_message)) {
                messageView.text = "HCE TEST MODE: ${if (isTestMode) "ENABLED" else "DISABLED"}"
            }
            if (action == ACTION_DUMP_APDU_LOG || action == ACTION_CLEAR_APDU_LOG) {
                refreshApduLog()
            }
        }
    }

    private fun scheduleApduLogRefresh() {
        stopApduLogRefresh()
        val runnable = object : Runnable {
            override fun run() {
                refreshApduLog()
                apduLogRefreshRunnable = this
                uiHandler.postDelayed(this, APDU_LOG_REFRESH_MS)
            }
        }
        apduLogRefreshRunnable = runnable
        uiHandler.post(runnable)
    }

    private fun stopApduLogRefresh() {
        apduLogRefreshRunnable?.let { uiHandler.removeCallbacks(it) }
        apduLogRefreshRunnable = null
    }

    private fun refreshApduLog() {
        val apduLogView = findViewById<TextView>(R.id.apduLogView)
        val lines = runCatching {
            val file = File(filesDir, APDU_EXCHANGE_LOG_FILE)
            if (!file.exists()) {
                return@runCatching emptyList()
            }
            file.readLines().takeLast(APDU_LOG_MAX_LINES)
        }.getOrElse {
            apduLogView.text = "Gagal membaca log APDU: ${it.message}"
            emptyList()
        }
        if (lines.isEmpty()) {
            apduLogView.text = "Belum ada log APDU."
        } else {
            apduLogView.text = lines.joinToString("\n")
        }
    }

    private fun clearApduLogFile() {
        runCatching {
            File(filesDir, APDU_EXCHANGE_LOG_FILE).delete()
            findViewById<TextView>(R.id.apduLogView).text = "Belum ada log APDU."
        }
    }

    private fun isDebuggable(): Boolean =
        (applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) != 0

    private fun setPreferredPaymentService(): Boolean {
        return runCatching {
            val adapter = NfcAdapter.getDefaultAdapter(this) ?: return false
            val ok = CardEmulation.getInstance(adapter).setPreferredService(
                this,
                ComponentName(this, com.korancrew.brizzi.hce.BrizziHostApduService::class.java)
            )
            Log.i("BrizziDebug", "setPreferredService -> $ok")
            ok
        }.getOrElse {
            Log.w("BrizziDebug", "setPreferredPaymentService failed", it)
            false
        }
    }

    private fun clearPreferredPaymentService(): Boolean {
        return runCatching {
            val adapter = NfcAdapter.getDefaultAdapter(this) ?: return false
            CardEmulation.getInstance(adapter).unsetPreferredService(this)
            Log.i("BrizziDebug", "unsetPreferredService invoked")
            true
        }.getOrElse {
            Log.w("BrizziDebug", "clearPreferredPaymentService failed", it)
            false
        }
    }

    companion object {
        /** Intent action untuk menampilkan summary metrik runtime secara debug. */
        const val ACTION_DUMP_METRICS = "com.korancrew.brizzi.ACTION_DUMP_METRICS"
        /** Intent action untuk menghapus counter metrik runtime secara debug. */
        const val ACTION_RESET_METRICS = "com.korancrew.brizzi.ACTION_RESET_METRICS"
        const val ACTION_ENABLE_TEST_MODE = "com.korancrew.brizzi.ACTION_ENABLE_TEST_MODE"
        const val ACTION_DISABLE_TEST_MODE = "com.korancrew.brizzi.ACTION_DISABLE_TEST_MODE"
        const val ACTION_SET_PREFERRED_PAYMENT = "com.korancrew.brizzi.ACTION_SET_PREFERRED_PAYMENT"
        const val ACTION_CLEAR_PREFERRED_PAYMENT = "com.korancrew.brizzi.ACTION_CLEAR_PREFERRED_PAYMENT"
        const val ACTION_DUMP_APDU_LOG = "com.korancrew.brizzi.ACTION_DUMP_APDU_LOG"
        const val ACTION_CLEAR_APDU_LOG = "com.korancrew.brizzi.ACTION_CLEAR_APDU_LOG"
        private const val PREFS_NAME = "brizzi_hce_config"
        private const val KEY_TEST_MODE_ENABLED = "hce_test_mode_enabled"
        private const val APDU_EXCHANGE_LOG_FILE = "apdu_exchange_log.txt"
        private const val APDU_LOG_MAX_LINES = 200
        private const val APDU_LOG_REFRESH_MS = 1500L
    }
}
