package org.fuseri.moduleexercise.question;

import jakarta.persistence.EntityNotFoundException;
import org.fuseri.moduleexercise.answer.Answer;
import org.fuseri.moduleexercise.exercise.Exercise;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@SpringBootTest
class QuestionServiceTest {

    @MockBean
    QuestionRepository questionRepository;

    @Autowired
    QuestionService questionService;

    Exercise exercise;
    Question question;
    Question question1;

    @BeforeEach
    void setup() {
        exercise = new Exercise("idioms", "exercise on basic idioms",2,1L,new HashSet<>());
        question = new Question("text",new HashSet<>(),exercise);
        question1 = new Question("text2",new HashSet<>(),exercise);
    }


    @Test
    void create() {
        when(questionRepository.save(question)).thenReturn(question);
        Question result = questionService.create(question);
        Assertions.assertEquals(question, result);
        verify(questionRepository).save(question);
    }

    @Test
    void notFound() {
        when(questionRepository.findById(anyLong())).thenReturn(Optional.empty());

        Assertions.assertThrows(EntityNotFoundException.class, () -> questionService.find(anyLong()));
    }

    @Test
    void find() {
        when(questionRepository.findById(anyLong())).thenReturn(Optional.of(question));

        Question result = questionService.find(anyLong());

        Assertions.assertEquals(question, result);
        verify(questionRepository).findById(anyLong());
    }

    @Test
    void patchUpdateWithoutAnswers() {
        when(questionRepository.findById(anyLong())).thenReturn(Optional.of(question));
        when(questionRepository.save(question)).thenReturn(question);
        Question result = questionService.patchUpdateWithoutAnswers(anyLong(), question);
        Assertions.assertEquals(question, result);
    }

    @Test
    void addAnswers() {
        Set<Answer> answers = Set.of(new Answer("BA", true, question));
        question.setAnswers(answers);
        when(questionRepository.findById(anyLong())).thenReturn(Optional.of(question));
        when(questionRepository.save(question)).thenReturn(question);
        Question result = questionService.patchUpdateWithoutAnswers(anyLong(), question);
        Assertions.assertEquals(question, result);
    }
}
