package me.rerere.rikkahub.ui.activity

import android.content.Intent
import android.content.pm.ApplicationInfo
import android.graphics.drawable.Drawable
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.tween
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.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.graphics.drawable.toBitmap
import kotlinx.coroutines.launch
import me.rerere.rikkahub.data.service.AppLockGuard
import me.rerere.rikkahub.data.service.AppLockStore

class AppLockUnlockActivity : ComponentActivity() {

    companion object {
        const val EXTRA_TARGET_PACKAGE = "target_package"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val targetPackage = intent.getStringExtra(EXTRA_TARGET_PACKAGE)
        if (targetPackage.isNullOrBlank()) {
            finish()
            return
        }
        setContent {
            me.rerere.rikkahub.ui.theme.RikkahubTheme {
                AppLockUnlockScreen(
                    targetPackage = targetPackage,
                    onUnlocked = {
                        AppLockGuard.grantGraceUnlock(targetPackage)
                        val launchIntent = packageManager.getLaunchIntentForPackage(targetPackage)
                        if (launchIntent != null) {
                            launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                            startActivity(launchIntent)
                        }
                        finish()
                    },
                    onCancel = { AppLockGuard.goHome(); finish() }
                )
            }
        }
    }

    override fun onBackPressed() {
        AppLockGuard.goHome()
        finish()
    }
}

private fun loadAppLabel(context: android.content.Context, packageName: String): String =
    try {
        val info: ApplicationInfo = context.packageManager.getApplicationInfo(packageName, 0)
        context.packageManager.getApplicationLabel(info).toString()
    } catch (_: Exception) {
        packageName
    }

private fun loadAppIcon(context: android.content.Context, packageName: String): Drawable? =
    try {
        context.packageManager.getApplicationIcon(packageName)
    } catch (_: Exception) {
        null
    }

@Composable
private fun AppLockUnlockScreen(
    targetPackage: String,
    onUnlocked: () -> Unit,
    onCancel: () -> Unit,
) {
    val context = LocalContext.current
    val scope = rememberCoroutineScope()
    var pin by remember { mutableStateOf("") }
    var errorMessage by remember { mutableStateOf<String?>(null) }
    val shakeOffset = remember { Animatable(0f) }

    val appLabel = remember(targetPackage) { loadAppLabel(context, targetPackage) }
    val appIcon = remember(targetPackage) { loadAppIcon(context, targetPackage) }
    val hasPin = remember { AppLockStore.hasPin(context) }
    val pinLength = remember { AppLockStore.getPinLength(context) }

    fun submit(candidate: String) {
        if (!hasPin) {
            errorMessage = "还没有设置解锁密码,请先让橘瓣设置密码"
            return
        }
        if (AppLockStore.verifyPin(context, candidate)) {
            onUnlocked()
        } else {
            errorMessage = "密码错误"
            pin = ""
            scope.launch {
                shakeOffset.snapTo(0f)
                shakeOffset.animateTo(20f, tween(50))
                shakeOffset.animateTo(-20f, tween(50))
                shakeOffset.animateTo(20f, tween(50))
                shakeOffset.animateTo(0f, tween(50))
            }
        }
    }

    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colorScheme.background
    ) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(24.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            Text(text = "\uD83D\uDD12", fontSize = 40.sp)
            Spacer(modifier = Modifier.height(16.dp))
            if (appIcon != null) {
                androidx.compose.foundation.Image(
                    bitmap = appIcon.toBitmap().asImageBitmap(),
                    contentDescription = appLabel,
                    modifier = Modifier.size(64.dp)
                )
            } else {
                Text(text = "\uD83D\uDCF1", fontSize = 40.sp)
            }
            Spacer(modifier = Modifier.height(8.dp))
            Text(text = appLabel, style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
            Text(
                text = "已被锁定,输入密码解锁",
                style = MaterialTheme.typography.bodyMedium,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
            Spacer(modifier = Modifier.height(24.dp))

            Row(
                modifier = Modifier.offset(x = shakeOffset.value.dp),
                horizontalArrangement = Arrangement.spacedBy(12.dp)
            ) {
                repeat(pinLength) { index ->
                    Box(
                        modifier = Modifier
                            .size(14.dp)
                            .background(
                                color = if (index < pin.length) MaterialTheme.colorScheme.primary
                                        else MaterialTheme.colorScheme.surfaceVariant,
                                shape = CircleShape
                            )
                    )
                }
            }

            errorMessage?.let {
                Spacer(modifier = Modifier.height(8.dp))
                Text(text = it, color = MaterialTheme.colorScheme.error, style = MaterialTheme.typography.bodySmall)
            }

            Spacer(modifier = Modifier.height(32.dp))

            val rows = listOf(
                listOf("1", "2", "3"),
                listOf("4", "5", "6"),
                listOf("7", "8", "9"),
                listOf("", "0", "back")
            )
            rows.forEach { row ->
                Row(horizontalArrangement = Arrangement.spacedBy(24.dp)) {
                    row.forEach { key ->
                        Box(modifier = Modifier.size(64.dp), contentAlignment = Alignment.Center) {
                            when {
                                key == "back" -> {
                                    IconButton(onClick = {
                                        if (pin.isNotEmpty()) pin = pin.dropLast(1)
                                        errorMessage = null
                                    }) {
                                        Text(text = "\u232B", fontSize = 22.sp)
                                    }
                                }
                                key.isNotEmpty() -> {
                                    IconButton(onClick = {
                                        if (pin.length < pinLength) {
                                            pin += key
                                            errorMessage = null
                                            if (pin.length == pinLength) submit(pin)
                                        }
                                    }) {
                                        Text(text = key, fontSize = 24.sp)
                                    }
                                }
                            }
                        }
                    }
                }
            }

            Spacer(modifier = Modifier.height(24.dp))
            IconButton(onClick = onCancel) {
                Text(text = "\u2715", fontSize = 20.sp)
            }
        }
    }
}