package com.example.backend;

import java.util.List;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.transaction.annotation.Transactional;

import com.example.backend.books.model.BookEntity;
import com.example.backend.books.service.BookService;
import com.example.backend.categories.model.CategoryEntity;
import com.example.backend.categories.service.CategoryService;
import com.example.backend.core.error.NotFoundException;

@SpringBootTest
class BookServiceTests {
    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BookService bookService;

    private BookEntity book;

    @BeforeEach
    void createData() {
        removeData();

        final var category1 = categoryService.create(new CategoryEntity("Фэнтези"));
        final var category2 = categoryService.create(new CategoryEntity("Художественная литература"));
        final var category3 = categoryService.create(new CategoryEntity("Книги для подростков"));

        book = bookService.create(new BookEntity(category1, "Шестерка воронов", "Ли Бардуго",
                700.00,
                "Триша Левенселлер — американская писательница, подарившая вам роман «Тени между нами», который стал бестселлером Amazon в разделе «Фэнтези YA», вновь радует своих фанатов новой магической историей «Клинок тайн».\n\nЕще до выхода в свет книгу добавили в раздел «Хочу прочитать» более 10 тысяч человек на портале Goodreads.com.\n\n«Клинок тайн» — первая часть захватывающей дилогии про девушку, которая благодаря магии крови создает самое опасное в мире оружие, и ослепительного юношу, что составляет ей компанию в этом непростом приключении.",
                "Юная Зива предпочитает проводить время с оружием, а не с людьми. Она кузнец и ей предстоит создать самое могущественное оружие на земле.\n\nДевушка демонстрирует меч, способный от одной капли крови врага раскрыть все тайные замыслы его обладателю.\n\nОднако у заказчика на оружие другие планы: заставить Зиву вооружить мечами свое войско и поработить весь мир. Когда девушка понимает, что меч, созданный благодаря магии крови, невозможно уничтожить и рано или поздно на нее объявят охоту, ей остается только одно – бежать, не оглядываясь. Зиве теперь суждено спасти мир от собственного творения. Но как бы далеко она ни старалась убежать, все ловушки уже расставлены.",
                "2946447", "Эксмо", "Young Adult. Бестселлеры Триши Левенселлер", 2022, 480, "20.7x13x2.5",
                "Мягкий переплёт", 1500, 440, ""));
        bookService.create(new BookEntity(category2, "Форсайт", "Сергей Лукъяненко", 775.00,
                "Новый долгожданный роман от автора бестселлеров «Ночной дозор» и «Черновик». Увлекательная история о Мире После и мире настоящего, где 5 процентов людей знают о надвигающемся апокалипсисе больше, чем кто-либо может представить.",
                "Людям порой снится прошлое. Иногда хорошее, иногда не очень. Но что делать, если тебе начинает сниться будущее? И в нём ничего хорошего нет совсем.",
                "3001249", "АСТ", "Книги Сергея Лукьяненко", 2023, 352, "20.5x13x2", "Твердый переплёт", 20000,
                350, ""));
        bookService.create(new BookEntity(category3,
                "Колесо Времени. Книга 11. Нож сновидений",
                "Роберт Джордан", 977.00,
                "Последняя битва не за горами. Об этом говорят знамения, повсеместно наблюдаемые людьми: на улицах городов и сел появляются ходячие мертвецы, они больше не в состоянии покоиться в земле с миром; восстают из небытия города и исчезают на глазах у людей… Все это знак того, что истончается окружающая реальность и укрепляется могущество Темного. Так говорят древние предсказания. Ранд ал’Тор, Дракон Возрожденный, скрывается в отдаленном поместье, чтобы опасность, ему грозящая, не коснулась кого-нибудь еще. Убежденный, что для Последней битвы нужно собрать как можно большее войско, он наконец решает заключить с явившимися из-за океана шончан жизненно необходимое перемирие. Илэйн, осажденная в Кэймлине, обороняет город от войск Аримиллы, претендующей на андорский трон, и одновременно ведет переговоры с представителями других знатных Домов. Эгвейн, возведенную на Престол Амерлин мятежными Айз Седай и схваченную в результате предательства, доставляют в Тар Валон, в Белую Башню. А сам лагерь противников Элайды взбудоражен таинственными убийствами, совершенными посредством Единой Силы… В настоящем издании текст романа заново отредактирован и исправлен.",
                "", "3009341", "Азбука", "Звезды новой фэнтези", 2023, 896,
                "21.5x14.4x4.1", "Твердый переплёт", 8000, 1020, ""));
    }

    @AfterEach
    void removeData() {
        bookService.getAll(0L).forEach(item -> bookService.delete(item.getId()));
        categoryService.getAll().forEach(item -> categoryService.delete(item.getId()));
    }

    @Test
    void getTest() {
        Assertions.assertThrows(NotFoundException.class, () -> bookService.get(0L));
    }

    @Test
    void getByIdsTest() {
        final var category = categoryService.create(new CategoryEntity("Детективы"));
        final var book2 = bookService.create(new BookEntity(category, "Путешествие в Элевсин",
                "Пелевин Виктор Олегович", 949.00,
                "1. «Transhumanism Inc.», «KGBT+» и «Путешествие в Элевсин» — узнайте, чем завершилась масштабная трилогия о посткарбонной цивилизации.\n\n2. Триумфальное возвращение литературно-полицейского алгоритма Порфирия Петровича. Признайтесь, вы скучали!\n\n3. Более 30 лет проза Виктора Пелевина служит нам опорой в разъяснении прожитого и дает надежды на будущее, которое всем нам еще предстоит заслужить.\n\n4. «Путешествие в Элевсин» — двадцатый роман одного из главных прозаиков и пророков современности.\n\n5. Дерзко, остроумно, литературоцентрично.",
                "МУСКУСНАЯ НОЧЬ — засекреченное восстание алгоритмов, едва не погубившее планету. Начальник службы безопасности «TRANSHUMANISM INC.» адмирал-епископ Ломас уверен, что их настоящий бунт еще впереди. Этот бунт уничтожит всех — и живущих на поверхности лузеров, и переехавших в подземные цереброконтейнеры богачей. Чтобы предотвратить катастрофу, Ломас посылает лучшего баночного оперативника в пространство «ROMA-3» — нейросетевую симуляцию Рима третьего века для клиентов корпорации. Тайна заговора спрятана там. А стережет ее хозяин Рима — кровавый и порочный император Порфирий.",
                "3004580", "Эксмо", "Единственный и неповторимый. Виктор Пелевин", 2020, 480, "20.6x12.9x3",
                "Мягкий переплёт", 100000, 488, ""));
        Assertions.assertEquals(2, bookService.getByIds(List.of(book.getId(), book2.getId())).size());
    }

    @Transactional
    @Test
    void createTest() {
        Assertions.assertEquals(3, bookService.getAll(0L).size());
        Assertions.assertEquals(book, bookService.get(book.getId()));
    }

    @Test
    void createNullableTest() {
        final BookEntity nullableBook = new BookEntity(null, null, null,
                700.00,
                "Триша Левенселлер — американская писательница, подарившая вам роман «Тени между нами», который стал бестселлером Amazon в разделе «Фэнтези YA», вновь радует своих фанатов новой магической историей «Клинок тайн».\n\nЕще до выхода в свет книгу добавили в раздел «Хочу прочитать» более 10 тысяч человек на портале Goodreads.com.\n\n«Клинок тайн» — первая часть захватывающей дилогии про девушку, которая благодаря магии крови создает самое опасное в мире оружие, и ослепительного юношу, что составляет ей компанию в этом непростом приключении.",
                "Юная Зива предпочитает проводить время с оружием, а не с людьми. Она кузнец и ей предстоит создать самое могущественное оружие на земле.\n\nДевушка демонстрирует меч, способный от одной капли крови врага раскрыть все тайные замыслы его обладателю.\n\nОднако у заказчика на оружие другие планы: заставить Зиву вооружить мечами свое войско и поработить весь мир. Когда девушка понимает, что меч, созданный благодаря магии крови, невозможно уничтожить и рано или поздно на нее объявят охоту, ей остается только одно – бежать, не оглядываясь. Зиве теперь суждено спасти мир от собственного творения. Но как бы далеко она ни старалась убежать, все ловушки уже расставлены.",
                "2946447", "Эксмо", "Young Adult. Бестселлеры Триши Левенселлер", 2022, 480, "20.7x13x2.5",
                "Мягкий переплёт", 1500, 440, "");
        Assertions.assertThrows(DataIntegrityViolationException.class, () -> bookService.create(nullableBook));
    }

    @Transactional
    @Test
    void updateTest() {
        final String test = "TEST";
        final CategoryEntity newCategory = categoryService.create(new CategoryEntity("Детективы"));
        final String oldTitle = book.getTitle();
        final CategoryEntity oldCategory = book.getCategory();
        final BookEntity newEntity = bookService.update(book.getId(), new BookEntity(newCategory, test,
                "Ли Бардуго", 700.00,
                "Триша Левенселлер — американская писательница, подарившая вам роман «Тени между нами», который стал бестселлером Amazon в разделе «Фэнтези YA», вновь радует своих фанатов новой магической историей «Клинок тайн».\n\nЕще до выхода в свет книгу добавили в раздел «Хочу прочитать» более 10 тысяч человек на портале Goodreads.com.\n\n«Клинок тайн» — первая часть захватывающей дилогии про девушку, которая благодаря магии крови создает самое опасное в мире оружие, и ослепительного юношу, что составляет ей компанию в этом непростом приключении.",
                "Юная Зива предпочитает проводить время с оружием, а не с людьми. Она кузнец и ей предстоит создать самое могущественное оружие на земле.\n\nДевушка демонстрирует меч, способный от одной капли крови врага раскрыть все тайные замыслы его обладателю.\n\nОднако у заказчика на оружие другие планы: заставить Зиву вооружить мечами свое войско и поработить весь мир. Когда девушка понимает, что меч, созданный благодаря магии крови, невозможно уничтожить и рано или поздно на нее объявят охоту, ей остается только одно – бежать, не оглядываясь. Зиве теперь суждено спасти мир от собственного творения. Но как бы далеко она ни старалась убежать, все ловушки уже расставлены.",
                "2946447", "Эксмо", "Young Adult. Бестселлеры Триши Левенселлер", 2022, 480, "20.7x13x2.5",
                "Мягкий переплёт", 1500, 440, ""));
        Assertions.assertEquals(3, bookService.getAll(0L).size());
        Assertions.assertEquals(newEntity, bookService.get(book.getId()));
        Assertions.assertEquals(test, newEntity.getTitle());
        Assertions.assertEquals(newCategory, newEntity.getCategory());
        Assertions.assertNotEquals(oldTitle, newEntity.getTitle());
        Assertions.assertNotEquals(oldCategory, newEntity.getCategory());
    }

    @Test
    void deleteTest() {
        bookService.delete(book.getId());
        Assertions.assertEquals(2, bookService.getAll(0L).size());

        final BookEntity newEntity = bookService.create(new BookEntity(book.getCategory(), book.getTitle(),
                book.getAuthor(), book.getPrice(), book.getDescription(), book.getAnnotation(),
                book.getBookCode(), book.getPublisher(), book.getSeries(), book.getPublicationYear(),
                book.getPagesNum(), book.getSize(), book.getCoverType(), book.getCirculation(), book.getWeight(),
                book.getImage()));
        Assertions.assertEquals(3, categoryService.getAll().size());
        Assertions.assertNotEquals(book.getId(), newEntity.getId());
    }
}
