<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\ActivityBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as Serializer;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

/**
 * Class ActivityType.
 */
#[ORM\Entity]
#[ORM\HasLifecycleCallbacks]
#[ORM\Table(name: 'activitytype')]
class ActivityType
{
    final public const FIELD_INVISIBLE = 0;

    final public const FIELD_OPTIONAL = 1;

    final public const FIELD_REQUIRED = 2;

    /**
     * @deprecated not in use
     */
    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $accompanyingPeriodLabel = '';

    /**
     * @deprecated not in use
     */
    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $accompanyingPeriodVisible = self::FIELD_INVISIBLE;

    #[Groups(['read'])]
    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN)]
    private bool $active = true;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $attendeeLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $attendeeVisible = self::FIELD_OPTIONAL;

    #[ORM\ManyToOne(targetEntity: ActivityTypeCategory::class)]
    private ?ActivityTypeCategory $category = null;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $commentLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $commentVisible = self::FIELD_OPTIONAL;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $dateLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 2])]
    private int $dateVisible = self::FIELD_REQUIRED;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $documentsLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $documentsVisible = self::FIELD_OPTIONAL;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $durationTimeLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $durationTimeVisible = self::FIELD_OPTIONAL;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $emergencyLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $emergencyVisible = self::FIELD_INVISIBLE;

    #[Groups(['docgen:read'])]
    #[ORM\Id]
    #[ORM\Column(name: 'id', type: \Doctrine\DBAL\Types\Types::INTEGER)]
    #[ORM\GeneratedValue(strategy: 'AUTO')]
    private ?int $id = null;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $locationLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $locationVisible = self::FIELD_INVISIBLE;

    #[Groups(['read', 'docgen:read'])]
    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)]
    #[Serializer\Context(['is-translatable' => true], groups: ['docgen:read'])]
    private array $name = [];

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::FLOAT, options: ['default' => '0.0'])]
    private float $ordering = 0.0;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $personLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $personsLabel = '';

    #[Groups(['read'])]
    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $personsVisible = self::FIELD_OPTIONAL;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 2])]
    private int $personVisible = self::FIELD_REQUIRED;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $privateCommentLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $privateCommentVisible = self::FIELD_OPTIONAL;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $reasonsLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $reasonsVisible = self::FIELD_OPTIONAL;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $sentReceivedLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $sentReceivedVisible = self::FIELD_OPTIONAL;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $socialActionsLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $socialActionsVisible = self::FIELD_INVISIBLE;

    /**
     * @deprecated not in use
     */
    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $socialDataLabel = '';

    /**
     * @deprecated not in use
     */
    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $socialDataVisible = self::FIELD_INVISIBLE;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $socialIssuesLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $socialIssuesVisible = self::FIELD_INVISIBLE;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $thirdPartiesLabel = '';

    #[Groups(['read'])]
    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $thirdPartiesVisible = self::FIELD_INVISIBLE;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $travelTimeLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $travelTimeVisible = self::FIELD_OPTIONAL;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $userLabel = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, nullable: false, options: ['default' => ''])]
    private string $usersLabel = '';

    #[Groups(['read'])]
    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 1])]
    private int $usersVisible = self::FIELD_OPTIONAL;

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::SMALLINT, nullable: false, options: ['default' => 2])]
    private int $userVisible = self::FIELD_REQUIRED;

    #[Assert\Callback]
    public function checkSocialActionsVisibility(ExecutionContextInterface $context, mixed $payload)
    {
        if ($this->socialIssuesVisible !== $this->socialActionsVisible) {
            // if social issues are invisible then social actions cannot be optional or required + if social issues are optional then social actions shouldn't be required
            if (
                (0 === $this->socialIssuesVisible && (1 === $this->socialActionsVisible || 2 === $this->socialActionsVisible))
                || (1 === $this->socialIssuesVisible && 2 === $this->socialActionsVisible)
            ) {
                $context
                    ->buildViolation('The socialActionsVisible value is not compatible with the socialIssuesVisible value')
                    ->atPath('socialActionsVisible')
                    ->addViolation();
            }
        }
    }

    /**
     * Get active
     * return true if the type is active.
     */
    public function getActive(): bool
    {
        return $this->active;
    }

    public function getAttendeeLabel(): string
    {
        return $this->attendeeLabel;
    }

    public function getAttendeeVisible(): int
    {
        return $this->attendeeVisible;
    }

    public function getCategory(): ?ActivityTypeCategory
    {
        return $this->category;
    }

    public function getCommentLabel(): string
    {
        return $this->commentLabel;
    }

    public function getCommentVisible(): int
    {
        return $this->commentVisible;
    }

    public function getDateLabel(): string
    {
        return $this->dateLabel;
    }

    public function getDateVisible(): int
    {
        return $this->dateVisible;
    }

    public function getDocumentsLabel(): string
    {
        return $this->documentsLabel;
    }

    public function getDocumentsVisible(): int
    {
        return $this->documentsVisible;
    }

    public function getDurationTimeLabel(): string
    {
        return $this->durationTimeLabel;
    }

    public function getDurationTimeVisible(): int
    {
        return $this->durationTimeVisible;
    }

    public function getEmergencyLabel(): string
    {
        return $this->emergencyLabel;
    }

    public function getEmergencyVisible(): int
    {
        return $this->emergencyVisible;
    }

    /**
     * Get id.
     */
    public function getId(): int
    {
        return $this->id;
    }

    public function getLabel(string $field): ?string
    {
        $property = $field.'Label';

        if (!property_exists($this, $property)) {
            throw new \InvalidArgumentException('Field "'.$field.'" not found');
        }

        /* @phpstan-ignore-next-line */
        return $this->{$property};
    }

    public function getLocationLabel(): ?string
    {
        return $this->locationLabel;
    }

    public function getLocationVisible(): ?int
    {
        return $this->locationVisible;
    }

    /**
     * Get name.
     */
    public function getName(): array
    {
        return $this->name;
    }

    public function getOrdering(): float
    {
        return $this->ordering;
    }

    public function getPersonLabel(): string
    {
        return $this->personLabel;
    }

    public function getPersonsLabel(): string
    {
        return $this->personsLabel;
    }

    public function getPersonsVisible(): int
    {
        return $this->personsVisible;
    }

    public function getPersonVisible(): int
    {
        return $this->personVisible;
    }

    public function getPrivateCommentLabel(): string
    {
        return $this->privateCommentLabel;
    }

    public function getPrivateCommentVisible(): int
    {
        return $this->privateCommentVisible;
    }

    public function getReasonsLabel(): string
    {
        return $this->reasonsLabel;
    }

    public function getReasonsVisible(): int
    {
        return $this->reasonsVisible;
    }

    public function getSentReceivedLabel(): string
    {
        return $this->sentReceivedLabel;
    }

    public function getSentReceivedVisible(): int
    {
        return $this->sentReceivedVisible;
    }

    public function getSocialActionsLabel(): ?string
    {
        return $this->socialActionsLabel;
    }

    public function getSocialActionsVisible(): ?int
    {
        return $this->socialActionsVisible;
    }

    public function getSocialIssuesLabel(): ?string
    {
        return $this->socialIssuesLabel;
    }

    public function getSocialIssuesVisible(): ?int
    {
        return $this->socialIssuesVisible;
    }

    public function getThirdPartiesLabel(): string
    {
        return $this->thirdPartiesLabel;
    }

    public function getThirdPartiesVisible(): int
    {
        return $this->thirdPartiesVisible;
    }

    public function getTravelTimeLabel(): string
    {
        return $this->travelTimeLabel;
    }

    public function getTravelTimeVisible(): int
    {
        return $this->travelTimeVisible;
    }

    public function getUserLabel(): string
    {
        return $this->userLabel;
    }

    public function getUsersLabel(): string
    {
        return $this->usersLabel;
    }

    public function getUsersVisible(): int
    {
        return $this->usersVisible;
    }

    public function getUserVisible(): int
    {
        return $this->userVisible;
    }

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

    /**
     * Is active
     * return true if the type is active.
     */
    public function isActive(): bool
    {
        return $this->getActive();
    }

    public function isRequired(string $field): bool
    {
        $property = $field.'Visible';

        if (!property_exists($this, $property)) {
            throw new \InvalidArgumentException('Field "'.$field.'" not found');
        }

        /* @phpstan-ignore-next-line */
        return self::FIELD_REQUIRED === $this->{$property};
    }

    public function isVisible(string $field): bool
    {
        $property = $field.'Visible';

        if (!property_exists($this, $property)) {
            throw new \InvalidArgumentException('Field "'.$field.'" not found');
        }

        /* @phpstan-ignore-next-line */
        return self::FIELD_INVISIBLE !== $this->{$property};
    }

    /**
     * Set active
     * set to true if the type is active.
     */
    public function setActive(bool $active): self
    {
        $this->active = $active;

        return $this;
    }

    public function setAttendeeLabel(string $attendeeLabel): self
    {
        $this->attendeeLabel = $attendeeLabel;

        return $this;
    }

    public function setAttendeeVisible(int $attendeeVisible): self
    {
        $this->attendeeVisible = $attendeeVisible;

        return $this;
    }

    public function setCategory(?ActivityTypeCategory $category): self
    {
        $this->category = $category;

        return $this;
    }

    public function setCommentLabel(string $commentLabel): self
    {
        $this->commentLabel = $commentLabel;

        return $this;
    }

    public function setCommentVisible(int $commentVisible): self
    {
        $this->commentVisible = $commentVisible;

        return $this;
    }

    public function setDateLabel(string $dateLabel): self
    {
        $this->dateLabel = $dateLabel;

        return $this;
    }

    public function setDateVisible(int $dateVisible): self
    {
        $this->dateVisible = $dateVisible;

        return $this;
    }

    public function setDocumentsLabel(string $documentsLabel): self
    {
        $this->documentsLabel = $documentsLabel;

        return $this;
    }

    public function setDocumentsVisible(int $documentsVisible): self
    {
        $this->documentsVisible = $documentsVisible;

        return $this;
    }

    public function setDurationTimeLabel(string $durationTimeLabel): self
    {
        $this->durationTimeLabel = $durationTimeLabel;

        return $this;
    }

    public function setDurationTimeVisible(int $durationTimeVisible): self
    {
        $this->durationTimeVisible = $durationTimeVisible;

        return $this;
    }

    public function setEmergencyLabel(string $emergencyLabel): self
    {
        $this->emergencyLabel = $emergencyLabel;

        return $this;
    }

    public function setEmergencyVisible(int $emergencyVisible): self
    {
        $this->emergencyVisible = $emergencyVisible;

        return $this;
    }

    public function setLocationLabel(string $locationLabel): self
    {
        $this->locationLabel = $locationLabel;

        return $this;
    }

    public function setLocationVisible(int $locationVisible): self
    {
        $this->locationVisible = $locationVisible;

        return $this;
    }

    /**
     * Set name.
     */
    public function setName(array $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function setOrdering(float $ordering): self
    {
        $this->ordering = $ordering;

        return $this;
    }

    public function setPersonLabel(string $personLabel): self
    {
        $this->personLabel = $personLabel;

        return $this;
    }

    public function setPersonsLabel(string $personsLabel): self
    {
        $this->personsLabel = $personsLabel;

        return $this;
    }

    public function setPersonsVisible(int $personsVisible): self
    {
        $this->personsVisible = $personsVisible;

        return $this;
    }

    public function setPersonVisible(int $personVisible): self
    {
        $this->personVisible = $personVisible;

        return $this;
    }

    public function setPrivateCommentLabel(string $privateCommentLabel): self
    {
        $this->privateCommentLabel = $privateCommentLabel;

        return $this;
    }

    public function setPrivateCommentVisible(int $privateCommentVisible): self
    {
        $this->privateCommentVisible = $privateCommentVisible;

        return $this;
    }

    public function setReasonsLabel(string $reasonsLabel): self
    {
        $this->reasonsLabel = $reasonsLabel;

        return $this;
    }

    public function setReasonsVisible(int $reasonsVisible): self
    {
        $this->reasonsVisible = $reasonsVisible;

        return $this;
    }

    public function setSentReceivedLabel(string $sentReceivedLabel): self
    {
        $this->sentReceivedLabel = $sentReceivedLabel;

        return $this;
    }

    public function setSentReceivedVisible(int $sentReceivedVisible): self
    {
        $this->sentReceivedVisible = $sentReceivedVisible;

        return $this;
    }

    public function setSocialActionsLabel(string $socialActionsLabel): self
    {
        $this->socialActionsLabel = $socialActionsLabel;

        return $this;
    }

    public function setSocialActionsVisible(int $socialActionsVisible): self
    {
        $this->socialActionsVisible = $socialActionsVisible;

        return $this;
    }

    public function setSocialIssuesLabel(string $socialIssuesLabel): self
    {
        $this->socialIssuesLabel = $socialIssuesLabel;

        return $this;
    }

    public function setSocialIssuesVisible(int $socialIssuesVisible): self
    {
        $this->socialIssuesVisible = $socialIssuesVisible;

        return $this;
    }

    public function setThirdPartiesLabel(string $thirdPartiesLabel): self
    {
        $this->thirdPartiesLabel = $thirdPartiesLabel;

        return $this;
    }

    public function setThirdPartiesVisible(int $thirdPartiesVisible): self
    {
        $this->thirdPartiesVisible = $thirdPartiesVisible;

        return $this;
    }

    public function setTravelTimeLabel(string $TravelTimeLabel): self
    {
        $this->travelTimeLabel = $TravelTimeLabel;

        return $this;
    }

    public function setTravelTimeVisible(int $TravelTimeVisible): self
    {
        $this->travelTimeVisible = $TravelTimeVisible;

        return $this;
    }

    public function setUserLabel(string $userLabel): self
    {
        $this->userLabel = $userLabel;

        return $this;
    }

    public function setUsersLabel(string $usersLabel): self
    {
        $this->usersLabel = $usersLabel;

        return $this;
    }

    public function setUsersVisible(int $usersVisible): self
    {
        $this->usersVisible = $usersVisible;

        return $this;
    }

    public function setUserVisible(int $userVisible): self
    {
        $this->userVisible = $userVisible;

        return $this;
    }
}
