package cy.hexor.furumi.domain.model

import java.net.URI
import java.util.Locale

data class ServerConfig(
    val baseUrl: String,
    val login: String = ""
) {
    val url: String
        get() = baseUrl

    companion object {
        fun credentials(serverUrl: String, login: String): Result<ServerConfig> {
            val normalizedBaseUrl = normalizeBaseUrl(serverUrl).getOrElse { return Result.failure(it) }
            val trimmedLogin = login.trim()

            if (trimmedLogin.isBlank()) {
                return Result.failure(IllegalArgumentException("Username is required"))
            }

            return Result.success(ServerConfig(normalizedBaseUrl, trimmedLogin))
        }

        fun sso(serverUrl: String): Result<ServerConfig> {
            val normalizedBaseUrl = normalizeBaseUrl(serverUrl).getOrElse { return Result.failure(it) }
            return Result.success(ServerConfig(normalizedBaseUrl))
        }

        fun normalizeBaseUrl(rawUrl: String): Result<String> {
            val trimmedUrl = rawUrl.trim().trimEnd('/')

            if (trimmedUrl.isBlank()) {
                return Result.failure(IllegalArgumentException("Server URL is required"))
            }

            val candidate = if (trimmedUrl.hasScheme()) trimmedUrl else "https://$trimmedUrl"
            val uri = runCatching { URI(candidate) }.getOrElse {
                return Result.failure(IllegalArgumentException("Enter a valid server URL"))
            }

            val scheme = uri.scheme?.lowercase(Locale.US)
            val rawAuthority = uri.rawAuthority
            val host = uri.host
            if (scheme != "http" && scheme != "https") {
                return Result.failure(IllegalArgumentException("Server URL must start with http:// or https://"))
            }

            if (rawAuthority.isNullOrBlank() || host.isNullOrBlank()) {
                return Result.failure(IllegalArgumentException("Enter a valid server URL"))
            }

            if (uri.userInfo != null) {
                return Result.failure(IllegalArgumentException("Server URL must not contain user info"))
            }

            if (uri.rawQuery != null || uri.rawFragment != null) {
                return Result.failure(IllegalArgumentException("Server URL must not contain query or fragment"))
            }

            val normalizedPath = uri.rawPath
                ?.takeUnless { it == "/" }
                ?.trimEnd('/')
                .orEmpty()

            val authority = rawAuthority.lowercase(Locale.US)
            return Result.success("$scheme://$authority$normalizedPath")
        }

        private fun String.hasScheme(): Boolean {
            return startsWith("http://", ignoreCase = true) || startsWith("https://", ignoreCase = true)
        }
    }
}
