package com.usky.cdi.service.util;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;

/**
 * 天气数据获取工具类
 * 使用OpenWeatherMap API获取天气数据，并进行缓存
 * @author fyc
 * @email yuchuan.fu@chinausky.com
 * @date 2025/12/15
 */
@Slf4j
public class WeatherFetcher {
    private static final String API_KEY = "d04f0f84421a99b9b66dd99243c36db4";
    private static final String CITY_NAME = "shanghai,cn";
    private static final String API_URL = "https://api.openweathermap.org/data/2.5/weather?q=" + CITY_NAME + "&appid=" + API_KEY;

    // 缓存相关字段
    private static final Map<String, Double> weatherCache = new ConcurrentHashMap<>();
    private static long lastUpdateTime = 0;
    private static final long CACHE_EXPIRE_TIME = 30 * 60 * 1000;  // 缓存30分钟

    // 默认天气数据，当API调用失败时使用
    private static final double DEFAULT_TEMPERATURE = 15.0;
    private static final int DEFAULT_HUMIDITY = 40;

    /**
     * 获取天气数据
     * 1. 优先使用缓存数据（如果缓存有效）
     * 2. 缓存无效时，调用API获取新数据
     * 3. API调用失败时，使用默认值
     *
     * @return 包含温度和湿度的Map
     */
    public static Map<String, Double> fetchWeather() {
        // 1. 检查缓存是否有效
        long currentTime = System.currentTimeMillis();
        if (!weatherCache.isEmpty() && (currentTime - lastUpdateTime) < CACHE_EXPIRE_TIME) {
            log.debug("使用缓存的天气数据，温度：{}°C，湿度：{}%",
                    weatherCache.get("temperature"), weatherCache.get("humidity"));
            return new HashMap<>(weatherCache);
        }

        double tempCelsius = DEFAULT_TEMPERATURE;
        int humidity = DEFAULT_HUMIDITY;

        log.debug("开始调用OpenWeatherMap API获取天气数据");
        long startTime = System.currentTimeMillis();

        try {
            // 1. 构造请求URL
            URL url = new URL(API_URL);

            // 2. 建立连接并发送请求
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(15000);
            conn.setReadTimeout(15000);

            // 3. 读取响应
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();

            // 4. 解析JSON数据（使用org.json库）
            JSONObject jsonResponse = new JSONObject(response.toString());
            JSONObject main = jsonResponse.getJSONObject("main");

            // 提取基础信息
            String cityName = jsonResponse.getString("name");
            int timezoneOffset = jsonResponse.getInt("timezone");

            // 注意：温度默认是开尔文单位，转换为摄氏度需要 -273.15
            double tempKelvin = main.getDouble("temp");
            tempCelsius = tempKelvin - 273.15;
            humidity = main.getInt("humidity");
            double feelsLikeKelvin = main.getDouble("feels_like");
            double feelsLikeCelsius = feelsLikeKelvin - 273.15;

            // 提取天气状况描述
            JSONObject weather = jsonResponse.getJSONArray("weather").getJSONObject(0);
            String description = weather.getString("description");

            // 记录日志，不输出到控制台
            log.debug("=== 天气解析结果 ===");
            log.debug("城市: {}", cityName);
            log.debug("温度: {:.2f}°C (原始: {}K)", tempCelsius, tempKelvin);
            System.out.println("体感温度: {:.2f}°C (原始: {}K)" + feelsLikeCelsius + "==========" + feelsLikeKelvin);
            log.debug("体感温度: {:.2f}°C", feelsLikeCelsius);
            log.debug("湿度: {}%", humidity);
            log.debug("天气状况: {}", description);
            log.debug("时区偏移: {}小时", (timezoneOffset / 3600));

            // 检查是否包含臭氧数据
            if (jsonResponse.has("air_quality") || jsonResponse.has("o3") || jsonResponse.has("components")) {
                log.debug("包含空气质量数据");
            } else {
                log.debug("当前数据不包含臭氧浓度等空气质量指标");
            }

            // 更新缓存
            weatherCache.clear();
            weatherCache.put("temperature", tempCelsius);
            weatherCache.put("humidity", (double) humidity);
            lastUpdateTime = currentTime;
            log.debug("天气数据缓存更新成功");

        } catch (Exception e) {
            log.error("获取天气数据失败：{}", e.getMessage());
            // 异常时使用默认值
            log.warn("使用默认天气数据，温度：{}°C，湿度：{}%", DEFAULT_TEMPERATURE, DEFAULT_HUMIDITY);
        } finally {
            // 打印API调用结束时间和时长
            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;
            System.out.println("第三方天气API调用时长" + duration + "毫秒");
            log.info("OpenWeatherMap API调用结束，开始时间: {}, 结束时间: {}, 时长: {}ms", startTime, endTime, duration);
        }

        Map<String, Double> resultMap = new HashMap<>();
        resultMap.put("temperature", tempCelsius);
        resultMap.put("humidity", (double) humidity);
        return resultMap;
    }

    public static void main(String[] args) {
        fetchWeather();
    }
}
