package kr.lunaticbum.back.lun.model

import kr.lunaticbum.back.lun.utils.LogService
import lombok.AllArgsConstructor
import lombok.Data
import lombok.NoArgsConstructor
import org.bson.BsonType
import org.bson.codecs.pojo.annotations.BsonId
import org.bson.codecs.pojo.annotations.BsonRepresentation
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.domain.Pageable
import org.springframework.data.mongodb.core.mapping.Document
import org.springframework.data.mongodb.repository.ReactiveMongoRepository
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.stereotype.Repository
import org.springframework.stereotype.Service
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import java.time.Duration

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "Post")
class Post {
    @BsonId
    @BsonRepresentation(BsonType.OBJECT_ID)
    var id: String? = null

    var originId: String? = null

    var title : String? = null
    var content : String? = null
    var category : String? = null
    var tags : String? = null

    var writer : String? = null
    var writeTime : Long = 0
    var posting : Boolean = false
    var firstPostLat : Double = 0.0
    var firstPostLon : Double = 0.0

    var modifyTime : Long = 0
    var modifyLat : Double = 0.0
    var modifyLon : Double = 0.0
}


@Repository
interface PostRepository : ReactiveMongoRepository<Post, String> {
  fun findAllByModifyTime(time : Long? = 0): Flux<Post>
    fun findAllByPostingTrue(pageable: Pageable): Flux<Post>
}


@Service
class PostManageg  {
    @Autowired
    private lateinit var logService: LogService

    @Autowired
    private lateinit var postRepository: PostRepository

    @Autowired
    private lateinit var bCryptPasswordEncoder: PasswordEncoder
    fun getPost(id : String) : Mono<Post> = postRepository.findById(id)

    fun find20(pageable :Pageable) : List<Post> {
        return  postRepository.findAllByPostingTrue(pageable).takeLast(20).buffer(20).blockLast(Duration.ofSeconds(30)) ?: listOf()
    }

    fun find20() : List<Post> {
        return  postRepository.findAllByModifyTime(0).takeLast(20).buffer(20).blockLast(Duration.ofSeconds(30)) ?: listOf()
    }

    fun save(post: Post): Mono<Post> {
        println("saved user before ${post}")
//        user.hashPassword(bCryptPasswordEncoder)
        return postRepository.save(post).apply {
            subscribe {
                println("saved user after ${this@apply}")
            }
        }
    }


}