package com.example.smarthome.data

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.location.Geocoder
import android.util.Log
import androidx.core.content.ContextCompat
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONObject
import java.util.Locale
import java.util.concurrent.TimeUnit

data class WeatherInfo(
    val temperature: String,
    val weather: String,
    val humidity: String,
    val airQuality: String,
    val aqi: Int,
    val city: String
)

object WeatherService {
    private const val TAG = "WeatherService"
    
    private val client = OkHttpClient.Builder()
        .connectTimeout(15, TimeUnit.SECONDS)
        .readTimeout(15, TimeUnit.SECONDS)
        .build()
    
    /**
     * 获取天气信息
     * 优先使用GPS定位，失败则用IP定位
     */
    suspend fun getWeather(context: Context): WeatherInfo {
        return withContext(Dispatchers.IO) {
            // 1. 优先尝试GPS定位
            val gpsLocation = getGpsLocation(context)
            if (gpsLocation != null) {
                val (lat, lon, city) = gpsLocation
                Log.d(TAG, "GPS location: $city ($lat, $lon)")
                
                // 用GPS坐标获取天气
                val weatherResult = getWeatherByLocation(lat, lon, city)
                if (weatherResult != null) {
                    return@withContext weatherResult
                }
            }
            
            // 2. GPS失败，尝试wttr.in（IP定位）
            Log.w(TAG, "GPS failed, trying wttr.in...")
            val wttrResult = tryWttrIn()
            if (wttrResult != null) {
                return@withContext wttrResult
            }
            
            // 3. wttr.in失败，尝试备用方案
            Log.w(TAG, "wttr.in failed, trying backup...")
            val backupResult = tryBackupApi()
            if (backupResult != null) {
                return@withContext backupResult
            }
            
            // 都失败了，返回模拟数据
            Log.e(TAG, "All weather APIs failed")
            getSimulatedWeather()
        }
    }
    
    // 获取GPS位置
    @Suppress("DEPRECATION")
    private fun getGpsLocation(context: Context): Triple<Double, Double, String>? {
        // 检查权限
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Log.w(TAG, "No location permission")
            return null
        }
        
        val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as android.location.LocationManager
        
        // 尝试获取缓存的位置
        val providers = listOf(
            android.location.LocationManager.GPS_PROVIDER,
            android.location.LocationManager.NETWORK_PROVIDER,
            android.location.LocationManager.PASSIVE_PROVIDER
        )
        
        for (provider in providers) {
            try {
                val location = locationManager.getLastKnownLocation(provider)
                if (location != null) {
                    val lat = location.latitude
                    val lon = location.longitude
                    val city = getCityFromLocation(context, lat, lon)
                    Log.d(TAG, "Got location from $provider: $city ($lat, $lon)")
                    return Triple(lat, lon, city)
                }
            } catch (e: Exception) {
                Log.w(TAG, "Failed to get location from $provider: ${e.message}")
            }
        }
        
        Log.w(TAG, "No cached GPS location available")
        return null
    }
    
    // 通过经纬度获取城市名
    @Suppress("DEPRECATION")
    private fun getCityFromLocation(context: Context, lat: Double, lon: Double): String {
        return try {
            val geocoder = Geocoder(context, Locale.CHINESE)
            val addresses = geocoder.getFromLocation(lat, lon, 1)
            if (!addresses.isNullOrEmpty()) {
                addresses[0].locality ?: addresses[0].subAdminArea ?: addresses[0].adminArea ?: "未知"
            } else {
                "未知"
            }
        } catch (e: Exception) {
            Log.e(TAG, "Geocoder failed", e)
            "未知"
        }
    }
    
    // 通过经纬度获取天气
    private fun getWeatherByLocation(lat: Double, lon: Double, city: String): WeatherInfo? {
        return try {
            // 使用7timer获取天气
            val weatherUrl = "https://www.7timer.info/bin/civil.php?lon=$lon&lat=$lat&ac=0&unit=metric&output=json"
            val weatherRequest = Request.Builder().url(weatherUrl).build()
            val weatherResponse = client.newCall(weatherRequest).execute()
            val weatherBody = weatherResponse.body?.string() ?: "{}"
            
            if (!weatherResponse.isSuccessful) {
                Log.e(TAG, "7timer failed: ${weatherResponse.code}")
                return null
            }
            
            val weatherJson = JSONObject(weatherBody)
            val dataseries = weatherJson.optJSONArray("dataseries")?.optJSONObject(0)
            
            if (dataseries == null) {
                Log.w(TAG, "7timer: No data")
                return null
            }
            
            val temp = dataseries.optInt("temp2m", 0).toString()
            val humidity = dataseries.optInt("rh2m", 0).toString()
            val weatherCode = dataseries.optString("weather", "")
            val weather = convertWeatherCode(weatherCode)
            
            Log.d(TAG, "GPS weather success: $temp°C, $weather, $city")
            
            WeatherInfo(temp, weather, humidity, "良", 50, city)
        } catch (e: Exception) {
            Log.e(TAG, "getWeatherByLocation exception", e)
            null
        }
    }
    
    // wttr.in API
    private fun tryWttrIn(): WeatherInfo? {
        return try {
            val url = "https://wttr.in/?format=j1&lang=zh"
            val request = Request.Builder()
                .url(url)
                .header("User-Agent", "SmartHome/1.0")
                .build()
            
            val response = client.newCall(request).execute()
            val body = response.body?.string() ?: "{}"
            Log.d(TAG, "wttr.in response code: ${response.code}")
            
            if (!response.isSuccessful) {
                Log.e(TAG, "wttr.in request failed: ${response.code}")
                return null
            }
            
            val json = JSONObject(body)
            val currentCondition = json.optJSONArray("current_condition")?.optJSONObject(0)
            val nearestArea = json.optJSONArray("nearest_area")?.optJSONObject(0)
            
            if (currentCondition == null) {
                Log.w(TAG, "wttr.in: No current condition data")
                return null
            }
            
            val areaName = nearestArea?.optJSONArray("areaName")?.optJSONObject(0)?.optString("value", "")
            val region = nearestArea?.optJSONArray("region")?.optJSONObject(0)?.optString("value", "")
            
            val cityName = when {
                !areaName.isNullOrBlank() && areaName != "Unknown" -> convertToChineseCityName(areaName)
                !region.isNullOrBlank() && region != "Unknown" -> convertToChineseCityName(region)
                else -> "未知"
            }
            
            val weatherDescArray = currentCondition.optJSONArray("lang_zh")
            val weatherDesc = weatherDescArray?.optJSONObject(0)?.optString("value", "未知") ?: "未知"
            val temp = currentCondition.optString("temp_C", "--")
            val humidity = currentCondition.optString("humidity", "--")
            
            Log.d(TAG, "wttr.in success: $temp°C, $weatherDesc, $cityName")
            
            WeatherInfo(temp, weatherDesc, humidity, "良", 50, cityName)
        } catch (e: Exception) {
            Log.e(TAG, "wttr.in exception", e)
            null
        }
    }
    
    // 备用API - 使用ip-api获取位置 + 7timer获取天气
    private fun tryBackupApi(): WeatherInfo? {
        return try {
            // 1. 获取IP位置
            val ipUrl = "http://ip-api.com/json/?lang=zh-CN"
            val ipRequest = Request.Builder().url(ipUrl).build()
            val ipResponse = client.newCall(ipRequest).execute()
            val ipBody = ipResponse.body?.string() ?: "{}"
            Log.d(TAG, "ip-api response: $ipBody")
            
            val ipJson = JSONObject(ipBody)
            val city = ipJson.optString("city", "未知")
            val lat = ipJson.optDouble("lat", 0.0)
            val lon = ipJson.optDouble("lon", 0.0)
            
            if (lat == 0.0 && lon == 0.0) {
                Log.w(TAG, "ip-api: Invalid location")
                return null
            }
            
            Log.d(TAG, "Location: $city ($lat, $lon)")
            
            // 2. 获取天气 - 使用7timer（免费，无需注册）
            val weatherUrl = "https://www.7timer.info/bin/civil.php?lon=$lon&lat=$lat&ac=0&unit=metric&output=json"
            val weatherRequest = Request.Builder().url(weatherUrl).build()
            val weatherResponse = client.newCall(weatherRequest).execute()
            val weatherBody = weatherResponse.body?.string() ?: "{}"
            Log.d(TAG, "7timer response code: ${weatherResponse.code}")
            
            if (!weatherResponse.isSuccessful) {
                Log.e(TAG, "7timer failed: ${weatherResponse.code}")
                return null
            }
            
            val weatherJson = JSONObject(weatherBody)
            val dataseries = weatherJson.optJSONArray("dataseries")?.optJSONObject(0)
            
            if (dataseries == null) {
                Log.w(TAG, "7timer: No data")
                return null
            }
            
            val temp = dataseries.optInt("temp2m", 0).toString()
            val humidity = dataseries.optInt("rh2m", 0).toString()
            val weatherCode = dataseries.optString("weather", "")
            val weather = convertWeatherCode(weatherCode)
            
            Log.d(TAG, "7timer success: $temp°C, $weather, $city")
            
            WeatherInfo(temp, weather, humidity, "良", 50, city)
        } catch (e: Exception) {
            Log.e(TAG, "Backup API exception", e)
            null
        }
    }
    
    // 7timer天气代码转中文
    private fun convertWeatherCode(code: String): String {
        return when {
            code.contains("clear") -> "晴"
            code.contains("pcloudy") -> "多云"
            code.contains("mcloudy") -> "多云"
            code.contains("cloudy") -> "阴"
            code.contains("humid") -> "潮湿"
            code.contains("lightrain") -> "小雨"
            code.contains("rain") -> "雨"
            code.contains("oshower") -> "阵雨"
            code.contains("ishower") -> "阵雨"
            code.contains("lightsnow") -> "小雪"
            code.contains("snow") -> "雪"
            code.contains("ts") -> "雷暴"
            else -> "晴"
        }
    }
    
    // 拼音城市名转中文（常用城市）
    private fun convertToChineseCityName(pinyin: String): String {
        val cityMap = mapOf(
            "Beijing" to "北京",
            "Shanghai" to "上海",
            "Guangzhou" to "广州",
            "Shenzhen" to "深圳",
            "Hangzhou" to "杭州",
            "Nanjing" to "南京",
            "Wuxi" to "无锡",
            "Suzhou" to "苏州",
            "Chengdu" to "成都",
            "Chongqing" to "重庆",
            "Wuhan" to "武汉",
            "Xi'an" to "西安",
            "Tianjin" to "天津",
            "Qingdao" to "青岛",
            "Dalian" to "大连",
            "Xiamen" to "厦门",
            "Ningbo" to "宁波",
            "Changsha" to "长沙",
            "Jiangsu" to "江苏",
            "Zhejiang" to "浙江",
            "Guangdong" to "广东",
            "Sichuan" to "四川"
        )
        return cityMap[pinyin] ?: pinyin
    }
    
    // 模拟天气数据（当API不可用时使用）
    fun getSimulatedWeather(): WeatherInfo {
        return WeatherInfo(
            temperature = "24",
            weather = "晴",
            humidity = "45",
            airQuality = "良",
            aqi = 50,
            city = "未知"
        )
    }
}
