package org.raddatz.familienarchiv.document;

import org.junit.jupiter.api.Test;
import org.raddatz.familienarchiv.PostgresContainerConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.transaction.annotation.Transactional;
import software.amazon.awssdk.services.s3.S3Client;

import java.time.LocalDate;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * End-to-end backfill against a real Postgres (#726, FR-003). H2 is unusable here — the
 * {@code title} column is NOT NULL and the title-sync semantics depend on that — so this pins the
 * behaviour on {@code postgres:16-alpine}: a stale auto-title is rewritten, the sweep is
 * idempotent, prose is left alone, and the mechanical rename writes no {@code document_versions}
 * rows. Permission enforcement (401/403) is covered faster by the {@code @WebMvcTest} slice in
 * {@code AdminControllerTest}.
 */
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
@ActiveProfiles("test")
@Import(PostgresContainerConfig.class)
@Transactional
class DocumentTitleBackfillIntegrationTest {

    @MockitoBean S3Client s3Client;
    @Autowired DocumentService documentService;
    @Autowired DocumentRepository documentRepository;
    @Autowired DocumentVersionRepository documentVersionRepository;

    private Document persist(String index, String title, LocalDate date, DatePrecision precision, String location) {
        return documentRepository.save(Document.builder()
                .originalFilename(index)
                .title(title)
                .documentDate(date)
                .metaDatePrecision(precision)
                .location(location)
                .status(DocumentStatus.PLACEHOLDER)
                .build());
    }

    @Test
    void backfill_rewritesStaleAutoTitle() {
        Document stale = persist("C-0029", "C-0029 – 2028 – Berlin",
                LocalDate.of(1928, 1, 1), DatePrecision.YEAR, "Berlin");

        int count = documentService.backfillTitles();

        assertThat(count).isEqualTo(1); // exactly the one stale row seeded (clean test DB)
        assertThat(documentRepository.findById(stale.getId()).orElseThrow().getTitle())
                .isEqualTo("C-0029 – 1928 – Berlin");
    }

    @Test
    void backfill_isIdempotent_secondRunChangesNothing() {
        persist("C-0029", "C-0029 – 2028 – Berlin", LocalDate.of(1928, 1, 1), DatePrecision.YEAR, "Berlin");

        documentService.backfillTitles();
        int secondRun = documentService.backfillTitles();

        assertThat(secondRun).isZero();
    }

    @Test
    void backfill_skipsProse() {
        Document prose = persist("C-0030", "C-0030 – Brief an Mutter",
                LocalDate.of(1928, 1, 1), DatePrecision.YEAR, null);

        documentService.backfillTitles();

        assertThat(documentRepository.findById(prose.getId()).orElseThrow().getTitle())
                .isEqualTo("C-0030 – Brief an Mutter");
    }

    @Test
    void backfill_addsNoDocumentVersionRows() {
        persist("C-0029", "C-0029 – 2028 – Berlin", LocalDate.of(1928, 1, 1), DatePrecision.YEAR, "Berlin");
        long versionsBefore = documentVersionRepository.count();

        documentService.backfillTitles();

        assertThat(documentVersionRepository.count()).isEqualTo(versionsBefore);
    }
}
