<?php

namespace App\Entity\Campaign;

use App\Entity\BroadcastableInterface;
use App\Entity\Campaign;
use App\Entity\Campaign\LandingPage\BacklinksReport;
use App\Entity\Campaign\LandingPage\PageAuthority;
use App\Entity\Traits\TimestampableTrait;
use App\Entity\User;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

/**
 * @ORM\Entity()
 * @ORM\Table(name="campaign_landing_page")
 * @UniqueEntity("url")
 */
class LandingPage implements BroadcastableInterface
{
    use TimestampableTrait;

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\Url(protocols = {"http", "https"})
     * @Assert\NotBlank()
     */
    private $url;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Campaign", inversedBy="landingPages")
     * @ORM\JoinColumn(nullable=false, onDelete="cascade")
     * @Assert\NotBlank()
     */
    private $campaign;

    /**
     * @ORM\Column(type="text", nullable=true)
     */
    private $description;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\User")
     * @ORM\JoinColumn(nullable=false)
     * @Gedmo\Blameable(on="create")
     */
    private $createdBy;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\CommentLandingPage", mappedBy="landingPage")
     */
    private $comments;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Campaign\LandingPage\PageAuthority", mappedBy="landingPage")
     */
    private $pageAuthorities;

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Campaign\LandingPage\PageAuthority")
     * @ORM\JoinColumn(onDelete="SET NULL")
     */
    private $latestPageAuthorityCheck;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Campaign\LandingPage\BacklinksReport", mappedBy="landingPage")
     */
    private $backlinksReports;

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Campaign\LandingPage\BacklinksReport")
     * @ORM\JoinColumn(onDelete="SET NULL")
     */
    private $latestBacklinksReport;

    public function __construct()
    {
        $this->pageAuthorities = new ArrayCollection();
        $this->backlinksReports = new ArrayCollection();
    }

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

    public function getUrl(): ?string
    {
        return $this->url;
    }

    public function setUrl(string $url): self
    {
        $this->url = $url;

        return $this;
    }

    public function getCampaign(): ?Campaign
    {
        return $this->campaign;
    }

    public function setCampaign(?Campaign $campaign): self
    {
        $this->campaign = $campaign;

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(?string $description): self
    {
        $this->description = $description;

        return $this;
    }

    public function getCreatedBy(): ?User
    {
        return $this->createdBy;
    }

    public function setCreatedBy(?User $createdBy): self
    {
        $this->createdBy = $createdBy;

        return $this;
    }

    /**
     * @Assert\Callback
     *
     * @param ExecutionContextInterface $context
     * @param                           $payload
     */
    public function validate(ExecutionContextInterface $context, $payload)
    {
        if (!filter_var($this->getUrl(), FILTER_VALIDATE_URL)) {
            $context->buildViolation('This is not valid URL')
                ->atPath('url')
                ->addViolation();
        }
    }

    public function getDataType(): string
    {
        return 'campaignlandingpage';
    }

    /**
     * @return Collection
     */
    public function getPageAuthorities(): Collection
    {
        return $this->pageAuthorities;
    }

    public function addPageAuthority(PageAuthority $pageAuthority): self
    {
        if (!$this->pageAuthorities->contains($pageAuthority)) {
            $this->pageAuthorities[] = $pageAuthority;
            $pageAuthority->setLandingPage($this);
        }

        return $this;
    }

    public function removePageAuthority(PageAuthority $pageAuthority): self
    {
        if ($this->pageAuthorities->contains($pageAuthority)) {
            $this->pageAuthorities->removeElement($pageAuthority);
            // set the owning side to null (unless already changed)
            if ($pageAuthority->getLandingPage() === $this) {
                $pageAuthority->setLandingPage(null);
            }
        }

        return $this;
    }

    public function getLatestPageAuthorityCheck(): ?PageAuthority
    {
        return $this->latestPageAuthorityCheck;
    }

    public function setLatestPageAuthorityCheck(?PageAuthority $latestPageAuthorityCheck): self
    {
        $this->latestPageAuthorityCheck = $latestPageAuthorityCheck;

        return $this;
    }

    /**
     * @return Collection
     */
    public function getBacklinksReports(): Collection
    {
        return $this->backlinksReports;
    }

    public function addBacklinksReport(BacklinksReport $backlinksReport): self
    {
        if (!$this->backlinksReports->contains($backlinksReport)) {
            $this->backlinksReports[] = $backlinksReport;
            $backlinksReport->setLandingPage($this);
        }

        return $this;
    }

    public function removeBacklinksReport(BacklinksReport $backlinksReport): self
    {
        if ($this->backlinksReports->contains($backlinksReport)) {
            $this->backlinksReports->removeElement($backlinksReport);
            // set the owning side to null (unless already changed)
            if ($backlinksReport->getLandingPage() === $this) {
                $backlinksReport->setLandingPage(null);
            }
        }

        return $this;
    }

    public function getLatestBacklinksReport(): ?BacklinksReport
    {
        return $this->latestBacklinksReport;
    }

    public function setLatestBacklinksReport(?BacklinksReport $latestBacklinksReport): self
    {
        $this->latestBacklinksReport = $latestBacklinksReport;

        return $this;
    }
}
