package com.ltgk.port.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.ltgk.common.constant.CacheConstants;
import com.ltgk.common.core.redis.RedisCache;
import com.ltgk.common.enums.DsMainAreaMarkTypeEnums;
import com.ltgk.port.domain.dto.XYCoordinate;
import com.ltgk.port.domain.entity.DsMainArea;
import com.ltgk.port.domain.vo.ParkedAreaForAppVO;
import com.ltgk.port.mapper.DsMainAreaMapper;
import com.ltgk.port.service.IDsMainAreaService;
import com.ltgk.system.domain.vo.DsDynamicRadarVO;
import com.ltgk.system.service.DynamicDataService;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * 重点区域信息/电子围栏/功能区划Service业务层处理
 *
 * @author Qi ChengBin
 * @date 2024-12-10
 */
@Service
public class DsMainAreaServiceImpl extends ServiceImpl<DsMainAreaMapper, DsMainArea> implements IDsMainAreaService {

    @Resource
    private DynamicDataService dynamicDataService;
    @Resource
    private RedisCache redisCache;

    /**
     * 移动端获取停泊区域数据
     *
     * @return com.ltgk.common.core.domain.AjaxResult
     * @author Qi ChengBin
     * @date 2025/5/21
     */
    @Override
    public List<ParkedAreaForAppVO> findParkedAreaListForApp() {
        // 查询所有的 停泊区域
        List<DsMainArea> parkedAreaList = this.lambdaQuery()
                .eq(DsMainArea::getMarkType, DsMainAreaMarkTypeEnums.PORT.getCode())
                .eq(DsMainArea::getBeShow, 1)
                .list();
        if (CollectionUtils.isEmpty(parkedAreaList)) {
            return Collections.emptyList();
        }

        return parkedAreaList.stream()
                .map(parkedArea -> {
                    ParkedAreaForAppVO parkedAreaForAppVO = new ParkedAreaForAppVO();
                    parkedAreaForAppVO.setPortName(parkedArea.getPortName())
                            .setParkedAreaName(parkedArea.getMarkName())
                            .setFillColor(parkedArea.getFillColor())
                            .setStrokeWidth(parkedArea.getLineWidth())
                            .setStrokeColor(parkedArea.getLineColor())
                            .setCenter(this.assembledCenter(parkedArea))
                            .setPoints(this.assembledPointList(parkedArea))
                            .setDiaphaneity(Double.parseDouble(parkedArea.getDiaphaneity()) * 100.00)
                            .setMaxBoatCount(parkedArea.getMaxBoatCount())
                            // 泊区当前停靠渔船数量  利用当前泊区的
                            .setNowBoatCount(this.getParkedAreaBoatNum(parkedArea.getPositionInfo()))
                    ;
                    return parkedAreaForAppVO;
                }).collect(Collectors.toList());
    }

    /**
     * 根据泊区的范围，计算泊区内现停了多少船
     *
     * @param positionInfo:泊区经纬度范围 x y 的形式
     * @return java.lang.String
     * @author Qi ChengBin
     * @date 2025/5/22
     */
    @Override
    public String getParkedAreaBoatNum(String positionInfo) {
        List<GeoResult<RedisGeoCommands.GeoLocation<String>>> dynamicList = null;
        try {
            dynamicList = dynamicDataService.getDynamicCountByRegion(positionInfo, 1);
        } catch (JsonProcessingException e) {
            log.error("获取区域内 redis 中缓存的 geo 数据个数失败:" + e);
            return "0";
        }
        if (CollectionUtils.isEmpty(dynamicList)) {
            return "0";
        }
        Set<String> resSet = new HashSet<>();
        dynamicList.forEach(item -> {
            // 获取缓存的名字用来获取 缓存的信息
            String cacheName = item.getContent().getName();
            if (ObjectUtils.isNotEmpty(cacheName)) {
                Object cacheObject = redisCache.getCacheObject(CacheConstants.TERMINAL_KEY + "-" + cacheName);
                if (ObjectUtils.isNotEmpty(cacheObject)) {
                    String boatInfo = cacheObject.toString();
                    if (ObjectUtils.isNotEmpty(boatInfo)) {
                        // 获取了redis 中在线的数据； 去除单纯的雷达数据，类型为 雷达，没有mmsi ，
                        DsDynamicRadarVO boatDynamicData = JSON.parseObject(cacheObject.toString(), DsDynamicRadarVO.class);
                        // 根据信息获取渔船数据
                        if (ObjectUtils.isNotEmpty(boatDynamicData)) {
                            // 去除雷达的 没有 mmsi 数据的值
                            if (StringUtils.isNotBlank(boatDynamicData.getMmsi()) && !boatDynamicData.getMmsi().equals("0")) {
                                resSet.add(boatDynamicData.getMmsi());
                            }
                        }
                    }
                }
            }
        });
        return String.valueOf(resSet.size());
    }

    /**
     * 根据泊区位置组装中心点位置
     *
     * @param parkedArea:
     * @return com.ltgk.port.domain.vo.ParkedAreaForAppVO.Point
     * @author Qi ChengBin
     * @date 2025/5/21
     */
    @Override
    public ParkedAreaForAppVO.Point assembledCenter(DsMainArea parkedArea) {
        List<XYCoordinate> xyCoordinateList = JSONUtil.toList(parkedArea.getPositionInfo(), XYCoordinate.class);

        // 使用Stream计算所有坐标的中心点
        // 经度
        double longitude = xyCoordinateList.stream()
                .collect(Collectors.averagingDouble(XYCoordinate::getX));
        // 纬度
        double latitude = xyCoordinateList.stream()
                .collect(Collectors.averagingDouble(XYCoordinate::getY));

        // 创建 GeometryFactory 实例
//        GeometryFactory geometryFactory = new GeometryFactory();
//
//        // 创建 Coordinate 对象
//        Coordinate coordinate = new Coordinate(longitude, latitude);

        // 创建 Point 对象
        return new ParkedAreaForAppVO.Point()
                .setLatitude(latitude)
                .setLongitude(longitude)
                ;
    }

    /**
     * 根据泊区位置组装移动端所需的范围列表
     *
     * @param parkedArea:
     * @return java.util.List<com.ltgk.port.domain.vo.ParkedAreaForAppVO.Point>
     * @author Qi ChengBin
     * @date 2025/5/21
     */
    private List<ParkedAreaForAppVO.Point> assembledPointList(DsMainArea parkedArea) {
        List<XYCoordinate> xyCoordinateList = JSONUtil.toList(parkedArea.getPositionInfo(), XYCoordinate.class);
        return xyCoordinateList.stream()
                .map(xyCoordinate ->
//                {
//                    // 创建 GeometryFactory 实例
//                    GeometryFactory geometryFactory = new GeometryFactory();
//
//                    // 创建 Coordinate 对象
//                    Coordinate coordinate = new Coordinate(xyCoordinate.getX(), xyCoordinate.getY());
//
//                    // 创建 Point 对象
//                    return geometryFactory.createPoint(coordinate);
                                new ParkedAreaForAppVO.Point()
                                        .setLatitude(xyCoordinate.getY())
                                        .setLongitude(xyCoordinate.getX())
//                }
                ).collect(Collectors.toList());
    }
}
