<?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\ConsentManager;

use Ferienpass\CoreBundle\Entity\Consent;
use Ferienpass\CoreBundle\Entity\ConsentForm;
use Ferienpass\CoreBundle\Entity\Edition;
use Ferienpass\CoreBundle\Entity\Participant\ParticipantInterface;
use Ferienpass\CoreBundle\Entity\User;

class ConsentState
{
    public function __construct(private readonly ?ConsentForm $consentForm = null, private ?Consent $signature = null, private ?ParticipantInterface $participant = null, private ?User $user = null, private ?string $consentToken = null)
    {
    }

    public function getConsentToken(): ?string
    {
        return $this->consentToken;
    }

    public function setConsentToken(?string $consentToken): void
    {
        $this->consentToken = $consentToken;
    }

    public function getUser(): ?User
    {
        return $this->user ?? $this->signature?->getUser();
    }

    public function getConsentForm(): ?ConsentForm
    {
        return $this->consentForm;
    }

    public function getScopeName(): ?string
    {
        return ($this->consentForm?->getOffer() ?? $this->signature?->getOffer())?->getName() ?? $this->getEditionName();
    }

    public function getEdition(): ?Edition
    {
        return $this->consentForm?->getEdition() ?? $this->consentForm?->getOffer()?->getEdition() ?? $this->signature?->getEdition();
    }

    public function getEditionName(): ?string
    {
        return $this->getEdition()?->getName();
    }

    public function getSubjectName(): ?string
    {
        return $this->participant?->getName() ?? $this->getUser()?->getName() ?? '-';
    }

    public function getSigneeName(): ?string
    {
        return $this->signature?->getUser()->getName();
    }

    public function getParticipant(): ?ParticipantInterface
    {
        return $this->participant;
    }

    public function getTitle(): ?string
    {
        return $this->consentForm?->getTitle();
    }

    public function getTargetId(): string
    {
        $id = $this->consentForm?->getId() ?? ('legacy-'.$this->signature?->getId());

        return 'consent-'.$id.($this->participant ? '-'.$this->participant->getId() : '');
    }

    public function getConsentText(): ?string
    {
        return $this->consentForm?->getText() ?? $this->signature?->getConsentText()?->getText();
    }

    public function isSigned(): bool
    {
        return $this->signature && 1 === $this->signature->getDecision() && $this->signature->isValid($this->getConsentText()) && !$this->signature->isRevoked();
    }

    public function hasSignature(): bool
    {
        return null !== $this->signature;
    }

    public function getSignature(): ?Consent
    {
        return $this->signature;
    }

    public function isAcknowledged(): bool
    {
        return $this->signature && $this->signature->isValid($this->getConsentText()) && !$this->isRevoked();
    }

    public function isRejected(): bool
    {
        return $this->signature && 0 === $this->signature->getDecision() && $this->signature->isValid($this->getConsentText()) && !$this->signature->isRevoked();
    }

    public function isRevoked(): bool
    {
        return true === $this->signature?->isRevoked();
    }

    public function isAgreed(): bool
    {
        return $this->isSigned() || (!$this->isAcknowledged() && $this->isOptOut());
    }

    public function isDisagreed(): bool
    {
        return $this->isRejected() || (!$this->isAcknowledged() && $this->isOptIn());
    }

    public function getCompulsory(): string
    {
        return $this->consentForm?->getCompulsory() ?? 'compulsory';
    }

    public function isCompulsory(): bool
    {
        return \in_array($this->getCompulsory(), ['compulsory', 'force_decision'], true);
    }

    public function isVoluntary(): bool
    {
        return !\in_array($this->getCompulsory(), ['compulsory', 'force_decision'], true);
    }

    public function isOptIn(): bool
    {
        return 'opt-in' === $this->getCompulsory();
    }

    public function isOptOut(): bool
    {
        return 'opt-out' === $this->getCompulsory();
    }

    public function isForceDecision(): bool
    {
        return 'force_decision' === $this->getCompulsory();
    }

    public function getDecision(): ?bool
    {
        if ($this->isSigned()) {
            return true;
        }

        if ($this->isRejected()) {
            return false;
        }

        return null;
    }

    public function isOutstanding(): bool
    {
        if ('compulsory' === $this->getCompulsory()) {
            return !$this->isSigned();
        }

        return !$this->isAcknowledged();
    }
}
