package de.accso.flexinale.domain.model;

import de.accso.flexinale.domain.model.KinoSaal;
import de.accso.flexinale.domain.model.Kontingent;
import de.accso.flexinale.domain.model.KontingentBereitsAusgeschoepftException;
import de.accso.flexinale.domain.model.Vorfuehrung;
import de.accso.flexinale.shared_code_for_test.TestDataBuilder;
import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;

import static de.accso.flexinale.domain.model.Ticket.VerkaufsKanal.KINOKASSE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

class KontingentTest {

    @Test
    void testOnlineKontingentCalculationQuote33() {
        Kontingent kontingent = TestDataBuilder.createKontingent(30, 33);

        assertThat(kontingent.getRestKontingentOnline().raw()).isEqualTo(10);
        assertThat(kontingent.getRestKontingentZentral().raw()).isEqualTo(10);
        assertThat(kontingent.getRestKontingentKinokasse().raw()).isEqualTo(10);
    }

    @Test
    void testOnlineKontingentCalculationQuote25() {
        Kontingent kontingent = TestDataBuilder.createKontingent(30, 25);

        assertThat(kontingent.getRestKontingentOnline().raw()).isEqualTo(8);
        assertThat(kontingent.getRestKontingentZentral().raw()).isEqualTo(11);
        assertThat(kontingent.getRestKontingentKinokasse().raw()).isEqualTo(11);
    }

    @Test
    void testOnlineKontingentCalculationQuote100() {
        Kontingent kontingent = TestDataBuilder.createKontingent(30, 100);

        assertThat(kontingent.getRestKontingentOnline().raw()).isEqualTo(30);
        assertThat(kontingent.getRestKontingentZentral().raw()).isEqualTo(0);
        assertThat(kontingent.getRestKontingentKinokasse().raw()).isEqualTo(0);
    }

    @Test
    void testOnlineKontingentCalculationQuote0() {
        Kontingent kontingent = TestDataBuilder.createKontingent(29, 0);

        assertThat(kontingent.getRestKontingentOnline().raw()).isEqualTo(0);
        assertThat(kontingent.getRestKontingentZentral().raw()).isEqualTo(14);
        assertThat(kontingent.getRestKontingentKinokasse().raw()).isEqualTo(15);
    }

    @Test
    void testNotEnoughKontingent() {
        KinoSaal kinoSaal = TestDataBuilder.createKinoWithKinosaele(20).kinoSaele.iterator().next();
        Vorfuehrung vorfuehrung = TestDataBuilder.createVorfuehrung(LocalDateTime.now(), null, kinoSaal, 90);

        assertThatThrownBy(() -> {
            vorfuehrung.verkaufeTickets(KINOKASSE, 4);
        })
        .isInstanceOf(KontingentBereitsAusgeschoepftException.class);

        assertThat(vorfuehrung.getKontingent().getRestKontingentOnline().raw()).isEqualTo(18);
        assertThat(vorfuehrung.getKontingent().getRestKontingentZentral().raw()).isEqualTo(1);
        assertThat(vorfuehrung.getKontingent().getRestKontingentKinokasse().raw()).isEqualTo(1);
        assertThat(vorfuehrung.getGesamtkapazitaetVerkauf()).isEqualTo(20);
    }
}
