package kz.konturai.parser.service;

import kz.konturai.parser.model.MarketItem;
import kz.konturai.parser.repository.MarketItemRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
@EnabledIfEnvironmentVariable(named = "RUN_INTEGRATION_TESTS", matches = "true")
@TestPropertySource(properties = {
        "spring.data.mongodb.host=localhost",
        "spring.data.mongodb.port=27017",
        "spring.data.mongodb.database=parser_test_db",
        "rss.feed.url=https://kursiv.media/feed/"
})
public class KursivParserServiceTest {

    @Autowired
    private KursivParserService kursivParserService;

    @Autowired
    private MarketItemRepository marketItemRepository;

    @Test
    public void testParseAndSaveRssFeed() {
        // Очищаем базу данных перед тестом
        marketItemRepository.deleteAll();

        // Запускаем парсинг
        List<MarketItem> savedItems = kursivParserService.parseAndSaveRssFeed();

        // Проверяем результаты
        assertNotNull(savedItems, "Список сохраненных элементов не должен быть null");

        // Проверяем, что хотя бы одна запись была обработана
        assertTrue(savedItems.size() > 0, "Должна быть обработана хотя бы одна запись");

        // Проверяем структуру первой записи
        MarketItem firstItem = savedItems.get(0);
        assertNotNull(firstItem.getTitle(), "Заголовок не должен быть null");
        assertNotNull(firstItem.getUrl(), "URL не должен быть null");
        assertNotNull(firstItem.getHash(), "Хэш не должен быть null");
        assertNotNull(firstItem.getPublishedAt(), "Дата публикации не должна быть null");
        assertNotNull(firstItem.getRawText(), "Текст не должен быть null");

        // Проверяем, что запись сохранилась в базе данных
        long totalCount = marketItemRepository.count();
        assertTrue(totalCount > 0, "В базе данных должны быть записи");

        // Проверяем дедупликацию - повторный запуск не должен создавать дубликаты
        List<MarketItem> secondRun = kursivParserService.parseAndSaveRssFeed();
        long secondCount = marketItemRepository.count();

        // Количество записей должно остаться тем же или увеличиться незначительно
        assertTrue(secondCount >= totalCount, "Количество записей не должно уменьшиться");

        System.out.println("Тест прошел успешно:");
        System.out.println("- Обработано записей в первом запуске: " + savedItems.size());
        System.out.println("- Обработано записей во втором запуске: " + secondRun.size());
        System.out.println("- Общее количество записей в БД: " + secondCount);
    }

    @Test
    public void testGetTotalItemsCount() {
        long count = kursivParserService.getTotalItemsCount();
        assertTrue(count >= 0, "Количество записей должно быть неотрицательным");
    }

    @Test
    public void testGetAllItems() {
        List<MarketItem> items = kursivParserService.getAllItems();
        assertNotNull(items, "Список элементов не должен быть null");

        // Проверяем структуру элементов
        for (MarketItem item : items) {
            assertNotNull(item.getId(), "ID элемента не должен быть null");
            assertNotNull(item.getHash(), "Хэш элемента не должен быть null");
            assertNotNull(item.getSourceName(), "Название источника не должно быть null");
            assertEquals("Kursiv (Бизнес/экономика)", item.getSourceName(),
                    "Название источника должно соответствовать ожидаемому");
        }
    }
}
