package com.betriebsratkanzlei.legalconsenthub.comment

import com.betriebsratkanzlei.legalconsenthub.application_form.ApplicationFormRepository
import com.betriebsratkanzlei.legalconsenthub.error.CommentNotCreatedException
import com.betriebsratkanzlei.legalconsenthub.error.CommentNotDeletedException
import com.betriebsratkanzlei.legalconsenthub.error.CommentNotFoundException
import com.betriebsratkanzlei.legalconsenthub.error.CommentNotUpdatedException
import com.betriebsratkanzlei.legalconsenthub.error.FormElementNotFoundException
import com.betriebsratkanzlei.legalconsenthub.form_element.FormElementRepository
import com.betriebsratkanzlei.legalconsenthub_api.model.CommentDto
import com.betriebsratkanzlei.legalconsenthub_api.model.CreateCommentDto
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.stereotype.Service
import java.util.UUID

@Service
class CommentService(
    private val commentRepository: CommentRepository,
    private val applicationFormRepository: ApplicationFormRepository,
    private val commentMapper: CommentMapper
) {

    fun createComment(applicationFormId: UUID, formElementId: UUID, createCommentDto: CreateCommentDto): Comment {
        val comment = commentMapper.toComment(applicationFormId, formElementId, createCommentDto)
        val savedComment: Comment
        try {
            savedComment = commentRepository.save(comment)
        } catch (e: Exception) {
            throw CommentNotCreatedException(e)
        }

        return savedComment
    }

    fun getCommentById(id: UUID): Comment {
        return commentRepository.findById(id).orElseThrow { CommentNotFoundException(id) }
    }

    fun getComments(applicationFormId: UUID): Page<Comment> {
        val applicationForm =
            applicationFormRepository.findById(applicationFormId).orElse(null)
        val pageable = PageRequest.of(0, 10)
        return commentRepository.findAllByApplicationForm(applicationForm, pageable)
    }

    fun updateComment(commentDto: CommentDto): Comment {
        // TODO find statt mappen?
        val comment = commentMapper.toComment(commentDto)
        val updatedComment: Comment

        try {
            updatedComment = commentRepository.save(comment)
        } catch (e: Exception) {
            throw CommentNotUpdatedException(e, commentDto.id)
        }

        return updatedComment
    }

    fun deleteCommentByID(id: UUID) {
        try {
            commentRepository.deleteById(id)
        } catch (e: Exception) {
            throw CommentNotDeletedException(e)
        }
    }
}
