package ru.forbion.f7cloud.mobile.ui

import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Logout
import androidx.compose.material.icons.filled.Group
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.QrCodeScanner
import androidx.compose.material.icons.filled.TaskAlt
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
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.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.Credentials
import okhttp3.Request
import org.json.JSONObject
import ru.forbion.f7cloud.core.auth.AuthSession
import ru.forbion.f7cloud.core.designsystem.F7Colors
import ru.forbion.f7cloud.core.designsystem.F7FloatingPanel
import ru.forbion.f7cloud.core.designsystem.F7NotificationRow
import ru.forbion.f7cloud.core.designsystem.formatNotificationRelativeTime
import ru.forbion.f7cloud.core.network.F7Notification
import ru.forbion.f7cloud.core.network.NetworkFactory
import ru.forbion.f7cloud.core.network.NotificationsRepository
import ru.forbion.f7cloud.core.network.UnauthorizedException
import ru.forbion.f7cloud.core.network.applyOcsJson

private fun themeHeaderAsset(serverUrl: String, fileName: String): String =
    "${serverUrl.trimEnd('/')}/themes/forbion/images/header/$fileName"

private fun resolveNotificationIcon(serverUrl: String, icon: String): String? {
    if (icon.isBlank()) return null
    return if (icon.startsWith("http")) icon else "${serverUrl.trimEnd('/')}$icon"
}

@Composable
fun ProfileSheet(
    visible: Boolean,
    session: AuthSession,
    onDismiss: () -> Unit,
    onLogout: () -> Unit,
    onScanBrowserQr: () -> Unit = {},
) {
    val context = LocalContext.current
    val base = session.serverUrl.trimEnd('/')
    val userId = session.davUserId ?: session.username
    var displayName by remember(session.username) { mutableStateOf(userId) }
    var aboutOpen by remember { mutableStateOf(false) }

    // Отображаемое имя тянем с сервера (OCS), пока — логин
    LaunchedEffect(visible, session.username) {
        if (visible) displayName = fetchDisplayName(session).ifBlank { userId }
    }

    fun openWeb(path: String) {
        runCatching {
            context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("$base$path")))
        }
        onDismiss()
    }

    F7FloatingPanel(
        visible = visible,
        onDismiss = onDismiss,
    ) {
        // Шапка: аватар-инициал + имя/«Открыть профиль» + кнопка QR
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.spacedBy(12.dp),
        ) {
            Box(
                modifier = Modifier
                    .size(44.dp)
                    .clip(CircleShape)
                    .background(F7Colors.PrimaryLight),
                contentAlignment = Alignment.Center,
            ) {
                Text(
                    displayName.firstOrNull()?.uppercaseChar()?.toString() ?: "?",
                    style = MaterialTheme.typography.titleMedium,
                    fontWeight = FontWeight.SemiBold,
                    color = F7Colors.Primary,
                )
            }
            Column(
                modifier = Modifier
                    .weight(1f)
                    .clip(RoundedCornerShape(8.dp))
                    .clickable { openWeb("/u/$userId") }
                    .padding(vertical = 2.dp),
            ) {
                Text(
                    displayName,
                    style = MaterialTheme.typography.titleMedium,
                    fontWeight = FontWeight.SemiBold,
                    color = F7Colors.TextPrimary,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
                Text(
                    "Открыть профиль",
                    style = MaterialTheme.typography.bodySmall,
                    color = F7Colors.Primary,
                )
            }
            Box(
                modifier = Modifier
                    .size(40.dp)
                    .clip(RoundedCornerShape(10.dp))
                    .background(F7Colors.Grey2)
                    .clickable {
                        onDismiss()
                        onScanBrowserQr()
                    },
                contentAlignment = Alignment.Center,
            ) {
                Icon(
                    Icons.Filled.QrCodeScanner,
                    contentDescription = "Сканировать QR браузера",
                    tint = F7Colors.TextSecondary,
                    modifier = Modifier.size(22.dp),
                )
            }
        }
        Spacer(Modifier.height(10.dp))
        HorizontalDivider(color = F7Colors.Border.copy(alpha = 0.5f))
        Spacer(Modifier.height(4.dp))
        ProfileMenuRow(Icons.Filled.TaskAlt, "Установить статус") { openWeb("/settings/user") }
        ProfileMenuRow(Icons.Filled.Person, "Личные настройки") { openWeb("/settings/user") }
        ProfileMenuRow(Icons.Filled.Group, "Учётные записи") { openWeb("/settings/user/security") }
        ProfileMenuRow(Icons.Outlined.Info, "О программе и что нового") { aboutOpen = true }
        ProfileMenuRow(
            icon = Icons.AutoMirrored.Filled.Logout,
            label = "Выйти",
            tint = F7Colors.Error,
        ) {
            onDismiss()
            onLogout()
        }
    }

    if (aboutOpen) {
        F7AboutDialog(onDismiss = { aboutOpen = false })
    }
}

@Composable
private fun ProfileMenuRow(
    icon: ImageVector,
    label: String,
    tint: Color = F7Colors.TextPrimary,
    onClick: () -> Unit,
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .clip(RoundedCornerShape(10.dp))
            .clickable(onClick = onClick)
            .padding(vertical = 12.dp, horizontal = 4.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(14.dp),
    ) {
        Icon(icon, contentDescription = null, tint = tint, modifier = Modifier.size(22.dp))
        Text(label, style = MaterialTheme.typography.bodyLarge, color = tint)
    }
}

@Composable
private fun F7AboutDialog(onDismiss: () -> Unit) {
    val context = LocalContext.current
    val version = remember {
        runCatching {
            context.packageManager.getPackageInfo(context.packageName, 0).versionName
        }.getOrNull() ?: "—"
    }
    AlertDialog(
        onDismissRequest = onDismiss,
        confirmButton = {
            TextButton(onClick = onDismiss) { Text("Закрыть") }
        },
        title = { Text("F7cloud Mobile") },
        text = {
            Column {
                Text("Версия $version", style = MaterialTheme.typography.bodyMedium, color = F7Colors.TextPrimary)
                Spacer(Modifier.height(8.dp))
                Text(
                    "Нативный клиент F7cloud: почта, файлы, календарь, контакты, задачи, конференции, поддержка.",
                    style = MaterialTheme.typography.bodySmall,
                    color = F7Colors.TextSecondary,
                )
            }
        },
    )
}

/** Отображаемое имя пользователя из OCS (fallback — пусто). */
private suspend fun fetchDisplayName(session: AuthSession): String = withContext(Dispatchers.IO) {
    runCatching {
        val client = NetworkFactory.newAuthedClient(
            session.username,
            session.appPassword,
            session.trustAllCerts,
        )
        val url = "${session.serverUrl.trimEnd('/')}/ocs/v2.php/cloud/user?format=json"
        val request = Request.Builder().url(url).applyOcsJson().get().build()
        client.newCall(request).execute().use { response ->
            val body = response.body?.string().orEmpty()
            JSONObject(body)
                .optJSONObject("ocs")
                ?.optJSONObject("data")
                ?.optString("displayname")
                .orEmpty()
        }
    }.getOrDefault("")
}

@Composable
fun NotificationsSheet(
    visible: Boolean,
    session: AuthSession,
    refreshRequest: Int = 0,
    onDismiss: () -> Unit,
    onNotificationClick: (F7Notification) -> Unit,
    onUnauthorized: () -> Unit,
) {
    val scope = rememberCoroutineScope()
    val repository = remember { NotificationsRepository() }
    var loading by remember { mutableStateOf(true) }
    var error by remember { mutableStateOf<String?>(null) }
    var items by remember { mutableStateOf<List<F7Notification>>(emptyList()) }
    val authHeader = remember(session.username, session.appPassword) {
        Credentials.basic(session.username, session.appPassword)
    }
    val closeIconUrl = remember(session.serverUrl) {
        themeHeaderAsset(session.serverUrl, "close-modal.svg")
    }

    fun loadNotifications() {
        loading = true
        error = null
        scope.launch {
            runCatching {
                withContext(Dispatchers.IO) {
                    repository.load(
                        serverUrl = session.serverUrl,
                        username = session.username,
                        appPassword = session.appPassword,
                        trustAllCerts = session.trustAllCerts,
                    )
                }
            }
                .onSuccess { list ->
                    items = list
                    loading = false
                }
                .onFailure { t ->
                    loading = false
                    if (t is UnauthorizedException) {
                        onDismiss()
                        onUnauthorized()
                    } else {
                        error = t.message ?: "Не удалось загрузить уведомления"
                    }
                }
        }
    }

    LaunchedEffect(visible, refreshRequest, session.serverUrl, session.username) {
        if (!visible && refreshRequest == 0) return@LaunchedEffect
        loadNotifications()
    }

    fun dismissNotification(notification: F7Notification) {
        items = items.filter { it.id != notification.id }
        scope.launch {
            runCatching {
                withContext(Dispatchers.IO) {
                    repository.dismiss(
                        serverUrl = session.serverUrl,
                        username = session.username,
                        appPassword = session.appPassword,
                        notificationId = notification.id,
                        trustAllCerts = session.trustAllCerts,
                    )
                }
            }.onFailure { t ->
                if (t is UnauthorizedException) {
                    onDismiss()
                    onUnauthorized()
                } else {
                    loadNotifications()
                }
            }
        }
    }

    F7FloatingPanel(
        visible = visible,
        onDismiss = onDismiss,
        fullHeight = true,
        contentPadding = PaddingValues(0.dp),
    ) {
        when {
            loading -> {
                Column(
                    modifier = Modifier
                        .fillMaxWidth()
                        .fillMaxHeight()
                        .padding(32.dp),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.Center,
                ) {
                    CircularProgressIndicator(color = F7Colors.Primary)
                }
            }
            !error.isNullOrBlank() -> {
                Text(
                    error ?: "",
                    color = F7Colors.Error,
                    style = MaterialTheme.typography.bodyLarge.copy(
                        fontSize = MaterialTheme.typography.bodyLarge.fontSize * 2,
                        lineHeight = MaterialTheme.typography.bodyLarge.lineHeight * 2,
                    ),
                    modifier = Modifier.padding(16.dp),
                )
            }
            items.isEmpty() -> {
                Column(
                    modifier = Modifier
                        .fillMaxWidth()
                        .fillMaxHeight()
                        .padding(horizontal = 16.dp, vertical = 24.dp),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.Center,
                ) {
                    AsyncImage(
                        model = themeHeaderAsset(session.serverUrl, "nof-not-icon.svg"),
                        contentDescription = null,
                        modifier = Modifier.size(120.dp),
                    )
                    Text(
                        "Нет уведомлений",
                        style = MaterialTheme.typography.titleMedium.copy(
                            fontSize = MaterialTheme.typography.titleMedium.fontSize * 2,
                            lineHeight = MaterialTheme.typography.titleMedium.lineHeight * 2,
                        ),
                        fontWeight = androidx.compose.ui.text.font.FontWeight.Medium,
                        color = F7Colors.TextPrimary,
                    )
                }
            }
            else -> Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .fillMaxHeight()
                    .verticalScroll(rememberScrollState()),
            ) {
                items.forEachIndexed { index, item ->
                    F7NotificationRow(
                        subject = item.subject,
                        message = item.message,
                        relativeTime = formatNotificationRelativeTime(item.datetime),
                        iconUrl = resolveNotificationIcon(session.serverUrl, item.icon),
                        closeIconUrl = closeIconUrl,
                        authHeader = authHeader,
                        onClick = {
                            onDismiss()
                            onNotificationClick(item)
                        },
                        onDismiss = { dismissNotification(item) },
                        showDivider = index < items.lastIndex,
                    )
                }
            }
        }
    }
}
