package com.example.ops_android.ui.settings

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.example.ops_android.data.local.SessionManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLException

data class SettingsUiState(
    val apiBaseUrl: String = "",
    val isTesting: Boolean = false,
    val testResult: String? = null,
    val testSuccess: Boolean = false,
    val message: String? = null,
    val blackMarkEnabled: Boolean = true,
    val unwindMm: String = "40",
    val labelWidthMm: String = "53",
    val labelHeightMm: String = "40",
    val printRetractMm: String = "10"
)

class SettingsViewModel(
    private val sessionManager: SessionManager
) : ViewModel() {

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

    private val client = OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .readTimeout(10, TimeUnit.SECONDS)
        .followRedirects(true)
        .build()

    init {
        loadCurrentUrl()
        loadPrinterSettings()
    }

    private fun loadCurrentUrl() {
        viewModelScope.launch {
            val url = sessionManager.getApiBaseUrl()
            _uiState.value = _uiState.value.copy(apiBaseUrl = url)
        }
    }

    private fun loadPrinterSettings() {
        _uiState.value = _uiState.value.copy(
            blackMarkEnabled = sessionManager.cachedBlackMarkEnabled,
            unwindMm = sessionManager.cachedUnwindMm.toString(),
            labelWidthMm = sessionManager.cachedLabelWidthMm.toString(),
            labelHeightMm = sessionManager.cachedLabelHeightMm.toString(),
            printRetractMm = sessionManager.cachedPrintRetractMm.toString()
        )
    }

    fun onUrlChange(value: String) {
        _uiState.value = _uiState.value.copy(apiBaseUrl = value, message = null)
    }

    fun onBlackMarkChange(enabled: Boolean) {
        _uiState.value = _uiState.value.copy(blackMarkEnabled = enabled)
        viewModelScope.launch { sessionManager.setBlackMarkEnabled(enabled) }
    }

    fun onUnwindMmChange(value: String) {
        if (value.isEmpty() || value.all { it.isDigit() } && value.toIntOrNull()?.let { it in 1..200 } == true) {
            _uiState.value = _uiState.value.copy(unwindMm = value)
        }
    }

    fun saveUnwindMm() {
        val mm = _uiState.value.unwindMm.toIntOrNull() ?: 40
        viewModelScope.launch {
            sessionManager.setUnwindMm(mm)
            _uiState.value = _uiState.value.copy(message = "走纸长度已保存")
        }
    }

    fun onLabelWidthChange(value: String) {
        if (value.isEmpty() || value.all { it.isDigit() } && value.toIntOrNull()?.let { it in 10..200 } == true) {
            _uiState.value = _uiState.value.copy(labelWidthMm = value)
        }
    }

    fun onLabelHeightChange(value: String) {
        if (value.isEmpty() || value.all { it.isDigit() } && value.toIntOrNull()?.let { it in 10..200 } == true) {
            _uiState.value = _uiState.value.copy(labelHeightMm = value)
        }
    }

    fun saveLabelSize() {
        val width = _uiState.value.labelWidthMm.toIntOrNull() ?: 53
        val height = _uiState.value.labelHeightMm.toIntOrNull() ?: 40
        viewModelScope.launch {
            sessionManager.setLabelWidthMm(width)
            sessionManager.setLabelHeightMm(height)
            _uiState.value = _uiState.value.copy(message = "标签尺寸已保存")
        }
    }

    fun onPrintRetractMmChange(value: String) {
        if (value.isEmpty() || value.all { it.isDigit() } && value.toIntOrNull()?.let { it in 0..50 } == true) {
            _uiState.value = _uiState.value.copy(printRetractMm = value)
        }
    }

    fun savePrintRetractMm() {
        val mm = _uiState.value.printRetractMm.toIntOrNull() ?: 10
        viewModelScope.launch {
            sessionManager.setPrintRetractMm(mm)
            _uiState.value = _uiState.value.copy(message = "回退长度已保存")
        }
    }

    fun saveUrl() {
        viewModelScope.launch {
            val url = _uiState.value.apiBaseUrl.trim()
            if (url.isBlank()) {
                _uiState.value = _uiState.value.copy(message = "请输入有效的API地址")
                return@launch
            }
            sessionManager.setApiBaseUrl(url)
            _uiState.value = _uiState.value.copy(message = "API地址已保存")
        }
    }

    fun testConnection() {
        viewModelScope.launch {
            val url = _uiState.value.apiBaseUrl.trim()
            if (url.isBlank()) {
                _uiState.value = _uiState.value.copy(message = "请先输入API地址")
                return@launch
            }

            _uiState.value = _uiState.value.copy(isTesting = true, testResult = null, message = null)

            try {
                val code = withContext(Dispatchers.IO) {
                    val request = Request.Builder().url(url).header("Accept", "application/json").build()
                    val response = client.newCall(request).execute()
                    response.use { it.code }
                }
                _uiState.value = _uiState.value.copy(
                    isTesting = false,
                    testResult = if (code in 200..299) "连接成功 ($code)" else "服务器响应异常: HTTP $code",
                    testSuccess = code in 200..299
                )
            } catch (e: UnknownHostException) {
                _uiState.value = _uiState.value.copy(
                    isTesting = false,
                    testResult = "连接失败: 无法解析服务器地址",
                    testSuccess = false
                )
            } catch (e: SocketTimeoutException) {
                _uiState.value = _uiState.value.copy(
                    isTesting = false,
                    testResult = "连接超时，请检查网络和服务器地址",
                    testSuccess = false
                )
            } catch (e: ConnectException) {
                _uiState.value = _uiState.value.copy(
                    isTesting = false,
                    testResult = "连接被拒绝: ${e.message ?: "服务器不可达"}",
                    testSuccess = false
                )
            } catch (e: SSLException) {
                _uiState.value = _uiState.value.copy(
                    isTesting = false,
                    testResult = "SSL证书错误，HTTP地址请使用http://",
                    testSuccess = false
                )
            } catch (e: Exception) {
                _uiState.value = _uiState.value.copy(
                    isTesting = false,
                    testResult = "连接失败: ${e.javaClass.simpleName} - ${e.message ?: "未知错误"}",
                    testSuccess = false
                )
            }
        }
    }

    class Factory(
        private val sessionManager: SessionManager
    ) : ViewModelProvider.Factory {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return SettingsViewModel(sessionManager) as T
        }
    }
}
