package org.dromara.main.service.impl;

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.core.exception.ServiceException;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.main.config.TencentMapGeoProperties;
import org.dromara.main.domain.dto.GeoPointDto;
import org.dromara.main.service.CompanyGeoService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 基于腾讯位置服务地址解析接口，将地址转换为经纬度。
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TencentMapCompanyGeoServiceImpl implements CompanyGeoService {

    private final TencentMapGeoProperties tencentMapGeoProperties;

    @Override
    public GeoPointDto geocode(String address) {
        if (StringUtils.isBlank(address)) {
            throw new ServiceException("办公地址不能为空");
        }
        if (StringUtils.isBlank(tencentMapGeoProperties.getKey())) {
            throw new ServiceException("未配置腾讯地图地理编码 Key");
        }

        Map<String, Object> params = new HashMap<>(4);
        params.put("key", tencentMapGeoProperties.getKey());
        params.put("address", address.trim());
        params.put("output", "json");

        try {
            String response = HttpUtil.get(tencentMapGeoProperties.getGeocodeUrl(), params);
            JSONObject result = JSONUtil.parseObj(response);
            Integer status = result.getInt("status");
            if (status == null || status != 0) {
                String message = result.getStr("message");
                log.error("腾讯地图地理编码失败，address={}, status={}, message={}", address, status, message);
                throw new ServiceException(StringUtils.format("地址解析失败: {}", StringUtils.blankToDefault(message, "腾讯地图接口调用失败")));
            }

            JSONObject resultNode = result.getJSONObject("result");
            JSONObject location = resultNode == null ? null : resultNode.getJSONObject("location");
            if (location == null) {
                throw new ServiceException("地址解析失败: 未匹配到经纬度，请检查办公地址");
            }

            BigDecimal latitude = BigDecimal.valueOf(location.getDouble("lat"));
            BigDecimal longitude = BigDecimal.valueOf(location.getDouble("lng"));
            return new GeoPointDto(latitude, longitude);
        } catch (ServiceException ex) {
            throw ex;
        } catch (Exception ex) {
            log.error("调用腾讯地图地理编码接口异常，address={}", address, ex);
            throw new ServiceException("地址解析失败，请稍后重试");
        }
    }
}
