package com.ruoyi.bst.areaSub.service.impl;

import java.util.Collections;
import java.util.List;

import org.locationtech.jts.geom.Geometry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.ruoyi.bst.areaSub.domain.AreaSub;
import com.ruoyi.bst.areaSub.domain.AreaSubQuery;
import com.ruoyi.bst.areaSub.domain.AreaSubVO;
import com.ruoyi.bst.areaSub.domain.enums.AreaSubStatus;
import com.ruoyi.bst.areaSub.domain.enums.AreaSubType;
import com.ruoyi.bst.areaSub.mapper.AreaSubMapper;
import com.ruoyi.bst.areaSub.service.AreaSubService;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.common.utils.map.GeoUtils;

/**
 * 子区域Service业务层处理
 *
 * @author ruoyi
 * @date 2025-03-15
 */
@Service
public class AreaSubServiceImpl implements AreaSubService
{
    @Autowired
    private AreaSubMapper areaSubMapper;

    @Autowired
    private RedisCache redisCache;

    /**
     * 查询子区域
     *
     * @param id 子区域主键
     * @return 子区域
     */
    @Override
    public AreaSubVO selectAreaSubById(Long id, boolean scope)
    {
        if (id == null) {
            return null;
        }
        AreaSubQuery query = new AreaSubQuery();
        query.setId(id);
        query.setScope(scope);
        return this.selectOne(query);
    }

    @Override
    public AreaSubVO selectOne(AreaSubQuery query) {
        PageHelper.startPage(1, 1);
        List<AreaSubVO> list = this.selectAreaSubList(query);
        return CollectionUtils.firstElement(list);
    }

    /**
     * 查询子区域列表
     *
     * @param areaSub 子区域
     * @return 子区域
     */
    @Override
    public List<AreaSubVO> selectAreaSubList(AreaSubQuery areaSub)
    {
        return areaSubMapper.selectAreaSubList(areaSub);
    }

    /**
     * 新增子区域
     *
     * @param areaSub 子区域
     * @return 结果
     */
    @Override
    public int insertAreaSub(AreaSub areaSub)
    {
        areaSub.setCreateTime(DateUtils.getNowDate());
        // 将边界值转Geometry对象
        if (areaSub.getBoundaryStr() != null) {
            Geometry geometry = GeoUtils.toGeometry(areaSub.getBoundaryStr());
            areaSub.setBoundary(GeoUtils.wkt(geometry));
        }
        int result = areaSubMapper.insertAreaSub(areaSub);

        if (result > 0) {
            this.clearCache(areaSub.getAreaId());
        }

        return result;
    }

    /**
     * 修改子区域
     *
     * @param areaSub 子区域
     * @return 结果
     */
    @Override
    public int updateAreaSub(AreaSub areaSub)
    {
        AreaSubVO old = selectAreaSubById(areaSub.getId());
        ServiceUtil.assertion(old == null, "ID为%s的待修改子区域不存在", areaSub.getId());

        // 将边界值转Geometry对象
        if (areaSub.getBoundaryStr() != null) {
            Geometry geometry = GeoUtils.toGeometry(areaSub.getBoundaryStr());
            areaSub.setBoundary(GeoUtils.wkt(geometry));
        }

        int result = areaSubMapper.updateAreaSub(areaSub);

        if (result > 0) {
            this.clearCache(old.getAreaId());
        }

        return result;
    }


    /**
     * 根据运营区ID查询子区域列表
     *
     * @param areaId 运营区ID
     * @return 子区域列表
     */
    @Override
    public List<AreaSubVO> selectAreaSubListByAreaId(Long areaId){
        if (areaId == null) {
            return Collections.emptyList();
        }
        AreaSubQuery query = new AreaSubQuery();
        query.setAreaId(areaId);
        return areaSubMapper.selectAreaSubList(query);
    }

    /**
     * 逻辑删除子区域
     * @param ids 子区域ID列表
     * @return 结果
     */
    @Override
    public int logicDel(List<Long> ids) {
        if (CollectionUtils.isEmptyElement(ids)) {
            return 0;
        }

        List<AreaSubVO> list = this.selectAreaSubByIds(ids);
        if (CollectionUtils.isEmptyElement(list)) {
            return 0;
        }

        // 删除数据库
        int result = areaSubMapper.logicDel(ids);

        // 删除缓存
        if (result > 0) {
            for (AreaSubVO areaSub : list) {
                this.clearCache(areaSub.getAreaId());
            }
        }

        return result;
    }

    private List<AreaSubVO> selectAreaSubByIds(List<Long> ids) {
        if (CollectionUtils.isEmptyElement(ids)) {
            return Collections.emptyList();
        }
        AreaSubQuery query = new AreaSubQuery();
        query.setIds(ids);
        return areaSubMapper.selectAreaSubList(query);
    }

    @Override
    public List<AreaSubVO> selectParkingAreaByAreaId(Long areaId) {
        if (areaId == null) {
            return Collections.emptyList();
        }
        String key = CacheConstants.PARKING_AREA_SUB_LIST + areaId;
        List<AreaSubVO> list = redisCache.getCacheObject(key);
        if (CollectionUtils.isEmptyElement(list)) {
            AreaSubQuery query = new AreaSubQuery();
            query.setAreaId(areaId);
            query.setStatus(AreaSubStatus.ENABLED.getCode());
            query.setType(AreaSubType.PARKING.getCode());
            list = areaSubMapper.selectAreaSubList(query);
            redisCache.setCacheObject(key, list);
        }
        return list;
    }

    @Override
    public List<AreaSubVO> selectNoRidingListByAreaId(Long areaId) {
        if (areaId == null) {
            return Collections.emptyList();
        }
        String key = CacheConstants.NO_RIDING_AREA_SUB_LIST + areaId;
        List<AreaSubVO> list = redisCache.getCacheObject(key);
        if (CollectionUtils.isEmptyElement(list)) {
            AreaSubQuery query = new AreaSubQuery();
            query.setAreaId(areaId);
            query.setStatus(AreaSubStatus.ENABLED.getCode());
            query.setType(AreaSubType.NO_RIDE.getCode());
            list = areaSubMapper.selectAreaSubList(query);
            redisCache.setCacheObject(key, list);
        }
        return list;
    }

    @Override
    public List<AreaSubVO> selectNoParkingAreaByAreaId(Long areaId) {
        if (areaId == null) {
            return Collections.emptyList();
        }
        String key = CacheConstants.NO_PARKING_AREA_SUB_LIST + areaId;
        List<AreaSubVO> list = redisCache.getCacheObject(key);
        if (CollectionUtils.isEmptyElement(list)) {
            AreaSubQuery query = new AreaSubQuery();
            query.setAreaId(areaId);
            query.setStatus(AreaSubStatus.ENABLED.getCode());
            query.setType(AreaSubType.NO_PARKING.getCode());
            list = areaSubMapper.selectAreaSubList(query);
            redisCache.setCacheObject(key, list);
        }
        return list;
    }

    private void clearCache(Long areaId) {
        if (areaId == null) {
            return;
        }
        redisCache.deleteObject(CacheConstants.NO_RIDING_AREA_SUB_LIST + areaId);
        redisCache.deleteObject(CacheConstants.PARKING_AREA_SUB_LIST + areaId);
        redisCache.deleteObject(CacheConstants.NO_PARKING_AREA_SUB_LIST + areaId);
    }
}
