<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use App\Repository\DocumentRepository;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity(repositoryClass=DocumentRepository::class)
 * @ORM\InheritanceType("JOINED")
 * @Gedmo\Loggable
 */
class Document
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity=User::class, inversedBy="documents")
     * @ORM\JoinColumn(nullable=false)
     */
    private $creator;

    /**
     * @ORM\ManyToOne(targetEntity=Group::class, inversedBy="documents")
     * @ORM\JoinColumn(nullable=false)
     */
    private $mainGroup;

    /**
     * @ORM\Column(type="datetime_immutable")
     * @Gedmo\Timestampable(on="create")
     */
    private $createdAt;

    /**
     * @ORM\Column(type="string", length=255)
     * @Gedmo\Versioned
     */
    private $share;

    /**
     * @Gedmo\Versioned
     * @ORM\Column(type="string", length=255)
     */
    private $title;

    /**
     * @ORM\ManyToMany(targetEntity=Group::class, inversedBy="allowedDocuments")
     */
    private $allowedGroups;

    /**
     * @Gedmo\Versioned
     * @ORM\Column(type="boolean", options={"default":"0"})
     */
    private $allowShare = false;

    /**
     * @ORM\OneToMany(targetEntity=Comment::class, mappedBy="document")
     */
    private $comments;

    /**
     * @ORM\Column(type="boolean", options={"default":"0"})
     * @Gedmo\Versioned
     */
    private $archive = false;

    /**
     * True if legal Access is needed
     * @ORM\Column(type="boolean", options={"default":"0"})
     */
    private $needLegalAccess = false;

    /**
     * True if medical Access is needed
     * @ORM\Column(type="boolean", options={"default":"0"})
     */
    private $needMedicalAccess = false;

    /**
     * True if Group Administration Access is needed
     * @ORM\Column(type="boolean", options={"default":"0"})
     */
    private $needGroupAdministration = false;

    /**
     * True if document is public to all groups who have "gang" access
     * @ORM\Column(type="boolean", options={"default":"0"})
     */
    private $isPublic = false;

    /**
     * @ORM\ManyToMany(targetEntity=Folder::class, mappedBy="documents")
     */
    private $folders;

    /**
     * @ORM\ManyToMany(targetEntity=SubGroup::class, inversedBy="documents")
     */
    private $allowedSubGroups;



    public function __construct(User $user)
    {
        $this->allowedGroups = new ArrayCollection();
        $this->share = uniqid();

        $this->setCreator($user);
        $this->setMainGroup($user->getMainGroup());
        $this->addAllowedGroup($this->getMainGroup());

        $this->comments = new ArrayCollection();
        $this->folders = new ArrayCollection();
        $this->allowedSubGroups = new ArrayCollection();
    }

    public function getClass(): ?string
    {
        return get_class($this);
    }

    public function getClassShort(): ?string
    {
        if ($pos = strrpos($this->getClass(), '\\')) {
            return substr($this->getClass(), $pos + 1);
        }
        return $pos;
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getCreator(): ?User
    {
        return $this->creator;
    }

    public function setCreator(?User $creator): self
    {
        $this->creator = $creator;

        return $this;
    }

    public function getMainGroup(): ?Group
    {
        return $this->mainGroup;
    }

    public function setMainGroup(?Group $mainGroup): self
    {
        $this->mainGroup = $mainGroup;

        return $this;
    }

    public function getCreatedAt(): ?\DateTimeImmutable
    {
        return $this->createdAt;
    }

    public function setCreatedAt(\DateTimeImmutable $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    public function getShare(): ?string
    {
        return $this->share;
    }

    public function setShare(string $share): self
    {
        $this->share = $share;

        return $this;
    }

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

    public function setTitle(string $title): self
    {
        $this->title = $title;

        return $this;
    }

    /**
     * @return Collection|Group[]
     */
    public function getAllowedGroups(): Collection
    {
        if (!$this->allowedGroups->contains($this->getMainGroup())) {
            $this->allowedGroups[] = $this->getMainGroup();
        }
        return $this->allowedGroups;
    }

    public function addAllowedGroup(Group $allowedGroup): self
    {
        if (!$this->allowedGroups->contains($allowedGroup)) {
            $this->allowedGroups[] = $allowedGroup;
        }

        return $this;
    }

    public function removeAllowedGroup(Group $allowedGroup): self
    {
        $this->allowedGroups->removeElement($allowedGroup);

        return $this;
    }

    public function getAllowShare(): ?bool
    {
        return $this->allowShare;
    }

    public function setAllowShare(bool $allowShare): self
    {
        $this->allowShare = $allowShare;

        return $this;
    }


    /**
     * @return Collection|Comment[]
     */
    public function getComments(): Collection
    {
        return $this->comments;
    }

    public function addComment(Comment $comment): self
    {
        if (!$this->comments->contains($comment)) {
            $this->comments[] = $comment;
            $comment->setDocument($this);
        }

        return $this;
    }

    public function removeComment(Comment $comment): self
    {
        if ($this->comments->removeElement($comment)) {
            // set the owning side to null (unless already changed)
            if ($comment->getDocument() === $this) {
                $comment->setDocument(null);
            }
        }

        return $this;
    }

    public function getArchive(): ?bool
    {
        return $this->archive;
    }

    public function setArchive(bool $archive): self
    {
        $this->archive = $archive;

        return $this;
    }

    public function getNeedLegalAccess(): ?bool
    {
        return $this->needLegalAccess;
    }

    public function setNeedLegalAccess(bool $needLegalAccess): self
    {
        $this->needLegalAccess = $needLegalAccess;

        return $this;
    }

    public function getNeedMedicalAccess(): ?bool
    {
        return $this->needMedicalAccess;
    }

    public function setNeedMedicalAccess(bool $needMedicalAccess): self
    {
        $this->needMedicalAccess = $needMedicalAccess;

        return $this;
    }

    public function getNeedGroupAdministration(): ?bool
    {
        return $this->needGroupAdministration;
    }

    public function setNeedGroupAdministration(bool $needGroupAdministration): self
    {
        $this->needGroupAdministration = $needGroupAdministration;

        return $this;
    }

    public function getIsPublic(): ?bool
    {
        return $this->isPublic;
    }

    public function setIsPublic(bool $isPublic): self
    {
        $this->isPublic = $isPublic;

        return $this;
    }

    /**
     * @return Collection|Folder[]
     */
    public function getFolders(): Collection
    {
        return $this->folders;
    }

    public function addFolder(Folder $folder): self
    {
        if (!$this->folders->contains($folder)) {
            $this->folders[] = $folder;
            $folder->addDocument($this);
        }

        return $this;
    }

    public function removeFolder(Folder $folder): self
    {
        if ($this->folders->removeElement($folder)) {
            $folder->removeDocument($this);
        }

        return $this;
    }

    /**
     * @return Collection|SubGroup[]
     */
    public function getAllowedSubGroups(): Collection
    {
        return $this->allowedSubGroups;
    }

    public function addAllowedSubGroup(SubGroup $allowedSubGroup): self
    {
        if (!$this->allowedSubGroups->contains($allowedSubGroup)) {
            $this->allowedSubGroups[] = $allowedSubGroup;
        }

        return $this;
    }

    public function removeAllowedSubGroup(SubGroup $allowedSubGroup): self
    {
        $this->allowedSubGroups->removeElement($allowedSubGroup);

        return $this;
    }
}
