package kr.lunaticbum.back.lun.service

import kr.lunaticbum.back.lun.model.dto.ContentType
import kr.lunaticbum.back.lun.model.dto.FeedItemDto
import kr.lunaticbum.back.lun.model.dto.FeedResponse
import kr.lunaticbum.back.lun.repository.PostRepository
import kr.lunaticbum.back.lun.repository.WebBookmarkRepository
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Service
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono

// service/FeedService.kt

@Service
class FeedService(
    private val postRepository: PostRepository,
    private val bookmarkRepository: WebBookmarkRepository
) {

    // 기존 메서드 시그니처 변경: keyword: String? 추가
    fun getGlobalFeed(cursorTime: Long?, size: Int, keyword: String? = null): Mono<FeedResponse> {
        val lastTime = cursorTime ?: System.currentTimeMillis()
        val pageable = PageRequest.of(0, size)

        // 1. Post 조회 (검색어가 있으면 searchPosts, 없으면 findFeedPostsBefore)
        val postsFlux = if (!keyword.isNullOrBlank()) {
            postRepository.searchPosts(keyword, lastTime, pageable)
        } else {
            postRepository.findFeedPostsBefore(lastTime, pageable)
        }.map { post ->
            val type = if (post.postType == "GIBBERISH") ContentType.GIBBERISH else ContentType.POST
            val rawContent = post.content?.replace(Regex("<.*?>"), "") ?: "" // 태그 제거

            FeedItemDto(
                id = post.id,
                type = type,
                title = post.title,
                content = if (type == ContentType.GIBBERISH) post.content else rawContent,
                thumbnail = post.thumb,
                createdAt = post.modifyTime,
                writer = post.writer,
                url = "/blog/viewer/${post.id}"
            )
        }

        // 2. Bookmark 조회
        val bookmarksFlux = if (!keyword.isNullOrBlank()) {
            bookmarkRepository.searchBookmarks(listOf("PUBLIC"), keyword, lastTime, pageable)
        } else {
            bookmarkRepository.findByVisibilityInAndSavedAtLessThanOrderBySavedAtDesc(
                listOf("PUBLIC"), lastTime, pageable
            )
        }.map { bookmark ->
            FeedItemDto(
                id = bookmark.id,
                type = ContentType.BOOKMARK,
                title = bookmark.title ?: bookmark.url,
                content = bookmark.userComment ?: bookmark.description,
                thumbnail = bookmark.displayImageUrl,
                createdAt = bookmark.savedAt,
                writer = bookmark.userId,
                url = bookmark.url ?: ""
            )
        }

        // 3. 병합 및 정렬 (기존 동일)
        return Flux.merge(postsFlux, bookmarksFlux)
            .sort(Comparator.comparing(FeedItemDto::createdAt).reversed())
            .take(size.toLong())
            .collectList()
            .map { items ->
                val nextCursor = if (items.isNotEmpty()) items.last().createdAt else null
                FeedResponse(items, nextCursor)
            }
    }

    /**
     * @param cursorTime 클라이언트가 가지고 있는 마지막 글의 시간 (첫 요청시엔 현재시간 or 아주 큰 값)
     * @param size 한 번에 불러올 개수 (예: 10개)
     */
//    fun getGlobalFeed(cursorTime: Long?, size: Int): Mono<FeedResponse> {
//        // 커서가 없으면 현재 시간으로 설정 (첫 로딩)
//        val lastTime = cursorTime ?: System.currentTimeMillis()
//
//        // 각 저장소에서 'size' 만큼만 가져옴 (부하 최소화)
//        val pageable = PageRequest.of(0, size)
//
//        // 1. Post 조회 (lastTime 이전 글)
//        val postsFlux = postRepository.findFeedPostsBefore(lastTime, pageable)
//            .map { post ->
//                val type = if (post.postType == "GIBBERISH") ContentType.GIBBERISH else ContentType.POST
//                val rawContent = post.content?.replace(Regex("<.*?>"), "") ?: "" // 태그 제거
//
//                FeedItemDto(
//                    id = post.id,
//                    type = type,
//                    title = post.title,
//                    content = if (type == ContentType.GIBBERISH) post.content else rawContent,
//                    thumbnail = post.thumb,
//                    createdAt = post.modifyTime,
//                    writer = post.writer,
//                    url = "/blog/viewer/${post.id}"
//                )
//            }
//
//        // 2. Bookmark 조회 (lastTime 이전 글)
//        val bookmarksFlux = bookmarkRepository.findByVisibilityInAndSavedAtLessThanOrderBySavedAtDesc(
//            listOf("PUBLIC"), lastTime, pageable
//        ).map { bookmark ->
//            FeedItemDto(
//                id = bookmark.id,
//                type = ContentType.BOOKMARK,
//                title = bookmark.title ?: bookmark.url,
//                content = bookmark.userComment ?: bookmark.description,
//                thumbnail = bookmark.displayImageUrl,
//                createdAt = bookmark.savedAt,
//                writer = bookmark.userId,
//                url = bookmark.url ?: ""
//            )
//        }
//
//        // 3. 병합 후 다시 정렬하고 size 만큼 자르기
//        return Flux.merge(postsFlux, bookmarksFlux)
//            .sort(Comparator.comparing(FeedItemDto::createdAt).reversed()) // 최신순 정렬
//            .take(size.toLong()) // 전체 중 상위 size 개만 선택
//            .collectList()
//            .map { items ->
//                // 마지막 아이템의 시간을 다음 커서로 설정
//                val nextCursor = if (items.isNotEmpty()) items.last().createdAt else null
//                FeedResponse(items, nextCursor)
//            }
//    }
}