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.GeoChina;
import cn.reghao.tnb.content.app.geo.model.po.GeoPoint;
import cn.reghao.tnb.content.app.geo.model.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
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 GeoPointMapper geoPointMapper;
    private final List<CascadeOption> cascadeOptionList = new ArrayList<>();

    public MapService(GeoChinaMapper geoChinaMapper, GeoPointMapper geoPointMapper) {
        this.geoChinaMapper = geoChinaMapper;
        this.geoPointMapper = geoPointMapper;
    }

    public void add(GeoChina geoChina) {
        geoChinaMapper.save(geoChina);
    }

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

    public void setMyPosition(MapPoint mapPoint) {
        int pointType = 1;
        GeoPoint geoPoint = new GeoPoint(mapPoint, pointType);
        long loginUser = geoPoint.getCreateBy();
        List<GeoPoint> list = geoPointMapper.findByPositionType(loginUser, pointType);
        if (list.isEmpty()) {
            geoPointMapper.save(geoPoint);
        } else {
            geoPointMapper.updateUserPosition(geoPoint);
        }
    }

    public List<MapMarker> getTrailMarks() {
        List<GeoPoint> list = getMyGeoPoints();
        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 void addTrail(List<MapPoint> list) {
        List<GeoPoint> geoPointList = list.stream()
                .map(GeoPoint::new)
                .collect(Collectors.toList());
        if (!geoPointList.isEmpty()) {
            long loginUser = UserContext.getUserId();
            geoPointMapper.deleteByPositionType(loginUser, 2);
            geoPointMapper.saveAll(geoPointList);
        }
    }

    public List getTrailPath() {
        List<GeoPoint> list = getMyGeoPoints();
        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);
    }

    private List<GeoPoint> getMyGeoPoints() {
        long userId = UserContext.getUserId();
        List<GeoPoint> list = geoPointMapper.findByPositionType(userId, 2);
        return list;
    }

    /**
     * 省市县三级联动数据
     *
     * @param
     * @return
     * @date 2025-08-12 16:41:41
     */
    public List<CascadeOption> getChinaCascade() {
        if (!cascadeOptionList.isEmpty()) {
            return cascadeOptionList;
        }

        loadChinaCascade();
        return cascadeOptionList;
    }

    private void loadChinaCascade() {
        cascadeOptionList.clear();
        List<GeoArea> geoChinaList = geoChinaMapper.findAllArea();
        Map<Integer, List<GeoArea>> groupMap = geoChinaList.stream().collect(Collectors.groupingBy(GeoArea::getPid));
        int pid = 0;
        List<GeoArea> level1 = groupMap.get(pid);
        for (GeoArea  geoChina1 : level1) {
            if (geoChina1.getId() == 10) {
                continue;
            }

            CascadeOption cascadeOption1 = new CascadeOption();
            cascadeOption1.setLabel(geoChina1.getName());
            cascadeOption1.setValue(geoChina1.getId()+"");

            pid = geoChina1.getId();
            List<GeoArea> level2 = groupMap.get(pid);
            for (GeoArea geoChina2 : level2) {
                CascadeOption cascadeOption2 = new CascadeOption();
                cascadeOption2.setLabel(geoChina2.getName());
                cascadeOption2.setValue(geoChina2.getId()+"");

                pid = geoChina2.getId();
                List<GeoArea> level3 = groupMap.get(pid);
                for (GeoArea geoChina3 : level3) {
                    CascadeOption cascadeOption3 = new CascadeOption();
                    cascadeOption3.setLabel(geoChina3.getName());
                    cascadeOption3.setValue(geoChina3.getId()+"");

                    cascadeOption3.setChildren(null);
                    cascadeOption2.getChildren().add(cascadeOption3);
                }
                cascadeOption1.getChildren().add(cascadeOption2);
            }

            cascadeOptionList.add(cascadeOption1);
        }
    }
}
