package com.example.demo.service

import com.example.demo.model.User
import com.example.demo.model.test_db.Tables
import com.example.demo.model.test_db.Tables.MESSAGES
import com.example.demo.model.test_db.tables.Users.USERS
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
import org.jooq.Condition
import org.jooq.DSLContext
import org.jooq.Record
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Lazy
import org.springframework.stereotype.Service
import reactor.core.publisher.Flux
import java.util.*


@Service
@Lazy
class UserService(@Autowired @Lazy private val dsl: DSLContext) {

    fun users(): Flux<User> = Flux
            .from(dsl
                    .select()
                    .from(Tables.USERS))
            .map(Query::toUser)


    suspend fun users2(): Flow<User> {
        return dsl
                .select()
                .from(USERS)
                .fetch()
                .map(Query::toUser)
                .asFlow()
    }

    suspend fun getUserByName(userName: String): Optional<User> = dsl
            .select(USERS.ID, USERS.NAME)
            .from(USERS)
            .where(USERS.NAME.eq(userName))
            .limit(1)
            .fetchOptional()
            .map(Query::toUser)


    suspend fun getAllMessages(): Flow<String> = dsl
            .select(MESSAGES.MESSAGE).from(MESSAGES)
            .fetch()
            .map { it.get(MESSAGES.MESSAGE) }
            .asFlow()

    suspend fun getUserMessages(userName: String): Flow<String> = dsl
            .select(MESSAGES.MESSAGE).from(MESSAGES, USERS)
            .where(MESSAGES.USER_ID.eq(USERS.ID), USERS.NAME.eq(userName))
            .fetch()
            .map { it.get(MESSAGES.MESSAGE) }
            .asFlow()

    fun test() = dsl
            .select(Query.messages)
            .from(MESSAGES)
            .where(Query.complexClause)
            .fetch()
            .asFlow()

    private object Query {
        val messages = listOf(MESSAGES.MESSAGE)
        val complexClause: Condition = MESSAGES.MESSAGE.eq("")
        fun toUser(r: Record) = User(r.get(USERS.ID), r.get(USERS.NAME))
    }
}
