package com.hipograf.companion.api

import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.hipograf.companion.BuildConfig
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import java.util.concurrent.TimeUnit

/**
 * Hipograf backend API client.
 * Handles login and Samsung Health data sync.
 */
object HipografApi {

    private val BASE_URL = BuildConfig.API_BASE_URL
    private val JSON = "application/json; charset=utf-8".toMediaType()
    private val gson = Gson()

    private val client = OkHttpClient.Builder()
        .connectTimeout(15, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS)
        .build()

    data class LoginResponse(
        val accessToken: String,
        val tokenType: String,
        val expiresIn: Int,
        val user: Map<String, Any>
    )

    data class SyncResponse(
        val accepted: Int,
        val serverTime: String
    )

    /**
     * Log in to Hipograf. Returns the JWT token on success.
     */
    fun login(identifier: String, password: String): Result<LoginResponse> {
        return try {
            // Determine if identifier is email or username
            val isEmail = identifier.contains("@")
            val body = if (isEmail) {
                mapOf("email" to identifier, "password" to password)
            } else {
                mapOf("username" to identifier, "password" to password)
            }

            val request = Request.Builder()
                .url("$BASE_URL/api/auth/login")
                .post(gson.toJson(body).toRequestBody(JSON))
                .build()

            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""

            if (response.isSuccessful) {
                val loginResp = gson.fromJson(responseBody, LoginResponse::class.java)
                Result.success(loginResp)
            } else {
                val error = try {
                    gson.fromJson<Map<String, String>>(
                        responseBody,
                        object : TypeToken<Map<String, String>>() {}.type
                    )["error"] ?: "Login failed"
                } catch (_: Exception) { "Login failed (${response.code})" }
                Result.failure(Exception(error))
            }
        } catch (e: Exception) {
            Result.failure(Exception("Network error: ${e.message}"))
        }
    }

    /**
     * Push Samsung Health readings to the backend.
     */
    fun syncReadings(token: String, readings: List<Map<String, Any>>, deviceInfo: Map<String, String>): Result<SyncResponse> {
        return try {
            val payload = mapOf(
                "readings" to readings,
                "syncedAt" to java.time.Instant.now().toString(),
                "deviceInfo" to deviceInfo
            )

            val request = Request.Builder()
                .url("$BASE_URL/api/devices/sync/samsung_health")
                .addHeader("Authorization", "Bearer $token")
                .post(gson.toJson(payload).toRequestBody(JSON))
                .build()

            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""

            if (response.isSuccessful) {
                val syncResp = gson.fromJson(responseBody, SyncResponse::class.java)
                Result.success(syncResp)
            } else {
                Result.failure(Exception("Sync failed (${response.code})"))
            }
        } catch (e: Exception) {
            Result.failure(Exception("Network error: ${e.message}"))
        }
    }
}
