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

import java.math.BigDecimal;
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.area.domain.Area;
import com.ruoyi.bst.area.domain.AreaQuery;
import com.ruoyi.bst.area.domain.AreaVO;
import com.ruoyi.bst.area.domain.vo.LocationAreaVO;
import com.ruoyi.bst.area.mapper.AreaMapper;
import com.ruoyi.bst.area.service.AreaService;
import com.ruoyi.bst.area.utils.AreaUtil;
import com.ruoyi.bst.areaJoin.domain.enums.AreaJoinPermission;
import com.ruoyi.bst.areaSub.domain.AreaSubVO;
import com.ruoyi.bst.areaSub.service.AreaSubService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.common.utils.map.GeoUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 运营区Service业务层处理
 *
 * @author ruoyi
 * @date 2025-03-14
 */
@Service
@Slf4j
public class AreaServiceImpl implements AreaService
{
    @Autowired
    private AreaMapper areaMapper;

    @Autowired
    private AreaSubService areaSubService;

    /**
     * 查询运营区
     *
     * @param id 运营区主键
     * @return 运营区
     */
    @Override
    public AreaVO selectAreaById(Long id, boolean scope)
    {
        if (id == null) {
            return null;
        }
        AreaQuery query = new AreaQuery();
        query.setId(id);
        query.setScope(scope);
        query.addAreaPermission(AreaJoinPermission.AREA_VIEW.getCode());
        return this.selectOne(query);
    }

    @Override
    public AreaVO selectOne(AreaQuery query) {
        PageHelper.startPage(1, 1);
        List<AreaVO> list = areaMapper.selectAreaList(query);
        return CollectionUtils.firstElement(list);
    }

    @Override
    public Long selectAreaByStoreId(Long storeId) {
        return areaMapper.selectAreaByStoreId(storeId);
    }

    @Override
    public List<AreaVO> selectSimpleList(AreaQuery query) {
        return areaMapper.selectSimpleList(query);
    }

    /**
     * 查询运营区列表
     *
     * @param area 运营区
     * @return 运营区
     */
    @Override
    public List<AreaVO> selectAreaList(AreaQuery area)
    {
        return areaMapper.selectAreaList(area);
    }

    /**
     * 新增运营区
     *
     * @param area 运营区
     * @return 结果
     */
    @Override
    public int insertArea(Area area)
    {
        // 将边界值转Geometry对象
        if (area.getBoundaryStr() != null) {
            Geometry geometry = GeoUtils.toGeometry(area.getBoundaryStr());
            area.setBoundary(GeoUtils.wkt(geometry));
        }
        area.setCreateTime(DateUtils.getNowDate());
        return areaMapper.insertArea(area);
    }

    /**
     * 修改运营区
     *
     * @param area 运营区
     * @return 结果
     */
    @Override
    public int updateArea(Area area)
    {
        // 将边界值转Geometry对象
        if (area.getBoundaryStr() != null) {
            Geometry geometry = GeoUtils.toGeometry(area.getBoundaryStr());
            area.setBoundary(GeoUtils.wkt(geometry));
        }
        return areaMapper.updateArea(area);
    }

    /**
     * 批量删除运营区
     *
     * @param ids 需要删除的运营区主键
     * @return 结果
     */
    @Override
    public int deleteAreaByIds(Long[] ids)
    {
        return areaMapper.deleteAreaByIds(ids);
    }

    /**
     * 删除运营区信息
     *
     * @param id 运营区主键
     * @return 结果
     */
    @Override
    public int deleteAreaById(Long id)
    {
        return areaMapper.deleteAreaById(id);
    }

    /**
     * 逻辑删除运营区
     *
     * @param ids 需要删除的运营区主键集合
     * @return 结果
     */
    @Override
    public int logicDel(List<Long> ids)
    {
        return areaMapper.logicDel(ids);
    }


    @Override
    public LocationAreaVO selectLocationArea(BigDecimal lon, BigDecimal lat, Long areaId) {
        if (lon == null || lat == null || areaId == null) {
            return null;
        }
        // 查询运营区
        AreaVO area = this.selectAreaById(areaId);
        if (area == null) {
            return null;
        }
        // 查询运营区内的禁行区
        List<AreaSubVO> noRidingList = areaSubService.selectNoRidingListByAreaId(areaId);
        
        return AreaUtil.getLocationArea(lon, lat, area, noRidingList);
    }
}
