package org.fuseri.moduleexercise.question;

import jakarta.persistence.EntityNotFoundException;
import lombok.Getter;
import org.fuseri.moduleexercise.answer.Answer;
import org.fuseri.moduleexercise.common.DomainService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;
import java.util.Set;

/**
 * Represent a service for managing Question entities
 */
@Service
public class QuestionService extends DomainService<Question> {

    /**
     * The repository instance used by this service
     */
    @Getter
    private final QuestionRepository repository;

    /**
     * Construct a new instance of QuestionService with the specified repository
     *
     * @param repository the repository instance to be used by this service
     */
    @Autowired
    public QuestionService(QuestionRepository repository) {
        this.repository = repository;
    }

    /**
     * Retrieve the Question entity with the specified ID
     *
     * @param id the ID of the Question entity to retrieve
     * @return the Question entity with the specified ID
     * @throws EntityNotFoundException if no Question entity exists with the specified ID
     */
    @Transactional(readOnly = true)
    public Question find(long id) {
        return repository.findById(id)
                .orElseThrow(() -> new EntityNotFoundException("Question '" + id + "' not found."));
    }

    /**
     * Patch update a question. Don't update question answers.
     *
     * @param id              the question ID
     * @param updatedQuestion the question to update
     * @return the updated question
     */
    @Transactional
    public Question patchUpdateWithoutAnswers(Long id, Question updatedQuestion) {
        Optional<Question> optionalQuestion = repository.findById(id);
        if (optionalQuestion.isPresent()) {
            Question question = optionalQuestion.get();
            question.setText(updatedQuestion.getText());
            question.setExercise(updatedQuestion.getExercise());
            return repository.save(question);
        } else {
            throw new EntityNotFoundException("Question with id: " + id + " was not found.");
        }
    }

    /**
     * Add answers to question with question ID.
     *
     * @param id      of question
     * @param answers to add to question
     * @return updated question
     */
    public Question addAnswers(Long id, Set<Answer> answers) {
        Optional<Question> optionalQuestion = repository.findById(id);
        if (optionalQuestion.isPresent()) {
            Question question = optionalQuestion.get();
            question.addAnswers(answers);
            return repository.save(question);
        } else {
            throw new EntityNotFoundException(
                    "Question with id: " + id + " was not found.");
        }
    }

    /**
     * Create a question with answers
     *
     * @param question the question to create
     * @return the created question
     */
    @Override
    public Question create(Question question) {
        for (var answer: question.getAnswers()) {
            answer.setQuestion(question);
        }
        return getRepository().save(question);
    }
}
