const axios = require('axios');
const config = require('../../config/config');




/**
 * 地理位置服务
 */
class LocationService {
    /**
     * 根据经纬度获取地址信息
     * @param {number} latitude 纬度
     * @param {number} longitude 经度
     * @returns {Promise<Object>} 地址信息
     */
    async getAddressByLocation(latitude, longitude) {
        try {
            const url = `https://apis.map.qq.com/ws/geocoder/v1/?location=${latitude},${longitude}&key=${config.qq_map_key}`;
            const response = await axios.get(url);

            if (response.data.status !== 0) {
                throw new Error('地理位置解析失败, ' + response.data.message);
            }

            let addressComponent = response.data.result.address_component
            let formatAddress = this.formatAddressInfo(addressComponent)



            return formatAddress;

        } catch (error) {

            throw error;
        }
    }

    /**
     * 根据地址获取经纬度
     * @param {string} address 地址
     * @returns {Promise<Object>} 经纬度信息
     */
    async getLocationByAddress(address) {
            
 
            const url = `https://apis.map.qq.com/ws/geocoder/v1/?address=${encodeURIComponent(address)}&key=${config.qq_map_key}`;
            const response = await axios.get(url);

            if (response.data.status !== 0) {
                throw new Error('地址解析失败, ' + response.data.message);
            }

            let addressComponent = response.data.result.location
            return addressComponent;


      
    }

    /**
     * 计算两点之间的距离（公里）
     * @param {number} lat1 第一个点的纬度
     * @param {number} lng1 第一个点的经度
     * @param {number} lat2 第二个点的纬度
     * @param {number} lng2 第二个点的经度
     * @returns {number} 距离（公里）
     */
    calculateDistance(lat1, lng1, lat2, lng2) {
        const R = 6371; // 地球半径（公里）
        const dLat = this.toRadians(lat2 - lat1);
        const dLng = this.toRadians(lng2 - lng1);

        const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(this.toRadians(lat1)) * Math.cos(this.toRadians(lat2)) *
            Math.sin(dLng / 2) * Math.sin(dLng / 2);

        const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        const distance = R * c;

        return Math.round(distance * 100) / 100; // 保留两位小数
    }

    /**
     * 角度转弧度
     * @param {number} degrees 角度
     * @returns {number} 弧度
     */
    toRadians(degrees) {
        return degrees * (Math.PI / 180);
    }

    /**
     * 格式化地址信息
     * @param {Object} addressComponent 地址组件
     * @returns {Object} 格式化后的地址信息
     */
    formatAddressInfo(addressComponent) {
        // 处理省份名称，去掉"省"、"市"、"自治区"等后缀
        let province = addressComponent.province || '';
        province = province.replace(/省|市|自治区|特别行政区/g, '');

        // 处理城市名称，去掉"市"后缀
        let city = addressComponent.city || '';
        city = city.replace(/市/g, '');

        // 处理区县名称
        let district = addressComponent.district || '';

        // 检查是否为直辖市（北京、上海、天津、重庆）
        const municipalities = ['北京', '上海', '天津', '重庆'];
        const isMunicipality = municipalities.includes(province) ||
            municipalities.some(m => addressComponent.province && addressComponent.province.includes(m));

        // 如果是直辖市，调整省份和城市字段
        if (isMunicipality) {
            // 直辖市：province 保持为直辖市名称，city 设置为区名
            const municipalityName = municipalities.find(m =>
                province.includes(m) || (addressComponent.province && addressComponent.province.includes(m))
            ) || province;

            province = municipalityName;

            // 特殊处理：浦东新区、滨海新区等特殊区名，保持完整名称
            if (district.includes('新区') || district.includes('开发区') || district.includes('高新区')) {
                city = district; // 保持完整的区名作为城市（不去掉后缀）
                district = ''; // 清空区字段
            } else {
                // 普通区名去掉后缀后作为城市
                city = district.replace(/区|县/g, '');
                district = ''; // 清空区字段
            }
        } else {
            // 非直辖市，按正常逻辑处理
            district = district.replace(/区|县/g, '');
        }

        // 构建简化的地址格式：城市 区县
        let formatted_address = '';
        if (city && district) {
            formatted_address = `${city} ${district}`;
        } else if (city) {
            formatted_address = city;
        } else if (district) {
            formatted_address = district;
        } else if (province) {
            formatted_address = province;
        }

        return {
            province: province,
            city: city,
            district: district,
            street: addressComponent.street || '',
            street_number: addressComponent.street_number || '',
            formatted_address: formatted_address
        };
    }
}

module.exports = new LocationService();
