package com.propertyManagement.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.propertyManagement.common.enums.IsEnableType;
import com.propertyManagement.common.utils.StringUtils;
import com.propertyManagement.common.core.page.TableDataInfo;
import com.propertyManagement.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.propertyManagement.business.domain.bo.WxCommunityBo;
import com.propertyManagement.business.domain.vo.WxCommunityVo;
import com.propertyManagement.business.domain.WxCommunity;
import com.propertyManagement.business.mapper.WxCommunityMapper;
import com.propertyManagement.business.service.IWxCommunityService;

import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 小区Service业务层处理
 *
 * @author liushuai
 * @date 2025-05-14
 */
@RequiredArgsConstructor
@Service
public class WxCommunityServiceImpl implements IWxCommunityService {

    private final WxCommunityMapper baseMapper;

    /**
     * 查询小区
     */
    @Override
    public WxCommunityVo queryById(Long communityId){
        return baseMapper.selectVoById(communityId);
    }

    @Override
    public WxCommunityVo queryByTargetLatAndTargetLon(double targetLat, double targetLon) {
        WxCommunityVo wxCommunityVo = new WxCommunityVo();
        double minDistance = Double.MAX_VALUE;

        LambdaQueryWrapper<WxCommunity> lqw = Wrappers.lambdaQuery();
        lqw.eq(WxCommunity::getIsEnable, IsEnableType.YES.getCode());
        List<WxCommunityVo> communityVoList = baseMapper.selectVoList(lqw);

        for (WxCommunityVo location : communityVoList) {
            double distance = calculateDistance(targetLat, targetLon, location.getLatitude(), location.getLongitude());

            if (distance < minDistance) {
                minDistance = distance;
                wxCommunityVo = location;
            }
        }
        return wxCommunityVo;
    }

    /**
     * 计算两个经纬度坐标之间的距离（单位：米）
     * 使用Haversine公式计算球面距离
     *
     * @param lat1 第一个点的纬度
     * @param lon1 第一个点的经度
     * @param lat2 第二个点的纬度
     * @param lon2 第二个点的经度
     * @return 两点之间的距离（米）
     */
    public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        final int R = 6371; // 地球半径（千米）

        double latDistance = Math.toRadians(lat2 - lat1);
        double lonDistance = Math.toRadians(lon2 - lon1);

        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
            + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
            * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);

        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        return R * c * 1000; // 转换为米
    }

    /**
     * 查询小区列表
     */
    @Override
    public TableDataInfo<WxCommunityVo> queryPageList(WxCommunityBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<WxCommunity> lqw = buildQueryWrapper(bo);
        Page<WxCommunityVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询小区列表
     */
    @Override
    public List<WxCommunityVo> queryList(WxCommunityBo bo) {
        LambdaQueryWrapper<WxCommunity> lqw = buildQueryWrapper(bo);
        lqw.eq(WxCommunity::getIsEnable, IsEnableType.YES.getCode());
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<WxCommunity> buildQueryWrapper(WxCommunityBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<WxCommunity> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getCommunityName()), WxCommunity::getCommunityName, bo.getCommunityName());
        lqw.eq(bo.getIsEnable() != null, WxCommunity::getIsEnable, bo.getIsEnable());
        return lqw;
    }

    /**
     * 新增小区
     */
    @Override
    public Boolean insertByBo(WxCommunityBo bo) {
        WxCommunity add = BeanUtil.toBean(bo, WxCommunity.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setCommunityId(add.getCommunityId());
        }
        return flag;
    }

    /**
     * 修改小区
     */
    @Override
    public Boolean updateByBo(WxCommunityBo bo) {
        WxCommunity update = BeanUtil.toBean(bo, WxCommunity.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(WxCommunity entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除小区
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
