package com.ghy.shop.service.impl;

import com.ghy.shop.domain.Shop;
import com.ghy.shop.domain.ShopDistanceQuery;
import com.ghy.shop.mapper.ShopMapper;
import com.ghy.shop.service.ShopService;
import com.ghy.common.utils.LocationUtils;
import com.ghy.common.utils.BaiduMapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.HashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Service
public class ShopServiceImpl implements ShopService {
    private static final Logger logger = LoggerFactory.getLogger(ShopServiceImpl.class);

    @Autowired
    private ShopMapper shopMapper;
    
    @Autowired
    private BaiduMapUtils baiduMapUtils;

    @Override
    public int addShop(Shop shop) {
        return shopMapper.insert(shop);
    }

    @Override
    public int updateShop(Shop shop) {
        return shopMapper.update(shop);
    }

    @Override
    public int deleteShop(Long shopId) {
        return shopMapper.delete(shopId);
    }

    @Override
    public Shop getShop(Long shopId) {
        return shopMapper.select(shopId);
    }

    @Override
    public List<Shop> listShops() {
        return shopMapper.selectAll();
    }

    @Override
    public List<Shop> getShopsByWorkerId(Long workerId) {
        return shopMapper.selectShopsByWorkerId(workerId);
    }
    
    @Override
    public Shop getShopWithDistance(ShopDistanceQuery query) {
        // 获取店铺基本信息
        Shop shop = shopMapper.select(query.getShopId());
        if (shop == null) {
            return null;
        }
        
        // 计算距离
        double distance = calculateDistance(shop, query);
        
        // 设置距离信息
        if (distance >= 0) {
            shop.setDistance(LocationUtils.formatDistance(distance * 1000)); // 转换为米并格式化
        } else {
            shop.setDistance("无法计算距离");
        }
        
        return shop;
    }
    
    /**
     * 计算店铺与指定坐标的距离
     * 实现逻辑：
     * 1. 传入的详细地址 → 转换为经纬度（作为用户当前位置）
     * 2. 店铺有经纬度 → 直接使用
     * 3. 店铺没有经纬度 → 通过详细地址生成经纬度
     * 4. 最终计算用户位置与店铺位置的距离
     */
    private double calculateDistance(Shop shop, ShopDistanceQuery query) {
        Double userLat = null;
        Double userLng = null;
        Double shopLat = null;
        Double shopLng = null;
        
        // 1. 获取用户当前位置（优先使用传入的经纬度，其次使用传入地址转换的经纬度）
        if (query.hasCoordinateInfo()) {
            // 直接使用传入的经纬度作为用户位置
            userLat = query.getLatitude();
            userLng = query.getLongitude();
            logger.info("使用传入的经纬度作为用户位置: 经度={}, 纬度={}", userLng, userLat);
        } else if (query.hasAddressInfo()) {
            // 通过传入的地址信息生成用户位置的经纬度
            try {
                Map<String, Double> coordinates = baiduMapUtils.getCoordinatesByAddress(
                    query.getProvinceName(), query.getCityName(), 
                    query.getCountryName(), query.getStreetName(), query.getAddress()
                );
                if (coordinates != null) {
                    userLat = coordinates.get("latitude");
                    userLng = coordinates.get("longitude");
                    logger.info("通过传入地址成功生成用户位置经纬度: 经度={}, 纬度={}", userLng, userLat);
                }
            } catch (Exception e) {
                logger.warn("通过传入地址生成用户位置经纬度失败: {}", e.getMessage());
            }
        }
        
        // 2. 获取店铺位置（优先使用店铺已有的经纬度，其次使用店铺地址生成的经纬度）
        if (shop.getLatitude() != null && shop.getLongitude() != null) {
            shopLat = shop.getLatitude();
            shopLng = shop.getLongitude();
            logger.info("使用店铺已有的经纬度: 经度={}, 纬度={}", shopLng, shopLat);
        } else if (shop.getAddress() != null && !shop.getAddress().trim().isEmpty()) {
            // 通过店铺的地址信息生成经纬度
            try {
                Map<String, Double> coordinates = baiduMapUtils.getCoordinatesByAddress(
                    shop.getProvinceName(), shop.getCityName(), 
                    shop.getCountryName(), shop.getStreetName(), shop.getAddress()
                );
                if (coordinates != null) {
                    shopLat = coordinates.get("latitude");
                    shopLng = coordinates.get("longitude");
                    logger.info("通过店铺地址成功生成经纬度: 经度={}, 纬度={}", shopLng, shopLat);
                    
                    // 更新店铺的经纬度信息
                    shop.setLatitude(shopLat);
                    shop.setLongitude(shopLng);
                    
                    // 如果请求更新店铺位置信息，则保存到数据库
                    if (query.getUpdateShopLocation() != null && query.getUpdateShopLocation()) {
                        shopMapper.update(shop);
                        logger.info("已更新并保存店铺[{}]的经纬度: 经度={}, 纬度={}", 
                                   shop.getShopName(), shopLng, shopLat);
                    }
                }
            } catch (Exception e) {
                logger.warn("通过店铺地址生成经纬度失败: {}", e.getMessage());
            }
        }
        
        // 3. 计算用户位置与店铺位置的距离
        if (userLat != null && userLng != null && shopLat != null && shopLng != null) {
            // 有用户位置和店铺位置，计算距离
            double distance = LocationUtils.getDistanceInKilometers(userLat, userLng, shopLat, shopLng);
            logger.info("成功计算用户位置与店铺位置的距离: {} 公里", distance);
            return distance;
        } else if (shopLat != null && shopLng != null) {
            // 只有店铺位置，没有用户位置，无法计算距离
            logger.info("已获取店铺位置，但未获取到用户位置，无法计算距离");
            return 0; // 返回0表示成功获取店铺位置但无法计算距离
        } else {
            // 无法获取店铺位置，返回-1表示无效
            logger.warn("无法获取店铺[{}]的经纬度信息，无法计算距离", shop.getShopName());
            return -1;
        }
    }
} 