package com.radiola.data.repository

import android.content.Context
import android.telephony.TelephonyManager
import android.util.Log
import com.radiola.domain.repository.RegionRepository
import com.radiola.domain.repository.SettingsRepository
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import java.util.Locale
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Определяет страну пользователя по IP (для гео-фильтрации). Код кэшируется в
 * настройках, так что после первого успешного запроса работает мгновенно и
 * оффлайн. Источник — публичные гео-IP сервисы (без ключа).
 */
@Singleton
class RegionRepositoryImpl @Inject constructor(
    private val okHttpClient: OkHttpClient,
    private val settingsRepository: SettingsRepository,
    @ApplicationContext private val context: Context
) : RegionRepository {

    override fun countryCode(): Flow<String?> = settingsRepository.getCountryCode()

    override suspend fun refresh() {
        withContext(Dispatchers.IO) {
            val code = fetchCountry()
            Log.d("RegionRepo", "country=$code")
            if (code != null) settingsRepository.setCountryCode(code)
        }
    }

    private fun fetchCountry(): String? {
        // IP — приоритет (учитывает VPN: при VPN страна = выходного узла, и тогда
        // украинские потоки доступны → не скрываем).
        ipCountry()?.let { return it }
        // Фолбэк, если IP-сервис недоступен (напр. заблокирован): страна SIM/сети/локали.
        return deviceCountry()
    }

    private fun ipCountry(): String? {
        // 1) api.country.is → {"ip":"..","country":"RU"}
        request("https://api.country.is/")?.let { body ->
            Regex("\"country\"\\s*:\\s*\"([A-Za-z]{2})\"").find(body)?.groupValues?.get(1)?.let {
                return it.uppercase()
            }
        }
        // 2) ipapi.co/country/ → "RU"
        request("https://ipapi.co/country/")?.trim()?.let { body ->
            if (body.matches(Regex("[A-Za-z]{2}"))) return body.uppercase()
        }
        return null
    }

    private fun deviceCountry(): String? = try {
        val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager
        val net = tm?.networkCountryIso?.takeIf { it.isNotBlank() }
        val sim = tm?.simCountryIso?.takeIf { it.isNotBlank() }
        (net ?: sim ?: Locale.getDefault().country.takeIf { it.isNotBlank() })?.uppercase()
    } catch (e: Exception) {
        null
    }

    private fun request(url: String): String? = try {
        okHttpClient.newCall(
            Request.Builder().url(url).header("User-Agent", "radiOLA").build()
        ).execute().use { if (it.isSuccessful) it.body?.string() else null }
    } catch (e: Exception) {
        Log.w("RegionRepo", "geo fetch fail ($url): ${e.message}")
        null
    }
}
