package org.dromara.system.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.system.domain.vo.WeatherVo;
import org.dromara.system.service.IWeatherService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class WeatherServiceImpl implements IWeatherService {

    private static final String FUZHOU_LOCATION = "101210101";
    private static final String FUAN_LOCATION = "101210901";
    private static final String WEATHER_API_URL = "https://p26hexq5xk.yun.qweatherapi.com/v7/weather/7d";
    private static final String REDIS_KEY_PREFIX = "weather:";
    private static final String REDIS_KEY = REDIS_KEY_PREFIX + FUZHOU_LOCATION;
    private static final String REDIS_KEY_FUAN = REDIS_KEY_PREFIX + FUAN_LOCATION;

    @Value("${qweather.apiKey}")
    private String apiKey;

    @Override
    public WeatherVo getFuzhouWeather() {
        try {
            WeatherVo cachedWeather = RedisUtils.getCacheObject(REDIS_KEY);
            if (cachedWeather != null) {
                log.info("从 Redis 获取福州天气数据");
                return cachedWeather;
            }

            log.info("调用和风天气 API 获取福州天气数据");
            WeatherVo weather = fetchWeatherFromApi(FUZHOU_LOCATION, "福州", REDIS_KEY);
            if (weather != null) {
                long expireTime = calculateExpireTime();
                RedisUtils.setCacheObject(REDIS_KEY, weather, Duration.ofMillis(expireTime));
                log.info("福州天气数据已缓存，过期时间：{} 毫秒", expireTime);
            }
            return weather;
        } catch (Exception e) {
            log.error("获取福州天气失败", e);
            return null;
        }
    }

    @Override
    public WeatherVo getFuAnWeather() {
        try {
            WeatherVo cachedWeather = RedisUtils.getCacheObject(REDIS_KEY_FUAN);
            if (cachedWeather != null) {
                log.info("从 Redis 获取福安天气数据");
                return cachedWeather;
            }

            log.info("调用和风天气 API 获取福安天气数据");
            WeatherVo weather = fetchWeatherFromApi(FUAN_LOCATION, "福安", REDIS_KEY_FUAN);
            if (weather != null) {
                long expireTime = calculateExpireTime();
                RedisUtils.setCacheObject(REDIS_KEY_FUAN, weather, Duration.ofMillis(expireTime));
                log.info("福安天气数据已缓存，过期时间：{} 毫秒", expireTime);
            }
            return weather;
        } catch (Exception e) {
            log.error("获取福安天气失败", e);
            return null;
        }
    }

    private WeatherVo fetchWeatherFromApi(String location, String cityName, String redisKey) {
        try {
            String url = WEATHER_API_URL + "?location=" + location + "&key=" + apiKey;
            String response = HttpUtil.get(url, 30000);
            JSONObject jsonResponse = JSONUtil.parseObj(response);

            if (jsonResponse.getInt("code") != 200) {
                log.error("和风天气 API 返回错误：{}", jsonResponse.getStr("message"));
                return null;
            }

            WeatherVo weather = new WeatherVo();
            weather.setLocation(cityName);
            weather.setFxLink(jsonResponse.getStr("fxLink"));

            List<JSONObject> dailyJsonList = jsonResponse.getBeanList("daily", JSONObject.class);
            List<WeatherVo.DayWeather> dayWeatherList = new ArrayList<>();

            for (JSONObject dayJson : dailyJsonList) {
                WeatherVo.DayWeather dayWeather = new WeatherVo.DayWeather();
                dayWeather.setFxDate(dayJson.getStr("fxDate"));
                dayWeather.setTempMax(dayJson.getStr("tempMax"));
                dayWeather.setTempMin(dayJson.getStr("tempMin"));
                dayWeather.setIconDay(dayJson.getStr("iconDay"));
                dayWeather.setTextDay(dayJson.getStr("textDay"));
                dayWeather.setWindDirDay(dayJson.getStr("windDirDay"));
                dayWeather.setWindScaleDay(dayJson.getStr("windScaleDay"));
                dayWeather.setHumidity(dayJson.getStr("humidity"));
                dayWeatherList.add(dayWeather);
            }
            weather.setDaily(dayWeatherList);

            return weather;
        } catch (Exception e) {
            log.error("调用和风天气 API 失败", e);
            return null;
        }
    }

    private long calculateExpireTime() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime tomorrowMidnight = LocalDate.now().plusDays(1).atTime(LocalTime.MIDNIGHT);
        return Duration.between(now, tomorrowMidnight).toMillis();
    }
}
