package com.qiuguo.iot.third.service;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.qiuguo.iot.base.utils.StringUtils;
import com.qiuguo.iot.base.utils.WebClientUtils;
import com.qiuguo.iot.data.request.third.ThirdWeatherInfoRequest;
import com.qiuguo.iot.data.resp.third.ThirdIpInfoResp;
import com.qiuguo.iot.data.resp.third.ThirdRpcResp;
import com.qiuguo.iot.data.resp.third.weather.TianqiapiResp;
import com.qiuguo.iot.data.resp.third.weather.WeatherResp;
import com.qiuguo.iot.third.enums.WeatherEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.CoreSubscriber;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.util.annotation.Nullable;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.regex.Pattern;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

/**
 * @author simon
 * @date 2023/9/21
 * @description 天气服务
 **/

@Service
@Slf4j
@Validated
public class WeatherService {
    //101.6656,39.2072/hourly?hourlysteps=1
    //101.6656,39.2072/daily?dailysteps=1
    @Value("https://api.caiyunapp.com/v2.6/ilUeAnf1vNkphxYS/")
    private String queryWeatherUrl;



    @Resource
    private IpService ipService;

    /**
     *
     * @return
     */
    public Mono<WeatherResp> queryWeather(ThirdWeatherInfoRequest req) {
        if (req.getType() < WeatherEnum.QUERY_TYPE_1.getCode() || req.getType() > WeatherEnum.QUERY_TYPE_2.getCode()) {
            req.setType(WeatherEnum.QUERY_TYPE_1.getCode());
        }
        if (req.getSize() < WeatherEnum.QUERY_MIN_SIZE.getCode()) {
            req.setSize(WeatherEnum.QUERY_MIN_SIZE.getCode());
        }
        //小时查询最大360小时
        if (req.getType().equals(WeatherEnum.QUERY_TYPE_1.getCode()) && req.getSize() > WeatherEnum.QUERY_HOUR_MAX_SIZE.getCode()) {
            req.setSize(WeatherEnum.QUERY_HOUR_MAX_SIZE.getCode());
        }
        //按天查询最多15天
        if (req.getType().equals(WeatherEnum.QUERY_TYPE_2.getCode()) && req.getSize() > WeatherEnum.QUERY_DAY_MAX_SIZE.getCode()) {
            req.setSize(WeatherEnum.QUERY_DAY_MAX_SIZE.getCode());
        }


        Mono<ThirdWeatherInfoRequest> lngLatMono = Mono.empty();

        //如果经纬度为空，通过ip获取经纬度
        if (ObjectUtils.isEmpty(req.getLng()) || ObjectUtils.isEmpty(req.getLat())) {
            if (ObjectUtils.isEmpty(req.getIp())) {
                throw new RuntimeException("ip经纬度不能同时为空");
            }
            boolean matches = Pattern.matches("^([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}$", req.getIp());
            if (!matches) {
                throw new RuntimeException("ip格式不正确");
            }

            lngLatMono = ipService.getIpInfo(req.getIp()).flatMap(resp -> {
                if (!resp.getCode().equals(HttpStatus.OK.value())) {
                    return Mono.error(new RuntimeException("ip服务查询失败:" + resp.getMsg() + " " + resp.getCode()));
                }
                if (ObjectUtils.isEmpty(resp.getData().getLng()) || ObjectUtils.isEmpty(resp.getData().getLat())) {
                    return Mono.error(new RuntimeException("当前ip查询失败:" + req.getIp()));
                }
                req.setLng(resp.getData().getLng().toString());
                req.setLat(resp.getData().getLat().toString());
                return Mono.just(req);
            });

        } else {
            lngLatMono = Mono.just(req);
        }

        return thirdQueryWeather(lngLatMono, req.getType(), req.getSize());
    }

    public Mono<WeatherResp> thirdQueryWeather(Mono<ThirdWeatherInfoRequest> lngLatMono, Integer queryType, Integer querySize) {
        //WebClient webClient =  WebClient.builder().build();

        return lngLatMono.flatMap(r -> {
            if (queryType.equals(WeatherEnum.QUERY_TYPE_1.getCode())) {
                queryWeatherUrl = queryWeatherUrl + r.getLng().toString() + "," + r.getLat().toString() +  "/hourly?hourlysteps=" + querySize;
            } else {
                queryWeatherUrl = queryWeatherUrl + r.getLng().toString() + "," + r.getLat().toString() +  "/daily?dailysteps=" + querySize;
            }

            return WebClientUtils.get(queryWeatherUrl).map(jsonObject -> {
                return jsonObject.toJavaObject(WeatherResp.class);
            });
            //return webClient.get().uri(queryWeatherUrl).retrieve().bodyToMono(WeatherResp.class);
        });
    }

    public Mono<TianqiapiResp> tianqiApi(ThirdWeatherInfoRequest req){
        //WebClient webClient =  WebClient.builder().build();
        String url = SpringUtil.getProperty("tianqiapi.url");
        if(StringUtils.isNotEmpty(req.getIp())){
            url += "&ip=" + req.getIp();
        }else{
            url += "&city=" + req.getCity();
        }
        return WebClientUtils.get(url).map(jsonObject -> {
            return jsonObject.toJavaObject(TianqiapiResp.class);
        });
    }
}
