package de.accso.flexinale.infrastructure.persistence.mapper;

import de.accso.flexinale.domain.model.Film;
import de.accso.flexinale.domain.model.KinoSaal;
import de.accso.flexinale.domain.model.Kontingent;
import de.accso.flexinale.domain.model.Vorfuehrung;
import de.accso.flexinale.infrastructure.persistence.FilmEntity;
import de.accso.flexinale.infrastructure.persistence.KinoSaalEntity;
import de.accso.flexinale.infrastructure.persistence.KontingentEntity;
import de.accso.flexinale.infrastructure.persistence.VorfuehrungEntity;
import de.accso.flexinale.shared_kernel.DateTimeHelper;
import de.accso.flexinale.shared_kernel.Identifiable;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static de.accso.flexinale.shared_kernel.RawWrapper.getRawOrNull;

public class VorfuehrungEntity2VorfuehrungMapper {

    public static Vorfuehrung map(final VorfuehrungEntity vorfuehrungEntity) {
        Film mappedFilm = FilmEntity2FilmMapper.map(vorfuehrungEntity.film);
        KinoSaal mappedKinoSaal = KinoKinoSaalEntity2KinoKinoSaalMapper.mapKinoSaal(vorfuehrungEntity.kinoSaal);
        Kontingent mappedKontingent = KontingentEntity2KontingentMapper.map(vorfuehrungEntity.kontingent);

        return new Vorfuehrung(Identifiable.Id.of(vorfuehrungEntity.id), vorfuehrungEntity.version(),
                new Vorfuehrung.Zeit(DateTimeHelper.fromEpochSeconds(vorfuehrungEntity.zeit)),
                mappedFilm, mappedKinoSaal, mappedKontingent);
    }

    @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
    public static Optional<Vorfuehrung> map(final Optional<VorfuehrungEntity> optionalVorfuehrungEntity) {
        if (optionalVorfuehrungEntity.isEmpty()) {
            return Optional.empty();
        }
        else {
            VorfuehrungEntity vorfuehrungEntity = optionalVorfuehrungEntity.get();
            return Optional.of(map(vorfuehrungEntity));
        }
    }

    public static VorfuehrungEntity map(final Vorfuehrung vorfuehrung) {
        FilmEntity mappedFilm = FilmEntity2FilmMapper.map(vorfuehrung.film);
        KinoSaalEntity mappedKinoSaal = KinoKinoSaalEntity2KinoKinoSaalMapper.mapKinoSaal(vorfuehrung.kinoSaal);
        KontingentEntity mappedKontingent = KontingentEntity2KontingentMapper.map(vorfuehrung.getKontingent());

        return new VorfuehrungEntity(vorfuehrung.id().id(), vorfuehrung.version().version(),
                getRawOrNull(vorfuehrung.zeit), mappedFilm, mappedKinoSaal, mappedKontingent);
    }

    public static List<Vorfuehrung> map(final List<VorfuehrungEntity> vorfuehrungEntities) {
        return vorfuehrungEntities.stream().map(VorfuehrungEntity2VorfuehrungMapper::map)
                .collect(Collectors.toCollection(ArrayList::new));
    }
}
