package ru.forbion.f7cloud.mobile.navigation

import ru.forbion.f7cloud.feature.files.OfficeFileLinks
import ru.forbion.f7cloud.feature.talk.TalkDeepLink
import ru.forbion.f7cloud.mobile.ui.AppTab

/**
 * Maps F7cloud web URLs (dashboard widgets, push, notifications) to in-app navigation.
 */
object AppLinkResolver {
    fun resolve(url: String?, serverUrl: String = ""): AppLinkTarget? {
        if (url.isNullOrBlank()) return null
        val lower = url.lowercase()

        TalkDeepLink.extractRoomToken(url)?.let { token ->
            return AppLinkTarget(
                tab = AppTab.Talk,
                talkRoomToken = token,
                talkMessageId = TalkDeepLink.extractMessageId(url),
            )
        }

        parseMail(url)?.let { return it }

        parseCalendar(url)?.let { return it }

        parseDeck(url)?.let { return it }

        parseTasks(url)?.let { return it }

        OfficeFileLinks.parseFileId(url, serverUrl)?.let { fileId ->
            return AppLinkTarget(tab = AppTab.Files, fileId = fileId)
        }

        if (lower.contains("/apps/files") || lower.contains("/remote.php/dav/files") ||
            lower.contains("fileid=") || lower.contains("/f/")
        ) {
            val fileId = OfficeFileLinks.parseFileId(url, serverUrl)
                ?: Regex("""fileid=(\d+)""", RegexOption.IGNORE_CASE).find(url)
                    ?.groupValues?.get(1)?.toLongOrNull()
            return AppLinkTarget(tab = AppTab.Files, fileId = fileId)
        }

        return when {
            lower.contains("/apps/f7mail") || lower.contains("/apps/mail") -> AppLinkTarget(tab = AppTab.Mail)
            lower.contains("/apps/calendar") -> AppLinkTarget(tab = AppTab.Calendar)
            lower.contains("/apps/tasks") -> parseTasks(url) ?: AppLinkTarget(tab = AppTab.Tasks)
            lower.contains("/apps/deck") -> AppLinkTarget(tab = AppTab.Deck)
            lower.contains("/apps/spreed") -> AppLinkTarget(tab = AppTab.Talk)
            lower.contains("/apps/f7support") -> {
                AppLinkTarget(tab = AppTab.Support, supportTicket = extractSupportTicket(url))
            }
            lower.contains("/apps/dashboard") -> AppLinkTarget(tab = AppTab.Files)
            lower.contains("/apps/contacts") -> AppLinkTarget(tab = AppTab.Contacts)
            else -> null
        }
    }

    private fun parseMail(url: String): AppLinkTarget? {
        if (!url.contains("/apps/f7mail", ignoreCase = true) &&
            !url.contains("/apps/mail", ignoreCase = true)
        ) {
            return null
        }
        val thread = Regex("""/thread/(\d+)""", RegexOption.IGNORE_CASE).find(url)
            ?.groupValues?.get(1)?.toIntOrNull()
        val mailbox = Regex("""/box/(\d+)""", RegexOption.IGNORE_CASE).find(url)
            ?.groupValues?.get(1)?.toIntOrNull()
        return AppLinkTarget(
            tab = AppTab.Mail,
            mailMessageId = thread,
            mailMailboxId = mailbox,
        )
    }

    private fun parseCalendar(url: String): AppLinkTarget? {
        if (!url.contains("/apps/calendar", ignoreCase = true)) return null
        val uid = Regex("""/edit/([^/?#]+)""", RegexOption.IGNORE_CASE).find(url)
            ?.groupValues?.get(1)
            ?.takeIf { it.isNotBlank() }
        return AppLinkTarget(tab = AppTab.Calendar, calendarEventUid = uid)
    }

    private fun parseDeck(url: String): AppLinkTarget? {
        if (!url.contains("/apps/deck", ignoreCase = true)) return null
        val cardId = Regex("""/card/(\d+)""", RegexOption.IGNORE_CASE).find(url)
            ?.groupValues?.get(1)?.toIntOrNull()
        return AppLinkTarget(tab = AppTab.Deck, deckCardId = cardId)
    }

    private fun parseTasks(url: String): AppLinkTarget? {
        if (!url.contains("/apps/tasks", ignoreCase = true)) return null
        val slug = Regex("""/calendars/([^/?#]+)""", RegexOption.IGNORE_CASE).find(url)
            ?.groupValues?.get(1)
            ?.takeIf { it.isNotBlank() }
        return AppLinkTarget(tab = AppTab.Tasks, tasksListSlug = slug)
    }

    private fun extractSupportTicket(url: String): String? {
        val marker = "ticket="
        val idx = url.indexOf(marker, ignoreCase = true)
        if (idx < 0) return null
        return url.substring(idx + marker.length).takeWhile { it.isDigit() }.ifBlank { null }
    }
}

data class AppLinkTarget(
    val tab: AppTab,
    val talkRoomToken: String? = null,
    val talkMessageId: Long? = null,
    val mailMessageId: Int? = null,
    val mailMailboxId: Int? = null,
    val calendarEventUid: String? = null,
    val deckCardId: Int? = null,
    val fileId: Long? = null,
    val supportTicket: String? = null,
    val tasksListSlug: String? = null,
)
