package org.raddatz.familienarchiv.tag;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Optional;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class TagImportUpsertTest {

    @Mock TagRepository tagRepository;
    @InjectMocks TagService tagService;

    @Test
    void upsertBySourceRef_insertsNewTag_whenSourceRefUnknown() {
        when(tagRepository.findBySourceRef("Themen/Brautbriefe")).thenReturn(Optional.empty());
        when(tagRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));

        UUID parentId = UUID.randomUUID();
        Tag result = tagService.upsertBySourceRef("Themen/Brautbriefe", "Brautbriefe", parentId);

        assertThat(result.getSourceRef()).isEqualTo("Themen/Brautbriefe");
        assertThat(result.getName()).isEqualTo("Brautbriefe");
        assertThat(result.getParentId()).isEqualTo(parentId);
    }

    @Test
    void upsertBySourceRef_updatesInPlace_whenSourceRefExists() {
        Tag existing = Tag.builder().id(UUID.randomUUID()).name("Brautbriefe")
                .sourceRef("Themen/Brautbriefe").build();
        when(tagRepository.findBySourceRef("Themen/Brautbriefe")).thenReturn(Optional.of(existing));
        when(tagRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));

        tagService.upsertBySourceRef("Themen/Brautbriefe", "Brautbriefe", null);

        verify(tagRepository).save(argThat(t -> t.getId().equals(existing.getId())));
        verify(tagRepository, never()).save(argThat(t -> t.getId() == null));
    }

    @Test
    void upsertBySourceRef_preservesHumanRenamedTag_onReimport() {
        Tag humanRenamed = Tag.builder().id(UUID.randomUUID()).name("Verlobungsbriefe")
                .sourceRef("Themen/Brautbriefe").build();
        when(tagRepository.findBySourceRef("Themen/Brautbriefe")).thenReturn(Optional.of(humanRenamed));
        when(tagRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));

        Tag result = tagService.upsertBySourceRef("Themen/Brautbriefe", "Brautbriefe", null);

        assertThat(result.getName()).isEqualTo("Verlobungsbriefe");
    }
}
