package com.pandoli365.bibimbap.mapper;

import com.pandoli365.bibimbap.data.PostData;
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.Update;

import java.time.OffsetDateTime;
import java.util.List;

@Mapper
public interface PostsMapper {

    @Select("""
            SELECT
                p.id,
                p.category_id AS categoryId,
                p.author_user_id AS authorUserId,
                p.title,
                p.body_markdown AS bodyMarkdown,
                p.body_sanitized_html AS bodySanitizedHtml,
                p.link_url AS linkUrl,
                p.og_title AS ogTitle,
                p.og_description AS ogDescription,
                p.og_image_url AS ogImageUrl,
                p.og_site_name AS ogSiteName,
                p.og_fetched_at AS ogFetchedAt,
                p.status,
                p.created_at AS createdAt,
                p.updated_at AS updatedAt,
                p.deleted_at AS deletedAt,
                p.is_delete AS isDelete,
                u.display_name AS authorDisplayName,
                c.name AS categoryName,
                c.slug AS categorySlug
            FROM posts p
            JOIN users u ON u.id = p.author_user_id
            JOIN post_categories c ON c.id = p.category_id
            WHERE p.status = 'PUBLISHED'
              AND p.is_delete = false
              AND (#{categoryId}::bigint IS NULL OR p.category_id = #{categoryId}::bigint)
              AND (
                    #{cursorCreatedAt}::timestamptz IS NULL
                    OR (p.created_at, p.id) < (#{cursorCreatedAt}::timestamptz, #{cursorId}::bigint)
                  )
            ORDER BY p.created_at DESC, p.id DESC
            LIMIT #{limit}
            """)
    List<PostData> listPublishedKeyset(@Param("cursorCreatedAt") OffsetDateTime cursorCreatedAt,
                                       @Param("cursorId") Long cursorId,
                                       @Param("categoryId") Long categoryId,
                                       @Param("limit") int limit);

    @Select("""
            SELECT
                p.id,
                p.category_id AS categoryId,
                p.author_user_id AS authorUserId,
                p.title,
                p.body_markdown AS bodyMarkdown,
                p.body_sanitized_html AS bodySanitizedHtml,
                p.link_url AS linkUrl,
                p.og_title AS ogTitle,
                p.og_description AS ogDescription,
                p.og_image_url AS ogImageUrl,
                p.og_site_name AS ogSiteName,
                p.og_fetched_at AS ogFetchedAt,
                p.status,
                p.created_at AS createdAt,
                p.updated_at AS updatedAt,
                p.deleted_at AS deletedAt,
                p.is_delete AS isDelete,
                u.display_name AS authorDisplayName,
                c.name AS categoryName,
                c.slug AS categorySlug
            FROM posts p
            JOIN users u ON u.id = p.author_user_id
            JOIN post_categories c ON c.id = p.category_id
            WHERE p.id = #{id}
              AND p.status = 'PUBLISHED'
              AND p.is_delete = false
            """)
    PostData getPublished(@Param("id") long id);

    @Insert("""
            INSERT INTO posts (
                category_id,
                author_user_id,
                title,
                body_markdown,
                body_sanitized_html,
                link_url,
                og_title,
                og_description,
                og_image_url,
                og_site_name,
                og_fetched_at,
                status
            ) VALUES (
                #{categoryId},
                #{authorUserId},
                #{title},
                #{bodyMarkdown},
                #{bodySanitizedHtml},
                #{linkUrl},
                #{ogTitle},
                #{ogDescription},
                #{ogImageUrl},
                #{ogSiteName},
                #{ogFetchedAt},
                #{status}
            )
            """)
    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
    int insert(PostData post);

    @Update("""
            UPDATE posts
            SET category_id = #{categoryId},
                title = #{title},
                body_markdown = #{bodyMarkdown},
                body_sanitized_html = #{bodySanitizedHtml},
                link_url = #{linkUrl},
                og_title = #{ogTitle},
                og_description = #{ogDescription},
                og_image_url = #{ogImageUrl},
                og_site_name = #{ogSiteName},
                og_fetched_at = #{ogFetchedAt},
                status = #{status},
                updated_at = now()
            WHERE id = #{id}
            """)
    int update(PostData post);

    @Update("""
            UPDATE posts
            SET is_delete = true,
                deleted_at = now()
            WHERE id = #{id}
            """)
    int softDelete(@Param("id") long id);
}
