package cn.edu.whu.boot.allocation.mapper;

import cn.edu.whu.boot.allocation.entities.Image;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

@Repository
public interface ImageMapper {
    @Select("SELECT file_name FROM task_image WHERE id = #{id}")
    String findFilenameById(int id);

    @Select("SELECT count(*) FROM task_image WHERE file_name = #{filename}")
    int countByFilename(String filename);

    @Select({
            "<script>",
            "SELECT file_name FROM task_image",
            "WHERE id IN (<foreach collection='ids' item='id' separator=','>#{id}</foreach>)",
            "</script>"
    })
    List<String> findFilenamesByIds(@Param("ids") List<Integer> ids);

    @Select("SELECT id, file_name, ST_XMin(bbox) as lon_min, ST_YMin(bbox) as lat_min, ST_XMax(bbox) as lon_max, ST_YMax(bbox) as lat_max " +
            "FROM task_image WHERE task_id = #{taskId}")
    @Results(
            {
                    @Result(property = "filename", column = "file_name"),
                    @Result(property = "minLon", column = "lon_min"),
                    @Result(property = "minLat", column = "lat_min"),
                    @Result(property = "maxLon", column = "lon_max"),
                    @Result(property = "maxLat", column = "lat_max")
            }
    )
    List<Image> findByTaskId(@Param("taskId") int taskId);

    @Select("SELECT count(*) FROM task_image WHERE task_id = #{taskId}")
    int countByTaskId(@Param("taskId") int taskId);

    @Select("SELECT id, substring(file_name, position('_' in file_name) + 1) as filename " +
            "FROM task_image WHERE task_id = #{taskId} " +
            "ORDER BY id " +
            "OFFSET (#{page} - 1) * #{count} LIMIT #{count}")
    List<Map<String, Object>> findByTaskIdPaginated(@Param("taskId") int taskId, @Param("page") int page, @Param("count") int count);

    @Select("INSERT INTO task_image(file_name, task_id, bbox) " +
            "VALUES (#{filename}, #{taskId}, ST_MakeEnvelope(#{minLon}, #{minLat}, #{maxLon}, #{maxLat})) RETURNING id")
    @Options(flushCache = Options.FlushCachePolicy.TRUE)
    int insert(Image image);

    @Delete({
            "<script>",
            "DELETE FROM task_image WHERE id IN (<foreach item='id' collection='ids' separator=','>#{id}</foreach>)",
            "</script>"
    })
    void deleteInIds(@Param("ids") List<Integer> ids);
}