package com.pandoli365.bibimbap.mapper;

import com.pandoli365.bibimbap.data.GameCommentData;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.Update;

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

@Mapper
public interface GameCommentsMapper {

    @Select("""
            SELECT
                c.id,
                c.game_id AS gameId,
                c.user_id AS userId,
                CASE
                    WHEN c.user_id IS NULL THEN c.nickname
                    WHEN u.is_delete IS TRUE THEN '(탈퇴한 사용자)'
                    ELSE u.display_name
                END AS authorName,
                c.nickname,
                c.content,
                c.created_at AS createdAt,
                c.updated_at AS updatedAt,
                (c.updated_at > c.created_at) AS edited,
                c.deleted_at AS deletedAt
            FROM game_comments c
            LEFT JOIN users u ON u.id = c.user_id
            WHERE c.id = #{id}
              AND c.is_delete IS NOT TRUE
            """)
    GameCommentData getGameComment(long id);

    @SelectProvider(type = CommentSqlProvider.class, method = "listComments")
    List<GameCommentData> listGameComments(@Param("gameId") long gameId,
                                           @Param("sort") String sort,
                                           @Param("offset") int offset,
                                           @Param("limit") int limit);

    @Insert("""
            INSERT INTO game_comments (
                game_id,
                user_id,
                nickname,
                content
            ) VALUES (
                #{gameId},
                #{userId},
                #{nickname},
                #{content}
            )
            """)
    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
    int addGameComment(GameCommentData gameComment);

    @Update("""
            UPDATE game_comments
            SET
                content = #{content},
                updated_at = now()
            WHERE id = #{id}
              AND is_delete IS NOT TRUE
            """)
    int editGameComment(GameCommentData gameComment);

    @Update("""
            UPDATE game_comments
            SET
                is_delete = true,
                deleted_at = COALESCE(deleted_at, now())
            WHERE id = #{id}
              AND is_delete IS NOT TRUE
            """)
    int softDeleteGameComment(long id);

    @Update("""
            UPDATE game_comments
            SET
                nickname = #{nickname},
                content = #{content},
                deleted_at = #{deletedAt},
                is_delete = CASE WHEN #{deletedAt} IS NULL THEN false ELSE true END
            WHERE id = #{id}
              AND is_delete IS NOT TRUE
            """)
    int updateGameComment(GameCommentData gameComment);

    class CommentSqlProvider {

        // SELECT/WHERE 는 컴파일타임 리터럴. ORDER BY 만 sort enum 으로 고정 문자열 분기(${} 미사용).
        public String listComments(Map<String, Object> params) {
            String sort = (String) params.get("sort");
            String orderBy = "newest".equals(sort)
                    ? "ORDER BY c.created_at DESC, c.id DESC"
                    : "ORDER BY c.created_at ASC, c.id ASC";
            return """
                    SELECT
                        c.id,
                        c.game_id AS gameId,
                        c.user_id AS userId,
                        CASE
                            WHEN c.user_id IS NULL THEN c.nickname
                            WHEN u.is_delete IS TRUE THEN '(탈퇴한 사용자)'
                            ELSE u.display_name
                        END AS authorName,
                        c.nickname,
                        c.content,
                        c.created_at AS createdAt,
                        c.updated_at AS updatedAt,
                        (c.updated_at > c.created_at) AS edited,
                        c.deleted_at AS deletedAt
                    FROM game_comments c
                    LEFT JOIN users u ON u.id = c.user_id
                    WHERE c.game_id = #{gameId}
                      AND c.is_delete IS NOT TRUE
                    """
                    + orderBy
                    + " LIMIT #{limit} OFFSET #{offset}";
        }
    }
}
