package de.assecutor.votianlt.service;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import de.assecutor.votianlt.model.AppUser;
import de.assecutor.votianlt.model.Job;
import de.assecutor.votianlt.model.User;
import de.assecutor.votianlt.model.task.ConfirmationTask;
import de.assecutor.votianlt.repository.AppUserRepository;
import de.assecutor.votianlt.repository.JobRepository;
import de.assecutor.votianlt.repository.TaskRepository;
import de.assecutor.votianlt.repository.UserRepository;
import java.util.List;
import java.util.Optional;
import org.bson.types.ObjectId;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.test.util.ReflectionTestUtils;

@ExtendWith(MockitoExtension.class)
class EmailServiceTest {

    @Mock
    private UserRepository userRepository;
    @Mock
    private JobRepository jobRepository;
    @Mock
    private TaskRepository taskRepository;
    @Mock
    private AppUserRepository appUserRepository;
    @Mock
    private JavaMailSender mailSender;

    @Captor
    private ArgumentCaptor<SimpleMailMessage> mailCaptor;

    private EmailService emailService;
    private TaskAssignmentService taskAssignmentService;

    @BeforeEach
    void setUp() {
        taskAssignmentService = new TaskAssignmentService(taskRepository, jobRepository);
        emailService = new EmailService(userRepository, jobRepository, taskAssignmentService, appUserRepository,
                mailSender);
        ReflectionTestUtils.setField(emailService, "smtpUsername", "noreply@example.com");
    }

    @Test
    void sendTaskCompletionNotificationUsesAssignedAppUserName() {
        User webUser = createWebUser();
        AppUser assignedAppUser = createAssignedAppUser();
        Job job = createJob(webUser, assignedAppUser);

        when(jobRepository.findById(job.getId())).thenReturn(Optional.of(job));
        when(userRepository.findById(webUser.getId())).thenReturn(Optional.of(webUser));
        when(appUserRepository.findById(assignedAppUser.getId())).thenReturn(Optional.of(assignedAppUser));

        emailService.sendTaskCompletionNotification(job.getId(), "PHOTO", "task-1", "ignored");

        verify(mailSender).send(mailCaptor.capture());
        String body = mailCaptor.getValue().getText();
        assertThat(body).contains("eine Aufgabe wurde von Max Mustermann abgeschlossen:");
        assertThat(body).contains("Abgeschlossen von: Max Mustermann");
        assertThat(body).contains("Hallo Dr. Anna Unternehmer,");
    }

    @Test
    void sendJobCompletionNotificationUsesAssignedAppUserName() {
        User webUser = createWebUser();
        AppUser assignedAppUser = createAssignedAppUser();
        Job job = createJob(webUser, assignedAppUser);

        when(jobRepository.findById(job.getId())).thenReturn(Optional.of(job));
        when(userRepository.findById(webUser.getId())).thenReturn(Optional.of(webUser));
        when(appUserRepository.findById(assignedAppUser.getId())).thenReturn(Optional.of(assignedAppUser));
        when(taskRepository.findByJobIdOrderByTaskOrderAsc(job.getId())).thenReturn(List.of(
                createConfirmationTask(0, "OK"),
                createConfirmationTask(1, "Weiter")));

        emailService.sendJobCompletionNotification(job.getId(), "ignored");

        verify(mailSender).send(mailCaptor.capture());
        String body = mailCaptor.getValue().getText();
        assertThat(body).contains("Anzahl erledigter Aufgaben: 2");
        assertThat(body).contains("Abgeschlossen von: Max Mustermann");
        assertThat(body).contains("Hallo Dr. Anna Unternehmer,");
    }

    private User createWebUser() {
        User user = new User();
        user.setId(new ObjectId());
        user.setTitle("Dr.");
        user.setFirstname("Anna");
        user.setName("Unternehmer");
        user.setEmail("anna@example.com");
        return user;
    }

    private AppUser createAssignedAppUser() {
        AppUser appUser = new AppUser();
        appUser.setId(new ObjectId());
        appUser.setVorname("Max");
        appUser.setNachname("Mustermann");
        appUser.setBezeichnung("Fahrer Max");
        return appUser;
    }

    private Job createJob(User webUser, AppUser assignedAppUser) {
        Job job = new Job();
        job.setId(new ObjectId());
        job.setCreatedBy(webUser.getId().toHexString());
        job.setAppUser(assignedAppUser.getId().toHexString());
        job.setJobNumber("JOB-2026-001");
        job.setDeliveryCompany("Beispiel GmbH");
        job.setPickupCity("Berlin");
        job.setDeliveryCity("Hamburg");
        return job;
    }

    private ConfirmationTask createConfirmationTask(int taskOrder, String buttonText) {
        ConfirmationTask task = new ConfirmationTask(buttonText);
        task.setTaskOrder(taskOrder);
        return task;
    }
}
