<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CoreBundle\Entity\Offer;

use Doctrine\Common\Collections\Collection;
use Ferienpass\CoreBundle\Entity\Attendance;
use Ferienpass\CoreBundle\Entity\Edition;
use Ferienpass\CoreBundle\Entity\Host;
use Ferienpass\CoreBundle\Entity\OfferAttachment;
use Ferienpass\CoreBundle\Entity\OfferDate;
use Ferienpass\CoreBundle\Entity\OfferMedia;
use Ferienpass\CoreBundle\Entity\OfferMemberAssociation;
use Ferienpass\CoreBundle\Entity\Participant\ParticipantInterface;
use Ferienpass\CoreBundle\Entity\User;
use Symfony\Component\String\Slugger\SluggerInterface;
use Symfony\Component\Uid\Uuid;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

interface OfferInterface
{
    public function getId(): ?int;

    public function getUuid(): Uuid;

    public function getEdition(): ?Edition;

    public function getName(): string;

    public function getAlias(): ?string;

    public function getRandomSeed(): ?string;

    public function getMeetingPoint(): ?string;

    public function setMeetingPoint(?string $meetingPoint): void;

    public function getMeetingAddress(): ?string;

    public function setMeetingAddress(?string $meetingAddress): void;

    public function getMeetingLat(): ?float;

    public function setMeetingLat(?float $meetingLat): void;

    public function getMeetingLng(): ?float;

    public function setMeetingLng(?float $meetingLng): void;

    public function isVariantBase(): bool;

    public function hasVariants(): bool;

    public function isVariant(): bool;

    public function isVariantOf(self $offer): bool;

    public function getVariants(): Collection;

    public function getVariantBase(): ?self;

    /**
     * @return Collection<int, Host>
     */
    public function getHosts(): Collection;

    /**
     * @return Collection<int, User>
     */
    public function getParticipantListRecipients(): Collection;

    // TODO refactor to own interface, make non-nullable
    public function getFee(): ?int;

    public function isOnlinePayable(): bool;

    /**
     * @return Collection<int, OfferDate>
     */
    public function getDates(): Collection;

    public function getApplicationDeadline(): ?\DateTimeImmutable;

    public function getDateBegin(): ?\DateTimeInterface;

    public function getDateEnd(): ?\DateTimeInterface;

    public function isFuture(): bool;

    public function isPast(): bool;

    public function isPublished(): bool;

    public function isFinalized(): bool;

    public function isReviewed(): bool;

    public function getMinParticipants(): ?int;

    public function getMaxParticipants(): ?int;

    public function getVacancies(): ?int;

    public function isFullyBooked(): bool;

    public function isApplicationDeadlineExpired(): bool;

    public function isInstantlyBookable(): bool;

    public function isCancelled(): bool;

    public function isCompleted(): bool;

    public function requiresApplication(): bool;

    public function isOnlineApplication(): bool;

    public function isCollectDateOfBirth(): bool;

    public function getApplicationExtra(): ?array;

    /**
     * @return Collection<OfferAttachment>
     */
    public function getAttachments(): Collection;

    /**
     * @return Collection<OfferMedia>
     */
    public function getMedia(): Collection;

    /**
     * @return Collection<OfferMemberAssociation>
     */
    public function getMemberAssociations(): Collection;

    public function getAttendances(): Collection;

    public function getAttendancesNotHidden(): Collection;

    public function getAttendancesConfirmed(): Collection;

    /**
     * @return Collection<Attendance>
     */
    public function getAttendancesWaiting(): Collection;

    public function getAttendancesWaitlisted(): Collection;

    public function getAttendancesConfirmedOrWaiting(): Collection;

    public function getAttendancesConfirmedOrWaitlisted(): Collection;

    public function addAttendance(Attendance $attendance): void;

    public function addMemberAssociation(OfferMemberAssociation $association): void;

    public function generateAlias(SluggerInterface $slugger): void;

    public function getFeePayable(ParticipantInterface $participant, ?EventDispatcherInterface $dispatcher = null): int;

    public function getFriendCodes(): Collection;

    public function setStateManually(string $state): void;

    public function resetStatus(): void;

    public function isDraft(): bool;

    public function getPublish(): string;

    public function setPublish(string $publish): void;

    public function getStatus(): array;

    public function getConversation(): Collection;
}
