package com.xxfc.platform.campsite.biz;

import cn.hutool.core.bean.BeanUtil;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.xxfc.platform.campsite.CampSiteApplication;
import com.xxfc.platform.campsite.dto.CampsiteShopCarouselDTO;
import com.xxfc.platform.campsite.dto.CampsiteShopCarouselDetailDTO;
import com.xxfc.platform.campsite.dto.CampsiteShopDetailDTO;
import com.xxfc.platform.campsite.dto.CampsiteShopPageDTO;
import com.xxfc.platform.campsite.vo.CampsiteShopCarouselDetailVo;
import com.xxfc.platform.campsite.vo.CampsiteShopDetailVo;
import com.xxfc.platform.campsite.vo.CampsiteShopPageVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xxfc.platform.campsite.entity.CampsiteShop;
import com.xxfc.platform.campsite.mapper.CampsiteShopMapper;
import com.github.wxiaoqi.security.common.biz.BaseBiz;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 营地店铺表
 *
 * @author libin
 * @email 18178966185@163.com
 * @date 2019-06-17 10:28:48
 */
@Service
@Slf4j
public class CampsiteShopBiz extends BaseBiz<CampsiteShopMapper,CampsiteShop> {
     /**
     * 地球半径,单位 km
     */
     private static final double EARTH_RADIUS = 6378.137;

       @Autowired
       private CampsiteShopTagBiz campsiteShopTagBiz;

       @Autowired
       private CampsiteShopCarouselBiz campsiteShopCarouselBiz;

    /**
     * 根据店铺类型查找列表
     * @param type
     * @return
     */
    public PageDataVO<CampsiteShopPageVo> findCampsiteShopPageByType(Integer type,Integer pageNo,Integer pageSize) {
         //根据type类型查找店铺
        PageDataVO<CampsiteShopPageDTO> pageDataVO = PageDataVO.pageInfo(pageNo, pageSize, () -> mapper.findCampsiteShopsByType(type));
        List<CampsiteShopPageDTO> campsiteShopPageDTOS = pageDataVO.getData();

        PageDataVO<CampsiteShopPageVo> campsiteShopPageDataVO = new PageDataVO<>();
        campsiteShopPageDataVO.setTotalPage(pageDataVO.getTotalPage());
        campsiteShopPageDataVO.setTotalCount(pageDataVO.getTotalCount());
        campsiteShopPageDataVO.setPageSize(pageDataVO.getPageSize());
        campsiteShopPageDataVO.setPageNum(pageDataVO.getPageNum());
        if (CollectionUtils.isEmpty(campsiteShopPageDTOS)){
            return  campsiteShopPageDataVO;
        }
        if (log.isDebugEnabled()){
            log.debug("根据type=【{}】查询到的店铺数据：【{}】",type,campsiteShopPageDTOS);
        }
        List<CampsiteShopPageVo> campsiteShopPageVoList = new ArrayList<>();
        for (CampsiteShopPageDTO campsiteShopPageDTO : campsiteShopPageDTOS) {
            CampsiteShopPageVo campsiteShopPageVo = new CampsiteShopPageVo();
            BeanUtils.copyProperties(campsiteShopPageDTO,campsiteShopPageVo);
            campsiteShopPageVoList.add(campsiteShopPageVo);
        }
        campsiteShopPageDataVO.setData(campsiteShopPageVoList);
        return campsiteShopPageDataVO;
    }

    /**
     * 根据店铺id查询店铺详情
     * @param id
     * @return
     */
    public CampsiteShopDetailVo findCampsiteShopDetailById(Integer id,Double longitude,Double latitude) {

        CampsiteShopDetailVo campsiteShopDetailVo = new CampsiteShopDetailVo();

        //从店铺表根据店铺id查询
          CampsiteShopDetailDTO  campsiteShopDetailDTO = mapper.findCampsiteShopDetailById(id);
          if (log.isDebugEnabled()){
              log.debug("根据店铺id=【{}】查询出店铺信息【{}】",id,campsiteShopDetailDTO);
          }
          BeanUtils.copyProperties(campsiteShopDetailDTO,campsiteShopDetailVo);
         //从轮播表根据店铺id查询
         List<CampsiteShopCarouselDetailDTO> campsiteShopCarouselDTOS  = campsiteShopCarouselBiz.findByCampsiteShopId(id);
         if (log.isDebugEnabled()){
             log.debug("根据店铺id=【{}】查询出店铺轮播图信息：【{}】",id,campsiteShopCarouselDTOS);
         }
         List<CampsiteShopCarouselDetailVo> campsiteShopCarouselDetailVos = new ArrayList<>();
        campsiteShopCarouselDTOS.forEach(campsiteShopCarouselDetailDTO -> {
             CampsiteShopCarouselDetailVo  carouselDetailVo  = new CampsiteShopCarouselDetailVo();
             BeanUtils.copyProperties(campsiteShopCarouselDetailDTO,carouselDetailVo);
            campsiteShopCarouselDetailVos.add(carouselDetailVo);
        });
         campsiteShopDetailVo.setCampsiteShopCarouselDetailVos(campsiteShopCarouselDetailVos);
         //从店铺类型表根据店铺id查询 -->类型列表拼接
         List<String> typeNameList = campsiteShopTagBiz.findByCampsiteShopId(id);
         if (log.isDebugEnabled()){
             log.debug("根据店铺id=【{}】查询出店铺类型:【{}】",id,typeNameList);
         }
         campsiteShopDetailVo.setTypeNames(typeNameList);
        //根据经纬度算距离
         double distance = getDistance(campsiteShopDetailDTO.getLongitude(),campsiteShopDetailDTO.getLatitude(),longitude,latitude);
         if (log.isDebugEnabled()){
             log.debug("根据店铺经度=【{}】,纬度=【{}】和自己所在位置的经度=【{}】,纬度=【{}】计算出的距离：【{}km】",campsiteShopDetailDTO.getLongitude(),campsiteShopDetailDTO.getLatitude(),longitude,latitude,distance);
         }
         campsiteShopDetailVo.setDistance(String.format("%.1f",distance));
        return  campsiteShopDetailVo;
    }

    /**
     * 根据经纬度，计算两点间的距离
     *
     * @param longitude1 第一个点的经度
     * @param latitude1  第一个点的纬度
     * @param longitude2 第二个点的经度
     * @param latitude2  第二个点的纬度
     * @return 返回距离 单位千米
     */
    private static double getDistance(double longitude1, double latitude1, double longitude2, double latitude2) {
        // 纬度
        double lat1 = Math.toRadians(latitude1);
        double lat2 = Math.toRadians(latitude2);
        // 经度
        double lng1 = Math.toRadians(longitude1);
        double lng2 = Math.toRadians(longitude2);
        // 纬度之差
        double a = lat1 - lat2;
        // 经度之差
        double b = lng1 - lng2;
        // 计算两点距离的公式
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));
        // 弧长乘地球半径, 返回单位: 千米
        s =  s * EARTH_RADIUS;
        return s;
    }
}