package cn.reghao.tnb.content.app.geo.service;

import cn.reghao.jutil.jdk.converter.DateTimeConverter;
import cn.reghao.tnb.common.auth.UserContext;
import cn.reghao.tnb.content.app.geo.db.mapper.*;
import cn.reghao.tnb.content.app.geo.model.po.BusStation;
import cn.reghao.tnb.content.app.geo.model.po.GeoChina;
import cn.reghao.tnb.content.app.geo.model.po.GeoPoint;
import cn.reghao.tnb.content.app.geo.model.po.GeoPolygon;
import cn.reghao.tnb.content.app.geo.model.vo.GeoMarker;
import cn.reghao.tnb.content.app.geo.model.vo.MapMarker;
import cn.reghao.tnb.content.app.geo.model.vo.MapPoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2023-08-31 17:49:48
 */
@Slf4j
@Service
public class MapService {
    private final GeoChinaMapper geoChinaMapper;
    private final GeoPolygonMapper geoPolygonMapper;
    private final GeoPointMapper geoPointMapper;
    private final BusStationMapper busStationMapper;

    public MapService(GeoChinaMapper geoChinaMapper, GeoPolygonMapper geoPolygonMapper,
                      GeoPointMapper geoPointMapper, BusStationMapper busStationMapper) {
        this.geoChinaMapper = geoChinaMapper;
        this.geoPolygonMapper = geoPolygonMapper;
        this.geoPointMapper = geoPointMapper;
        this.busStationMapper = busStationMapper;
    }

    @Transactional(rollbackFor = Exception.class)
    public void add(GeoChina geoChina, GeoPolygon geoPolygon) {
        try {
            //geoChinaMapper.save(geoChina);
            geoPolygonMapper.save(geoPolygon);
        } catch (Exception e) {
            log.info("insert {} -> {} error", geoChina.getId(), geoChina.getExtName());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    public void addGeoPoint(MapPoint mapPoint) {
        GeoPoint geoPoint = new GeoPoint(mapPoint);
        geoPointMapper.save(geoPoint);
    }

    public List<MapMarker> getCityMarks() {
        int deep = 2;
        List<GeoMarker> list = geoChinaMapper.findByDeep(deep);
        return list.stream().map(geoMarker -> {
            String id = String.valueOf(geoMarker.getId());
            String name = geoMarker.getName();
            double lng = geoMarker.getLng();
            double lat = geoMarker.getLat();
            MapPoint mapPoint = new MapPoint(lng, lat);
            return new MapMarker(id, name, mapPoint);
        }).collect(Collectors.toList());
    }

    public List<MapMarker> getTrailMarks() {
        long userId = UserContext.getUserId();
        List<GeoPoint> list = geoPointMapper.findByUserId(userId);
        return list.stream().map(geoPoint -> {
            String id = String.valueOf(geoPoint.getId());
            String dateStr = DateTimeConverter.format(geoPoint.getCreateAt());
            double lng = geoPoint.getLongitude().doubleValue();
            double lat = geoPoint.getLatitude().doubleValue();
            MapPoint mapPoint = new MapPoint(lng, lat);
            return new MapMarker(id, dateStr, mapPoint);
        }).collect(Collectors.toList());
    }

    public List<MapMarker> getStationMarks() {
        List<BusStation> list = busStationMapper.findAll();
        return list.stream().map(busStation -> {
            String id = busStation.getId()+"";
            String stationName = busStation.getStationName();
            String latStr = String.valueOf(busStation.getLat());
            String latStr1 = String.format("%s.%s", latStr.substring(0, 2), latStr.substring(2));
            double lat = Double.parseDouble(latStr1);

            String lngStr = String.valueOf(busStation.getLng());
            String lngStr1 = String.format("%s.%s", lngStr.substring(0, 3), lngStr.substring(3));
            double lng = Double.parseDouble(lngStr1);
            MapPoint mapPoint = new MapPoint(lng, lat);
            return new MapMarker(id, stationName, mapPoint);
        }).collect(Collectors.toList());
    }

    public List getTrailPath() {
        long userId = UserContext.getUser();
        List<GeoPoint> list = geoPointMapper.findByUserId(userId);
        List<List<Double>> list1 = list.stream().map(geoPoint -> {
            Double lng = geoPoint.getLongitude().doubleValue();
            Double lat = geoPoint.getLatitude().doubleValue();
            return List.of(lng, lat);
        }).collect(Collectors.toList());

        Map<String, List<List<Double>>> map = new HashMap<>();
        map.put("path", list1);
        return List.of(map);
    }
}
