package com.swoosh.microblog.ui.setup

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.swoosh.microblog.data.AccountManager
import com.swoosh.microblog.data.SiteMetadataCache
import com.swoosh.microblog.data.api.ApiClient
import com.swoosh.microblog.data.api.GhostJwtGenerator
import com.swoosh.microblog.data.repository.PostRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

class SetupViewModel(application: Application) : AndroidViewModel(application) {

    private val accountManager = AccountManager(application)
    private val siteMetadataCache = SiteMetadataCache(application)

    private val _uiState = MutableStateFlow(SetupUiState(
        isAddingAccount = accountManager.hasAnyAccount
    ))
    val uiState: StateFlow<SetupUiState> = _uiState.asStateFlow()

    fun updateUrl(url: String) {
        _uiState.update { it.copy(url = url) }
    }

    fun updateApiKey(key: String) {
        _uiState.update { it.copy(apiKey = key) }
    }

    fun updateAccountName(name: String) {
        _uiState.update { it.copy(accountName = name) }
    }

    fun confirmConnection() {
        _uiState.update { it.copy(isSuccess = true) }
    }

    fun cancelConfirmation() {
        // Remove the account that was added during save()
        val accountId = _uiState.value.pendingAccountId
        if (accountId != null) {
            accountManager.removeAccount(accountId)
            siteMetadataCache.remove(accountId)
        }
        _uiState.update {
            it.copy(
                showConfirmation = false,
                siteName = null,
                siteDescription = null,
                siteIcon = null,
                siteVersion = null,
                versionWarning = false,
                pendingAccountId = null
            )
        }
    }

    fun save() {
        val state = _uiState.value
        if (state.url.isBlank() || state.apiKey.isBlank()) {
            _uiState.update { it.copy(error = "Both fields are required") }
            return
        }

        // Validate API key format
        val parts = state.apiKey.split(":")
        if (parts.size != 2 || parts[0].isBlank() || parts[1].isBlank()) {
            _uiState.update { it.copy(error = "Invalid API key format. Expected {id}:{secret}") }
            return
        }

        viewModelScope.launch {
            _uiState.update { it.copy(isTesting = true, error = null) }

            try {
                // Validate the API key can generate a JWT
                GhostJwtGenerator.generateToken(state.apiKey)

                // Add account
                val result = accountManager.addAccount(
                    name = state.accountName,
                    blogUrl = state.url,
                    apiKey = state.apiKey
                )

                result.fold(
                    onSuccess = { account ->
                        // Reset ApiClient to pick up new account
                        ApiClient.reset()

                        // Test connection
                        val repo = PostRepository(getApplication())
                        repo.fetchPosts(page = 1, limit = 1).fold(
                            onSuccess = {
                                // Fetch user profile for avatar
                                try {
                                    val service = ApiClient.getService(
                                        state.url,
                                        apiKeyProvider = { state.apiKey }
                                    )
                                    val userResponse = service.getCurrentUser()
                                    val avatarUrl = userResponse.body()?.users?.firstOrNull()?.profile_image
                                    if (avatarUrl != null) {
                                        accountManager.updateAccount(id = account.id, avatarUrl = avatarUrl)
                                    }
                                } catch (_: Exception) { /* avatar is best-effort */ }

                                // Fetch site metadata
                                var siteLoaded = false
                                try {
                                    val service = ApiClient.getService(
                                        state.url,
                                        apiKeyProvider = { state.apiKey }
                                    )
                                    val siteResponse = service.getSite()
                                    val site = siteResponse.body()
                                    if (site != null) {
                                        siteMetadataCache.save(account.id, site)
                                        val majorVersion = site.version?.split(".")?.firstOrNull()?.toIntOrNull()
                                        _uiState.update {
                                            it.copy(
                                                isTesting = false,
                                                showConfirmation = true,
                                                siteName = site.title,
                                                siteDescription = site.description,
                                                siteIcon = site.icon ?: site.logo,
                                                siteVersion = site.version,
                                                versionWarning = majorVersion != null && majorVersion < 5,
                                                pendingAccountId = account.id
                                            )
                                        }
                                        siteLoaded = true
                                    }
                                } catch (_: Exception) { /* site metadata is best-effort */ }

                                // Fallback: skip confirmation if site fetch failed
                                if (!siteLoaded) {
                                    _uiState.update { it.copy(isTesting = false, isSuccess = true) }
                                }
                            },
                            onFailure = { e ->
                                // Remove the account since connection failed
                                accountManager.removeAccount(account.id)
                                _uiState.update { it.copy(isTesting = false, error = "Connection failed: ${e.message}") }
                            }
                        )
                    },
                    onFailure = { e ->
                        _uiState.update { it.copy(isTesting = false, error = e.message) }
                    }
                )
            } catch (e: Exception) {
                _uiState.update { it.copy(isTesting = false, error = "Invalid API key: ${e.message}") }
            }
        }
    }
}

data class SetupUiState(
    val url: String = "",
    val apiKey: String = "",
    val accountName: String = "",
    val isTesting: Boolean = false,
    val isSuccess: Boolean = false,
    val isAddingAccount: Boolean = false,
    val error: String? = null,
    val siteName: String? = null,
    val siteDescription: String? = null,
    val siteIcon: String? = null,
    val siteVersion: String? = null,
    val showConfirmation: Boolean = false,
    val versionWarning: Boolean = false,
    val pendingAccountId: String? = null
)
