package com.lanyuanxiaoyao.digtal.market

import com.blinkfox.fenix.jpa.FenixJpaRepository
import com.blinkfox.fenix.specification.FenixJpaSpecificationExecutor
import jakarta.persistence.Entity
import jakarta.persistence.Id
import jakarta.persistence.Lob
import java.util.Date
import org.springframework.data.jpa.repository.Modifying
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import org.springframework.stereotype.Repository
import org.springframework.transaction.annotation.Transactional

@Entity
class Article(
    @Id var id: String,
    var code: String,
    var url: String,
    var title: String?,
    var author: String?,
    var category: String?,
    @Lob var text: String?,
    @Lob var html: String?,
    var subtitle: String?,
    @Lob var description: String?,
    var tags: String?,
    var createTime: Date?,
    var pushed: Boolean?,
    var error: Int?,
) {
    override fun toString(): String {
        return "Article(id='$id', code='$code', url='$url', title=$title, author=$author, category=$category, text=$text, html=$html, subtitle=$subtitle, description=$description, tags=$tags, createTime=$createTime, pushed=$pushed, error=$error)"
    }
}

@Repository
interface ArticleRepository : FenixJpaRepository<Article, String>, FenixJpaSpecificationExecutor<Article> {
    fun findAllByDescriptionIsNullAndTextIsNotNull(): List<Article>
    fun findAllByHtmlIsNotNull(): List<Article>

    fun existsByCode(code: String): Boolean

    @Query("select distinct article.category from Article article where article.category is not null and article.category <> ''")
    fun findAllCategory(): List<String>

    @Query("select distinct article.author from Article article where article.author is not null and article.author <> ''")
    fun findAllAuthor(): List<String>

    @Modifying
    @Transactional
    @Query("update Article article set article.pushed = :pushed where article.id = :id")
    fun updatePushedById(@Param("id") id: String, @Param("pushed") pushed: Boolean)

    @Query("select article.id from Article article where (article.error is not null and article.error > 3) or (article.description is not null and article.text is not null and article.text <> '')")
    fun findAllId(): List<String>

    @Query("select new com.lanyuanxiaoyao.digtal.market.CountGroupByString(article.code, count(article.code)) from Article article group by article.code")
    fun countGroupByCode(): List<CountGroupByString>

    @Query("select article.error from Article article where article.id = :id")
    fun findErrorById(@Param("id") id: String): Int?
}

data class CountGroupByString(
    val key: String,
    val count: Long,
)
