package com.alttd.altitudeweb.database.web_db;

import org.apache.ibatis.annotations.*;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

public interface PrivilegedUserMapper {

    /**
     * Retrieves a user by their UUID along with their permissions
     * @param uuid The UUID of the user to retrieve
     * @return The optional PrivilegedUser with their permissions
     */
    @Select("""
        SELECT id, uuid
        FROM privileged_users
        WHERE uuid = #{uuid}
        """)
    @Results({
            @Result(property = "id", column = "id"),
            @Result(property = "uuid", column = "uuid"),
            @Result(property = "permissions", column = "id", javaType = List.class,
                    many = @Many(select = "getPermissionsForUser"))
    })
    Optional<PrivilegedUser> getUserByUuid(@Param("uuid") UUID uuid);

    /**
     * Retrieves all privileged users with their permissions
     * @return List of all privileged users with their permissions
     */
    @Select("""
            SELECT id, uuid
            FROM privileged_users
            """)
    @Results({
            @Result(property = "id", column = "id"),
            @Result(property = "uuid", column = "uuid"),
            @Result(property = "permissions", column = "id", javaType = List.class,
                    many = @Many(select = "getPermissionsForUser"))
    })
    List<PrivilegedUser> getAllUsers();

    /**
     * Gets all permissions for a specific user
     * @param userId The ID of the user
     * @return List of permission strings
     */
    @Select("""
            SELECT privileges
            FROM privileges
            WHERE user_id = #{userId}
            """)
    List<String> getPermissionsForUser(@Param("userId") int userId);

    /**
     * Adds a new privileged user
     * @param user The PrivilegedUser object to add
     * @return The number of rows affected
     */
    @Insert("""
            INSERT INTO privileged_users (uuid)
            VALUES (#{user.uuid})
            """)
    @Options(useGeneratedKeys = true, keyProperty = "user.id", keyColumn = "id")
    int addUser(@Param("user") PrivilegedUser user);

    /**
     * Deletes a privileged user by their UUID
     * @param uuid The UUID of the user to delete
     * @return The number of rows affected
     */
    @Delete("""
            DELETE FROM privileged_users
            WHERE uuid = #{uuid}
            """)
    int deleteUserByUuid(@Param("uuid") String uuid);

    /**
     * Adds a permission to a user
     * @param userId The ID of the user
     * @param permission The permission to add
     * @return The number of rows affected
     */
    @Insert("""
            INSERT INTO privileges (user_id, privileges)
            VALUES (#{userId}, #{permission})
            """)
    int addPermissionToUser(@Param("userId") int userId, @Param("permission") String permission);

    /**
     * Removes a permission from a user
     * @param userId The ID of the user
     * @param permission The permission to remove
     * @return The number of rows affected
     */
    @Delete("""
            DELETE FROM privileges
            WHERE user_id = #{userId} AND privileges = #{permission}
            """)
    int removePermissionFromUser(@Param("userId") int userId, @Param("permission") String permission);

    @Insert("""
        INSERT INTO privileged_users (uuid)
        VALUES (#{user.uuid})
        """)
    @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "user.id", before = false, resultType = int.class)
    void createPrivilegedUser(@Param("user") PrivilegedUser user);
}
