package com.tt.honeyDue.network

import com.tt.honeyDue.models.*
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.http.*

class AuthApi(private val client: HttpClient = ApiClient.httpClient) {
    private val baseUrl = ApiClient.getBaseUrl()

    suspend fun register(request: RegisterRequest): ApiResult<AuthResponse> {
        return try {
            val response = client.post("$baseUrl/auth/register/") {
                contentType(ContentType.Application.Json)
                setBody(request)
            }

            if (response.status.isSuccess()) {
                ApiResult.Success(response.body())
            } else {
                // Parse actual error message from backend
                val errorMessage = ErrorParser.parseError(response)
                ApiResult.Error(errorMessage, response.status.value)
            }
        } catch (e: Exception) {
            ApiResult.Error(e.message ?: "Unknown error occurred")
        }
    }

    suspend fun login(request: LoginRequest): ApiResult<AuthResponse> {
        return try {
            val response = client.post("$baseUrl/auth/login/") {
                contentType(ContentType.Application.Json)
                setBody(request)
            }

            if (response.status.isSuccess()) {
                ApiResult.Success(response.body())
            } else {
                // Parse actual error message from backend
                val errorMessage = ErrorParser.parseError(response)
                ApiResult.Error(errorMessage, response.status.value)
            }
        } catch (e: Exception) {
            ApiResult.Error(e.message ?: "Unknown error occurred")
        }
    }

    suspend fun logout(token: String): ApiResult<Unit> {
        return try {
            val response = client.post("$baseUrl/auth/logout/") {
                header("Authorization", "Token $token")
            }

            if (response.status.isSuccess()) {
                ApiResult.Success(Unit)
            } else {
                ApiResult.Error("Logout failed", response.status.value)
            }
        } catch (e: Exception) {
            ApiResult.Error(e.message ?: "Unknown error occurred")
        }
    }

    suspend fun getCurrentUser(token: String): ApiResult<User> {
        return try {
            val response = client.get("$baseUrl/auth/me/") {
                header("Authorization", "Token $token")
            }

            if (response.status.isSuccess()) {
                ApiResult.Success(response.body())
            } else {
                ApiResult.Error("Failed to get user", response.status.value)
            }
        } catch (e: Exception) {
            ApiResult.Error(e.message ?: "Unknown error occurred")
        }
    }

    suspend fun verifyEmail(token: String, request: VerifyEmailRequest): ApiResult<VerifyEmailResponse> {
        return try {
            val response = client.post("$baseUrl/auth/verify-email/") {
                header("Authorization", "Token $token")
                contentType(ContentType.Application.Json)
                setBody(request)
            }

            if (response.status.isSuccess()) {
                ApiResult.Success(response.body())
            } else {
                val errorBody = try {
                    response.body<Map<String, String>>()
                } catch (e: Exception) {
                    mapOf("error" to "Verification failed")
                }
                ApiResult.Error(errorBody["error"] ?: "Verification failed", response.status.value)
            }
        } catch (e: Exception) {
            ApiResult.Error(e.message ?: "Unknown error occurred")
        }
    }

    suspend fun updateProfile(token: String, request: UpdateProfileRequest): ApiResult<User> {
        return try {
            val response = client.put("$baseUrl/auth/profile/") {
                header("Authorization", "Token $token")
                contentType(ContentType.Application.Json)
                setBody(request)
            }

            if (response.status.isSuccess()) {
                ApiResult.Success(response.body())
            } else {
                val errorBody = try {
                    response.body<Map<String, String>>()
                } catch (e: Exception) {
                    mapOf("error" to "Profile update failed")
                }
                ApiResult.Error(errorBody["error"] ?: "Profile update failed", response.status.value)
            }
        } catch (e: Exception) {
            ApiResult.Error(e.message ?: "Unknown error occurred")
        }
    }

    // Password Reset Methods
    suspend fun forgotPassword(request: ForgotPasswordRequest): ApiResult<ForgotPasswordResponse> {
        return try {
            val response = client.post("$baseUrl/auth/forgot-password/") {
                contentType(ContentType.Application.Json)
                setBody(request)
            }

            if (response.status.isSuccess()) {
                ApiResult.Success(response.body())
            } else {
                val errorBody = try {
                    response.body<Map<String, String>>()
                } catch (e: Exception) {
                    mapOf("error" to "Failed to send reset code")
                }
                ApiResult.Error(errorBody["error"] ?: "Failed to send reset code", response.status.value)
            }
        } catch (e: Exception) {
            ApiResult.Error(e.message ?: "Unknown error occurred")
        }
    }

    suspend fun verifyResetCode(request: VerifyResetCodeRequest): ApiResult<VerifyResetCodeResponse> {
        return try {
            val response = client.post("$baseUrl/auth/verify-reset-code/") {
                contentType(ContentType.Application.Json)
                setBody(request)
            }

            if (response.status.isSuccess()) {
                ApiResult.Success(response.body())
            } else {
                val errorBody = try {
                    response.body<Map<String, String>>()
                } catch (e: Exception) {
                    mapOf("error" to "Invalid code")
                }
                ApiResult.Error(errorBody["error"] ?: "Invalid code", response.status.value)
            }
        } catch (e: Exception) {
            ApiResult.Error(e.message ?: "Unknown error occurred")
        }
    }

    suspend fun resetPassword(request: ResetPasswordRequest): ApiResult<ResetPasswordResponse> {
        return try {
            val response = client.post("$baseUrl/auth/reset-password/") {
                contentType(ContentType.Application.Json)
                setBody(request)
            }

            if (response.status.isSuccess()) {
                ApiResult.Success(response.body())
            } else {
                // Try to parse Django validation errors (Map<String, List<String>>)
                val errorMessage = try {
                    val validationErrors = response.body<Map<String, List<String>>>()
                    // Flatten all error messages into a single string
                    validationErrors.flatMap { (field, errors) ->
                        errors.map { error ->
                            if (field == "non_field_errors") error else "$field: $error"
                        }
                    }.joinToString(". ")
                } catch (e: Exception) {
                    // Try simple error format {error: "message"}
                    try {
                        val simpleError = response.body<Map<String, String>>()
                        simpleError["error"] ?: "Failed to reset password"
                    } catch (e2: Exception) {
                        "Failed to reset password"
                    }
                }
                ApiResult.Error(errorMessage, response.status.value)
            }
        } catch (e: Exception) {
            ApiResult.Error(e.message ?: "Unknown error occurred")
        }
    }

    // Apple Sign In
    suspend fun appleSignIn(request: AppleSignInRequest): ApiResult<AppleSignInResponse> {
        return try {
            val response = client.post("$baseUrl/auth/apple-sign-in/") {
                contentType(ContentType.Application.Json)
                setBody(request)
            }

            if (response.status.isSuccess()) {
                ApiResult.Success(response.body())
            } else {
                val errorBody = try {
                    response.body<Map<String, String>>()
                } catch (e: Exception) {
                    mapOf("error" to "Apple Sign In failed")
                }
                ApiResult.Error(errorBody["error"] ?: "Apple Sign In failed", response.status.value)
            }
        } catch (e: Exception) {
            ApiResult.Error(e.message ?: "Unknown error occurred")
        }
    }

    // Delete Account
    suspend fun deleteAccount(token: String, request: DeleteAccountRequest): ApiResult<Unit> {
        return try {
            val response = client.delete("$baseUrl/auth/account/") {
                header("Authorization", "Token $token")
                contentType(ContentType.Application.Json)
                setBody(request)
            }

            if (response.status.isSuccess()) {
                ApiResult.Success(Unit)
            } else {
                val errorMessage = ErrorParser.parseError(response)
                ApiResult.Error(errorMessage, response.status.value)
            }
        } catch (e: Exception) {
            ApiResult.Error(e.message ?: "Unknown error occurred")
        }
    }

    // Token Refresh
    suspend fun refreshToken(token: String): ApiResult<TokenRefreshResponse> {
        return try {
            val response = client.post("$baseUrl/auth/refresh/") {
                header("Authorization", "Token $token")
                contentType(ContentType.Application.Json)
            }

            if (response.status.isSuccess()) {
                ApiResult.Success(response.body())
            } else {
                val errorMessage = ErrorParser.parseError(response)
                ApiResult.Error(errorMessage, response.status.value)
            }
        } catch (e: Exception) {
            ApiResult.Error(e.message ?: "Unknown error occurred")
        }
    }

    // Google Sign In
    suspend fun googleSignIn(request: GoogleSignInRequest): ApiResult<GoogleSignInResponse> {
        return try {
            val response = client.post("$baseUrl/auth/google-sign-in/") {
                contentType(ContentType.Application.Json)
                setBody(request)
            }

            if (response.status.isSuccess()) {
                ApiResult.Success(response.body())
            } else {
                val errorBody = try {
                    response.body<Map<String, String>>()
                } catch (e: Exception) {
                    mapOf("error" to "Google Sign In failed")
                }
                ApiResult.Error(errorBody["error"] ?: "Google Sign In failed", response.status.value)
            }
        } catch (e: Exception) {
            ApiResult.Error(e.message ?: "Unknown error occurred")
        }
    }
}
