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

import cn.edu.whu.boot.allocation.controllers.dtos.Worker;
import cn.edu.whu.boot.allocation.entities.TaskUserRole;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface TaskUserRoleMapper {
    @Select("SELECT id, task_id, user_id, work_role FROM task_user_role WHERE id = #{id}")
    @Results(
            {
                    @Result(property = "taskId", column = "task_id"),
                    @Result(property = "userId", column = "user_id"),
                    @Result(property = "workRole", column = "work_role")
            }
    )
    TaskUserRole findById(int id);

    @Select("SELECT id, task_id, user_id, work_role FROM task_user_role WHERE task_id = #{taskId}")
    @Results(
            {
                    @Result(property = "taskId", column = "task_id"),
                    @Result(property = "userId", column = "user_id"),
                    @Result(property = "workRole", column = "work_role")
            }
    )
    List<TaskUserRole> findByTaskId(@Param("taskId") int taskId);

    @Select("SELECT id, task_id, user_id, work_role FROM task_user_role WHERE user_id = #{userId}")
    @Results(
            {
                    @Result(property = "taskId", column = "task_id"),
                    @Result(property = "userId", column = "user_id"),
                    @Result(property = "workRole", column = "work_role")
            }
    )
    List<TaskUserRole> findByUserId(@Param("userId") int userId);

    @Select("SELECT a.id, a.real_name, b.work_role " +
            "FROM user_staff AS a, task_user_role AS b " +
            "WHERE b.task_id = #{taskId} AND a.id = b.user_id")
    @Results(
            {
                    @Result(property = "id", column = "id"),
                    @Result(property = "username", column = "real_name"),
                    @Result(property = "role", column = "work_role")
            }
    )
    List<Worker> findWorkerByTaskId(@Param("taskId") int taskId);

    @Select("SELECT work_role FROM task_user_role WHERE task_id = #{taskId} AND user_id = #{userId}")
    Integer findWorkRoleByTaskIdAndUserId(@Param("taskId") int taskId, @Param("userId") int userId);

    @Insert("INSERT INTO task_user_role(task_id, user_id, work_role)" +
            " VALUES(#{taskId}, #{userId}, #{workRole})" +
            " ON CONFLICT (task_id, user_id) DO NOTHING")
    void insert(TaskUserRole taskUserRole);

    @Insert({
            "<script>",
            "INSERT INTO task_user_role(task_id, user_id, work_role)",
            "VALUES" +
                    "<foreach item='item' index='item' collection='list' open='' separator=',' close=''>" +
                    "(" +
                    "#{item.taskId}, #{item.userId}, #{item.workRole}",
            ")" +
                    "</foreach> " +
                    "ON CONFLICT (task_id, user_id) DO NOTHING",
            "</script>"})
    void insertForeach(@Param("list") List<TaskUserRole> list);

    @Select("UPDATE task_user_role SET task_id = #{taskId}, user_id = #{userId}, work_role = #{workRole} RETURNING id")
    @Options(flushCache = Options.FlushCachePolicy.TRUE)
    int update(TaskUserRole taskUserRole);

    @Select("SELECT user_id FROM task_user_role WHERE task_id = #{taskId};")
    List<Integer> getUserIdByTaskId(@Param("taskId") int taskId);

    @Delete("DELETE FROM task_user_role WHERE task_id = #{taskId}")
    void deleteByTaskId(@Param("taskId") int taskId);

    @Delete("DELETE FROM task_user_role WHERE task_id = #{taskId} AND user_id = #{userId}")
    void deleteByTaskIdAndUserId(@Param("taskId") int taskId, @Param("userId") int userId);
}
