package com.tt.honeyDue.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.tt.honeyDue.models.*
import com.tt.honeyDue.network.ApiResult
import com.tt.honeyDue.network.APILayer
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

enum class PasswordResetStep {
    REQUEST_CODE,
    VERIFY_CODE,
    RESET_PASSWORD,
    LOGGING_IN,
    SUCCESS
}

class PasswordResetViewModel(
    private val deepLinkToken: String? = null
) : ViewModel() {

    private val _forgotPasswordState = MutableStateFlow<ApiResult<ForgotPasswordResponse>>(ApiResult.Idle)
    val forgotPasswordState: StateFlow<ApiResult<ForgotPasswordResponse>> = _forgotPasswordState

    private val _verifyCodeState = MutableStateFlow<ApiResult<VerifyResetCodeResponse>>(ApiResult.Idle)
    val verifyCodeState: StateFlow<ApiResult<VerifyResetCodeResponse>> = _verifyCodeState

    private val _resetPasswordState = MutableStateFlow<ApiResult<ResetPasswordResponse>>(ApiResult.Idle)
    val resetPasswordState: StateFlow<ApiResult<ResetPasswordResponse>> = _resetPasswordState

    private val _loginState = MutableStateFlow<ApiResult<AuthResponse>>(ApiResult.Idle)
    val loginState: StateFlow<ApiResult<AuthResponse>> = _loginState

    // Callback for successful login after password reset
    var onLoginSuccess: ((Boolean) -> Unit)? = null

    private val _currentStep = MutableStateFlow(
        if (deepLinkToken != null) PasswordResetStep.RESET_PASSWORD else PasswordResetStep.REQUEST_CODE
    )
    val currentStep: StateFlow<PasswordResetStep> = _currentStep

    private val _resetToken = MutableStateFlow(deepLinkToken)
    val resetToken: StateFlow<String?> = _resetToken

    private val _email = MutableStateFlow("")
    val email: StateFlow<String> = _email

    fun setEmail(email: String) {
        _email.value = email
    }

    fun requestPasswordReset(email: String) {
        viewModelScope.launch {
            _forgotPasswordState.value = ApiResult.Loading
            val result = APILayer.forgotPassword(ForgotPasswordRequest(email))
            _forgotPasswordState.value = when (result) {
                is ApiResult.Success -> {
                    _email.value = email
                    // Move to next step after short delay
                    kotlinx.coroutines.delay(1500)
                    _currentStep.value = PasswordResetStep.VERIFY_CODE
                    ApiResult.Success(result.data)
                }
                is ApiResult.Error -> result
                else -> ApiResult.Error("Unknown error")
            }
        }
    }

    fun verifyResetCode(email: String, code: String) {
        viewModelScope.launch {
            _verifyCodeState.value = ApiResult.Loading
            val result = APILayer.verifyResetCode(VerifyResetCodeRequest(email, code))
            _verifyCodeState.value = when (result) {
                is ApiResult.Success -> {
                    _resetToken.value = result.data.resetToken
                    // Move to next step after short delay
                    kotlinx.coroutines.delay(1500)
                    _currentStep.value = PasswordResetStep.RESET_PASSWORD
                    ApiResult.Success(result.data)
                }
                is ApiResult.Error -> result
                else -> ApiResult.Error("Unknown error")
            }
        }
    }

    private var _newPassword: String = ""

    fun resetPassword(newPassword: String, confirmPassword: String) {
        val token = _resetToken.value
        if (token == null) {
            _resetPasswordState.value = ApiResult.Error("Invalid reset token. Please start over.")
            return
        }

        _newPassword = newPassword

        viewModelScope.launch {
            _resetPasswordState.value = ApiResult.Loading
            // Note: confirmPassword is for UI validation only, not sent to API
            val result = APILayer.resetPassword(
                ResetPasswordRequest(
                    resetToken = token,
                    newPassword = newPassword
                )
            )
            _resetPasswordState.value = when (result) {
                is ApiResult.Success -> {
                    // Password reset successful - now auto-login
                    _currentStep.value = PasswordResetStep.LOGGING_IN
                    autoLogin()
                    ApiResult.Success(result.data)
                }
                is ApiResult.Error -> result
                else -> ApiResult.Error("Unknown error")
            }
        }
    }

    private suspend fun autoLogin() {
        val username = _email.value

        if (username.isEmpty()) {
            // If we don't have the email (e.g., deep link flow), fall back to manual login
            _currentStep.value = PasswordResetStep.SUCCESS
            return
        }

        _loginState.value = ApiResult.Loading

        val loginResult = APILayer.login(LoginRequest(username = username, password = _newPassword))

        when (loginResult) {
            is ApiResult.Success -> {
                val isVerified = loginResult.data.user.verified
                // Initialize lookups
                APILayer.initializeLookups()
                _loginState.value = loginResult
                // Call the login success callback
                onLoginSuccess?.invoke(isVerified)
            }
            is ApiResult.Error -> {
                // Auto-login failed, fall back to manual login
                println("Auto-login failed: ${loginResult.message}")
                _loginState.value = ApiResult.Idle
                _currentStep.value = PasswordResetStep.SUCCESS
            }
            else -> {
                _currentStep.value = PasswordResetStep.SUCCESS
            }
        }
    }

    fun moveToNextStep() {
        _currentStep.value = when (_currentStep.value) {
            PasswordResetStep.REQUEST_CODE -> PasswordResetStep.VERIFY_CODE
            PasswordResetStep.VERIFY_CODE -> PasswordResetStep.RESET_PASSWORD
            PasswordResetStep.RESET_PASSWORD -> PasswordResetStep.LOGGING_IN
            PasswordResetStep.LOGGING_IN -> PasswordResetStep.SUCCESS
            PasswordResetStep.SUCCESS -> PasswordResetStep.SUCCESS
        }
    }

    fun moveToPreviousStep() {
        _currentStep.value = when (_currentStep.value) {
            PasswordResetStep.REQUEST_CODE -> PasswordResetStep.REQUEST_CODE
            PasswordResetStep.VERIFY_CODE -> PasswordResetStep.REQUEST_CODE
            PasswordResetStep.RESET_PASSWORD -> PasswordResetStep.VERIFY_CODE
            PasswordResetStep.LOGGING_IN -> PasswordResetStep.LOGGING_IN // Can't go back while logging in
            PasswordResetStep.SUCCESS -> PasswordResetStep.SUCCESS
        }
    }

    fun resetForgotPasswordState() {
        _forgotPasswordState.value = ApiResult.Idle
    }

    fun resetVerifyCodeState() {
        _verifyCodeState.value = ApiResult.Idle
    }

    fun resetResetPasswordState() {
        _resetPasswordState.value = ApiResult.Idle
    }

    fun resetAll() {
        _email.value = ""
        _resetToken.value = null
        _forgotPasswordState.value = ApiResult.Idle
        _verifyCodeState.value = ApiResult.Idle
        _resetPasswordState.value = ApiResult.Idle
        _currentStep.value = PasswordResetStep.REQUEST_CODE
    }
}
