package cn.qinys.platform.mobile.service;

import cn.qinys.platform.entity.wishing.WishingTree;
import cn.qinys.platform.mobile.mapper.WishingTreeMapper;
import cn.qinys.platform.mobile.req.WishingTreeListReq;
import cn.qinys.platform.mobile.resp.WishingTreeListResp;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author lie tan
 * @description 许愿树服务实现
 * @date 2026-05-24 21:34
 **/
@Slf4j
@Service
public class WishTreeServiceImpl implements WishTreeService {

    @Resource
    private WishingTreeMapper wishingTreeMapper;

    private static final int EARTH_RADIUS = 6371000; // 地球半径（米）

    @Override
    public List<WishingTreeListResp> listNearbyTrees(WishingTreeListReq req) {


        // 查询所有启用的许愿树
        List<WishingTree> trees = wishingTreeMapper.selectList(
                new LambdaQueryWrapper<WishingTree>()
                        .eq(WishingTree::getIsActive, 1)
        );

        List<WishingTreeListResp> result = new ArrayList<>();
        for (WishingTree tree : trees) {
            int dist = haversine(
                    req.getLng().doubleValue(), req.getLat().doubleValue(),
                    tree.getLongitude().doubleValue(), tree.getLatitude().doubleValue()
            );

            WishingTreeListResp resp = new WishingTreeListResp();
            resp.setId(tree.getId());
            resp.setName(tree.getName());
            resp.setDescription(tree.getDescription());
            resp.setLongitude(tree.getLongitude());
            resp.setLatitude(tree.getLatitude());
            resp.setAddress(tree.getAddress());
            resp.setRadius(tree.getRadius());
            resp.setCoverImage(tree.getCoverImage());
            resp.setTotalWishes(tree.getTotalWishes());
            resp.setDistance(dist);
            resp.setIsInRange(dist <= (tree.getRadius() != null ? tree.getRadius() : 100));
            result.add(resp);
        }

        // 按距离排序，限制返回数量
        return result.stream()
                .sorted(Comparator.comparingInt(WishingTreeListResp::getDistance))
                .filter(it -> it.getDistance() <= req.getMaxDistance())
                .limit(req.getLimit())
                .collect(Collectors.toList());
    }

    @Override
    public WishingTreeListResp getTreeDetail(Long id) {
        WishingTree tree = wishingTreeMapper.selectById(id);
        if (tree == null) {
            return null;
        }
        WishingTreeListResp resp = new WishingTreeListResp();
        resp.setId(tree.getId());
        resp.setName(tree.getName());
        resp.setDescription(tree.getDescription());
        resp.setLongitude(tree.getLongitude());
        resp.setLatitude(tree.getLatitude());
        resp.setAddress(tree.getAddress());
        resp.setRadius(tree.getRadius());
        resp.setCoverImage(tree.getCoverImage());
        resp.setTotalWishes(tree.getTotalWishes());
        return resp;
    }

    /** Haversine 公式计算两点间距离（米） */
    private int haversine(double lng1, double lat1, double lng2, double lat2) {
        double dLat = Math.toRadians(lat2 - lat1);
        double dLng = Math.toRadians(lng2 - lng1);
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
                + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
                * Math.sin(dLng / 2) * Math.sin(dLng / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return (int) Math.round(EARTH_RADIUS * c);
    }
}
