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 ResidenceApi(private val client: HttpClient = ApiClient.httpClient) {
    private val baseUrl = ApiClient.getBaseUrl()

    suspend fun getResidences(token: String): ApiResult<List<ResidenceResponse>> {
        return try {
            val response = client.get("$baseUrl/residences/") {
                header("Authorization", "Token $token")
            }

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

    suspend fun getResidence(token: String, id: Int): ApiResult<ResidenceResponse> {
        return try {
            val response = client.get("$baseUrl/residences/$id/") {
                header("Authorization", "Token $token")
            }

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

    suspend fun createResidence(token: String, request: ResidenceCreateRequest): ApiResult<WithSummaryResponse<ResidenceResponse>> {
        return try {
            val response = client.post("$baseUrl/residences/") {
                header("Authorization", "Token $token")
                contentType(ContentType.Application.Json)
                setBody(request)
            }

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

    suspend fun updateResidence(token: String, id: Int, request: ResidenceCreateRequest): ApiResult<WithSummaryResponse<ResidenceResponse>> {
        return try {
            val response = client.put("$baseUrl/residences/$id/") {
                header("Authorization", "Token $token")
                contentType(ContentType.Application.Json)
                setBody(request)
            }

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

    suspend fun deleteResidence(token: String, id: Int): ApiResult<WithSummaryResponse<String>> {
        return try {
            val response = client.delete("$baseUrl/residences/$id/") {
                header("Authorization", "Token $token")
            }

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

    suspend fun getSummary(token: String): ApiResult<TotalSummary> {
        return try {
            val response = client.get("$baseUrl/residences/summary/") {
                header("Authorization", "Token $token")
            }

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

    suspend fun getMyResidences(token: String): ApiResult<MyResidencesResponse> {
        return try {
            val response = client.get("$baseUrl/residences/my-residences/") {
                header("Authorization", "Token $token")
            }

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

    // Share Code Management
    suspend fun generateSharePackage(token: String, residenceId: Int): ApiResult<SharedResidence> {
        return try {
            val response = client.post("$baseUrl/residences/$residenceId/generate-share-package/") {
                header("Authorization", "Token $token")
            }

            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")
        }
    }

    suspend fun generateShareCode(token: String, residenceId: Int): ApiResult<GenerateShareCodeResponse> {
        return try {
            val response = client.post("$baseUrl/residences/$residenceId/generate-share-code/") {
                header("Authorization", "Token $token")
            }

            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")
        }
    }

    suspend fun getShareCode(token: String, residenceId: Int): ApiResult<ShareCodeResponse> {
        return try {
            val response = client.get("$baseUrl/residences/$residenceId/share-code/") {
                header("Authorization", "Token $token")
            }

            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")
        }
    }

    /**
     * Accept a residence invite (push-notification action button).
     *
     * Backend: `POST /api/residences/{id}/invite/accept`. No body.
     * Parity: `NotificationCategories.swift` ACCEPT_INVITE on iOS.
     */
    suspend fun acceptResidenceInvite(token: String, residenceId: Int): ApiResult<Unit> {
        return try {
            val response = client.post("$baseUrl/residences/$residenceId/invite/accept/") {
                header("Authorization", "Token $token")
            }

            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")
        }
    }

    /**
     * Decline a residence invite. See [acceptResidenceInvite] for endpoint
     * pattern. Backend: `POST /api/residences/{id}/invite/decline`.
     */
    suspend fun declineResidenceInvite(token: String, residenceId: Int): ApiResult<Unit> {
        return try {
            val response = client.post("$baseUrl/residences/$residenceId/invite/decline/") {
                header("Authorization", "Token $token")
            }

            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")
        }
    }

    suspend fun joinWithCode(token: String, code: String): ApiResult<JoinResidenceResponse> {
        return try {
            val response = client.post("$baseUrl/residences/join-with-code/") {
                header("Authorization", "Token $token")
                contentType(ContentType.Application.Json)
                setBody(JoinResidenceRequest(code))
            }

            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")
        }
    }

    // User Management
    suspend fun getResidenceUsers(token: String, residenceId: Int): ApiResult<ResidenceUsersResponse> {
        return try {
            val response = client.get("$baseUrl/residences/$residenceId/users/") {
                header("Authorization", "Token $token")
            }

            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")
        }
    }

    suspend fun removeUser(token: String, residenceId: Int, userId: Int): ApiResult<RemoveUserResponse> {
        return try {
            val response = client.delete("$baseUrl/residences/$residenceId/users/$userId/") {
                header("Authorization", "Token $token")
            }

            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")
        }
    }

    // PDF Report Generation
    suspend fun generateTasksReport(token: String, residenceId: Int, email: String? = null): ApiResult<GenerateReportResponse> {
        return try {
            val response = client.post("$baseUrl/residences/$residenceId/generate-tasks-report/") {
                header("Authorization", "Token $token")
                contentType(ContentType.Application.Json)
                if (email != null) {
                    setBody(mapOf("email" to email))
                }
            }

            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")
        }
    }
}

@kotlinx.serialization.Serializable
data class GenerateReportResponse(
    val message: String,
    val residence_name: String,
    val recipient_email: String
)

// Removed: PaginatedResponse - no longer using paginated responses
// All API endpoints now return direct lists instead of paginated responses
