package com.devlab.app.ui.servers

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.devlab.app.data.model.*
import com.devlab.app.data.repository.ServerRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

data class ServerDetailUiState(
    val isLoading: Boolean = true,
    val server: Server? = null,
    val metrics: LatestMetrics? = null,
    val metricsHistory: List<MetricPoint> = emptyList(),
    val error: String? = null,
    val commandText: String = "",
    val commandOutput: String? = null,
    val commandError: String? = null,
    val isExecuting: Boolean = false,
    val selectedTab: Int = 0,
    val services: List<ServiceInfo> = emptyList(),
    val isLoadingServices: Boolean = false,
    val servicesError: String? = null,
    val serviceActionRunning: String? = null,
    val serviceActionResult: String? = null,
    val isTestingConnection: Boolean = false,
    val connectionResult: Boolean? = null,
    val actionMessage: String? = null,
    val isActionRunning: Boolean = false
)

class ServerDetailViewModel : ViewModel() {

    private val repository = ServerRepository()
    private var serverId: Int = 0

    private val _uiState = MutableStateFlow(ServerDetailUiState())
    val uiState: StateFlow<ServerDetailUiState> = _uiState.asStateFlow()

    fun load(id: Int) {
        serverId = id
        loadDetail()
    }

    private fun loadDetail() {
        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isLoading = true, error = null)
            try {
                val response = repository.getServerDetail(serverId)
                if (response.success) {
                    _uiState.value = _uiState.value.copy(
                        isLoading = false,
                        server = response.data?.server,
                        metrics = response.data?.metrics,
                        error = null
                    )
                } else {
                    _uiState.value = _uiState.value.copy(
                        isLoading = false,
                        error = response.error ?: "Failed to load server details"
                    )
                }
            } catch (e: Exception) {
                _uiState.value = _uiState.value.copy(
                    isLoading = false,
                    error = e.message ?: "Network error"
                )
            }
        }
    }

    fun loadMetrics() {
        viewModelScope.launch {
            try {
                val response = repository.getServerMetrics(serverId)
                if (response.success) {
                    _uiState.value = _uiState.value.copy(
                        metricsHistory = response.data ?: emptyList()
                    )
                }
            } catch (_: Exception) { }
        }
    }

    fun loadServices() {
        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isLoadingServices = true, servicesError = null)
            try {
                val response = repository.getServerServices(serverId)
                if (response.success) {
                    _uiState.value = _uiState.value.copy(
                        isLoadingServices = false,
                        services = response.data ?: emptyList()
                    )
                } else {
                    _uiState.value = _uiState.value.copy(
                        isLoadingServices = false,
                        servicesError = response.error ?: "Failed to load services"
                    )
                }
            } catch (e: Exception) {
                _uiState.value = _uiState.value.copy(
                    isLoadingServices = false,
                    servicesError = e.message ?: "Network error"
                )
            }
        }
    }

    fun testConnection() {
        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isTestingConnection = true, connectionResult = null, actionMessage = null)
            try {
                val response = repository.testConnection(serverId)
                if (response.success && response.data != null) {
                    _uiState.value = _uiState.value.copy(
                        isTestingConnection = false,
                        connectionResult = response.data.connected,
                        actionMessage = if (response.data.connected) "Connection successful" else "Connection failed: ${response.data.error ?: "Unknown error"}"
                    )
                } else {
                    _uiState.value = _uiState.value.copy(
                        isTestingConnection = false,
                        connectionResult = false,
                        actionMessage = response.error ?: "Test failed"
                    )
                }
            } catch (e: Exception) {
                _uiState.value = _uiState.value.copy(
                    isTestingConnection = false,
                    connectionResult = false,
                    actionMessage = e.message ?: "Network error"
                )
            }
        }
    }

    fun reboot() {
        runAction("Rebooting server...") {
            repository.rebootServer(serverId)
        }
    }

    fun shutdown() {
        runAction("Shutting down server...") {
            repository.shutdownServer(serverId)
        }
    }

    private fun runAction(loadingMsg: String, action: suspend () -> ApiResponse<Map<String, String>>) {
        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isActionRunning = true, actionMessage = loadingMsg)
            try {
                val response = action()
                if (response.success) {
                    _uiState.value = _uiState.value.copy(
                        isActionRunning = false,
                        actionMessage = "Command executed successfully"
                    )
                } else {
                    _uiState.value = _uiState.value.copy(
                        isActionRunning = false,
                        actionMessage = response.error ?: "Action failed"
                    )
                }
            } catch (e: Exception) {
                _uiState.value = _uiState.value.copy(
                    isActionRunning = false,
                    actionMessage = e.message ?: "Network error"
                )
            }
        }
    }

    fun updateCommand(text: String) {
        _uiState.value = _uiState.value.copy(commandText = text, commandOutput = null, commandError = null)
    }

    fun executeCommand() {
        val command = _uiState.value.commandText.trim()
        if (command.isBlank()) return

        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isExecuting = true, commandOutput = null, commandError = null)
            try {
                val response = repository.executeCommand(serverId, command)
                if (response.success) {
                    _uiState.value = _uiState.value.copy(
                        isExecuting = false,
                        commandOutput = response.data?.output ?: "(no output)"
                    )
                } else {
                    _uiState.value = _uiState.value.copy(
                        isExecuting = false,
                        commandError = response.error ?: "Command failed"
                    )
                }
            } catch (e: Exception) {
                _uiState.value = _uiState.value.copy(
                    isExecuting = false,
                    commandError = e.message ?: "Failed to execute command"
                )
            }
        }
    }

    fun selectTab(tab: Int) {
        _uiState.value = _uiState.value.copy(selectedTab = tab)
        when (tab) {
            1 -> if (_uiState.value.metricsHistory.isEmpty()) loadMetrics()
            3 -> if (_uiState.value.services.isEmpty() && !_uiState.value.isLoadingServices) loadServices()
        }
    }

    fun serviceAction(service: String, action: String) {
        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(
                serviceActionRunning = "$action:$service",
                serviceActionResult = null
            )
            try {
                val response = repository.serviceAction(serverId, service, action)
                if (response.success) {
                    _uiState.value = _uiState.value.copy(
                        serviceActionRunning = null,
                        serviceActionResult = "Service '${service}' ${action}ed."
                    )
                    loadServices()
                } else {
                    _uiState.value = _uiState.value.copy(
                        serviceActionRunning = null,
                        serviceActionResult = response.error ?: "Action failed"
                    )
                }
            } catch (e: Exception) {
                _uiState.value = _uiState.value.copy(
                    serviceActionRunning = null,
                    serviceActionResult = e.message ?: "Network error"
                )
            }
        }
    }

    fun clearActionMessage() {
        _uiState.value = _uiState.value.copy(
            actionMessage = null,
            connectionResult = null,
            serviceActionResult = null
        )
    }
}
