package com.multictrl.modules.business.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.multictrl.common.constant.SysParamsKey;
import com.multictrl.common.exception.ErrorCode;
import com.multictrl.common.exception.RenException;
import com.multictrl.common.utils.JsonUtils;
import com.multictrl.modules.business.service.WeatherService;
import com.multictrl.modules.sys.dao.SysParamsDao;
import com.multictrl.modules.sys.entity.SysParamsEntity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 天气服务
 *
 * @author Sdy
 * @since 1.0.0 2026/6/16
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WeatherServiceImpl implements WeatherService {
    private final SysParamsDao paramsDao;

    private final static String GAODE_GEOCODE_REGEO = "https://restapi.amap.com/v3/geocode/regeo?key=%s&location=%s&radius=1&extensions=all";
    public static final String GAODE_WEATHER_API = "https://restapi.amap.com/v3/weather/weatherInfo?key=%s&city=%s&extensions=base";

    @Override
    public String getWeatherByLonLat(Double longitude, Double latitude) {
        String location = longitude + "," + latitude;
        try {
            String adCode = getAdCode(location);
            if (StrUtil.isEmpty(adCode)) {
                log.debug("获取 adcode 失败，经纬度：{}", location);
                throw new RenException(ErrorCode.GAODE_REQUEST_ERROR);
            }
            String weatherByAdCode = getWeatherByAdCode(adCode);
            if (StrUtil.isEmpty(weatherByAdCode)) {
                log.debug("获取 weatherByAdCode 失败，经纬度：{}, adCode：{}", location, adCode);
                throw new RenException(ErrorCode.GAODE_REQUEST_ERROR);
            }
            return weatherByAdCode;
        } catch (Exception e) {
            log.error("获取天气信息异常，经纬度：{}", location, e);
            throw new RenException(ErrorCode.GAODE_REQUEST_ERROR);
        }
    }

    /**
     * 获取高德Key
     */
    private String getGaoDeKey() {
        SysParamsEntity entity = paramsDao.selectOne(new QueryWrapper<SysParamsEntity>()
                .eq("param_code", SysParamsKey.GAODE_API_KEY));
        if (entity == null) {
            throw new RenException(ErrorCode.GAODE_API_KEY_NO_CONFIG);
        }

        return entity.getParamValue();
    }

    /**
     * 调用高德地理编码 API 获取 adcode
     */
    private String getAdCode(String location) {
        String url = String.format(GAODE_GEOCODE_REGEO, getGaoDeKey(), location);
        try {
            String response = HttpUtil.get(url);
            if (StrUtil.isEmpty(response)) {
                log.debug("gaode_地理编码接口返回空，url：{}", url);
                return null;
            }
            JSONObject jsonObject = JsonUtils.parseObject(response, JSONObject.class);
            if (jsonObject == null || !"OK".equals(jsonObject.getStr("info"))) {
                log.debug("gaode_地理编码接口返回失败，url：{}, response：{}", url, response);
                return null;
            }
            JSONObject regeocode = jsonObject.getJSONObject("regeocode");
            if (regeocode == null) {
                return null;
            }
            JSONObject addressComponent = regeocode.getJSONObject("addressComponent");
            if (addressComponent == null) {
                return null;
            }
            return addressComponent.getStr("adcode");
        } catch (Exception e) {
            log.error("gaode_地理编码请求异常，url：{}", url, e);
            return null;
        }
    }

    /**
     * 根据 adcode 调用高德天气 API 获取实时天气
     */
    private String getWeatherByAdCode(String adCode) {
        String url = String.format(GAODE_WEATHER_API, getGaoDeKey(), adCode);
        try {
            String response = HttpUtil.get(url);
            if (StrUtil.isEmpty(response)) {
                log.debug("gaode_天气接口返回空，adCode：{}", adCode);
                return null;
            }
            JSONObject weatherObject = JsonUtils.parseObject(response, JSONObject.class);
            if (weatherObject == null) {
                log.debug("gaode_天气接口返回非 JSON，adCode：{}", adCode);
                return null;
            }
            // 高德天气成功状态为 "1"
            if (!"1".equals(weatherObject.getStr("status"))) {
                log.debug("gaode_天气接口返回失败，adCode：{}, response：{}", adCode, response);
                return null;
            }
            JSONArray lives = weatherObject.getJSONArray("lives");
            if (lives == null || lives.isEmpty()) {
                log.debug("gaode_天气接口返回 lives 为空，adCode：{}", adCode);
                return null;
            }
            JSONObject firstLive = lives.getJSONObject(0);
            return firstLive.toString();
        } catch (Exception e) {
            log.error("gaode_天气请求异常，url：{}", url, e);
            return null;
        }
    }
}
