<?php

/** @noinspection ALL */

namespace App\Entity\Campaign;

use App\Entity\Campaign;
use App\Entity\Traits\TimestampableTrait;
use Doctrine\ORM\Mapping as ORM;
use Webmozart\Assert\Assert;

/**
 * @ORM\Entity()
 */
class OrganicOverviewCheck
{
    use TimestampableTrait;

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

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

    /**
     * @ORM\Column(type="integer")
     */
    private $total;

    /**
     * @ORM\Column(type="float")
     */
    private $visibility;

    /**
     * @ORM\Column(type="float")
     */
    private $differenceVisibility;

    /**
     * @ORM\Column(type="integer")
     */
    private $top100;

    /**
     * @ORM\Column(type="integer")
     */
    private $top100Improved;

    /**
     * @ORM\Column(type="integer")
     */
    private $top100Declined;

    /**
     * @ORM\Column(type="integer")
     */
    private $top100Difference;

    /**
     * @ORM\Column(type="integer")
     */
    private $top100Left;

    /**
     * @ORM\Column(type="integer")
     */
    private $top100Entered;

    /**
     * @ORM\Column(type="integer")
     */
    private $top3;

    /**
     * @ORM\Column(type="integer")
     */
    private $top3Improved;

    /**
     * @ORM\Column(type="integer")
     */
    private $top3Declined;

    /**
     * @ORM\Column(type="integer")
     */
    private $top3Difference;

    /**
     * @ORM\Column(type="integer")
     */
    private $top3Left;

    /**
     * @ORM\Column(type="integer")
     */
    private $top3Entered;

    /**
     * @ORM\Column(type="integer")
     */
    private $top10;

    /**
     * @ORM\Column(type="integer")
     */
    private $top10Improved;

    /**
     * @ORM\Column(type="integer")
     */
    private $top10Declined;

    /**
     * @ORM\Column(type="integer")
     */
    private $top10Difference;

    /**
     * @ORM\Column(type="integer")
     */
    private $top10Left;

    /**
     * @ORM\Column(type="integer")
     */
    private $top10Entered;

    /**
     * @ORM\Column(type="integer")
     */
    private $top20;

    /**
     * @ORM\Column(type="integer")
     */
    private $top20Improved;

    /**
     * @ORM\Column(type="integer")
     */
    private $top20Declined;

    /**
     * @ORM\Column(type="integer")
     */
    private $top20Difference;

    /**
     * @ORM\Column(type="integer")
     */
    private $top20Left;

    /**
     * @ORM\Column(type="integer")
     */
    private $top20Entered;

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

    /**
     * @param array $data
     *
     * @return OrganicOverviewCheck
     */
    public static function fromArray(array $data)
    {
        $check = new self();

        try {
            Assert::keyExists($data, 'total');
            Assert::keyExists($data, 'visibility');
            Assert::keyExists($data, 'differenceVisibility');
            Assert::keyExists($data, 'all');
            Assert::keyExists($data, 'all_improved');
            Assert::keyExists($data, 'all_declined');
            Assert::keyExists($data, 'all_difference');
            Assert::keyExists($data, 'all_left');
            Assert::keyExists($data, 'all_entered');
            Assert::keyExists($data, 'top3');
            Assert::keyExists($data, 'top3_improved');
            Assert::keyExists($data, 'top3_declined');
            Assert::keyExists($data, 'top3_difference');
            Assert::keyExists($data, 'top3_left');
            Assert::keyExists($data, 'top3_entered');
            Assert::keyExists($data, 'top10');
            Assert::keyExists($data, 'top10_improved');
            Assert::keyExists($data, 'top10_declined');
            Assert::keyExists($data, 'top10_difference');
            Assert::keyExists($data, 'top10_left');
            Assert::keyExists($data, 'top10_entered');
            Assert::keyExists($data, 'top20');
            Assert::keyExists($data, 'top20_improved');
            Assert::keyExists($data, 'top20_declined');
            Assert::keyExists($data, 'top20_difference');
            Assert::keyExists($data, 'top20_left');
            Assert::keyExists($data, 'top20_entered');
            Assert::keyExists($data, 'data');
        } catch (\Exception $exception) {
            throw $exception;
        }

        $check->setTotal($data['total'])
            ->setVisibility($data['visibility'])
            ->setDifferenceVisibility($data['differenceVisibility'])
            ->setTop100($data['all'])
            ->setTop100Improved($data['all_improved'])
            ->setTop100Declined($data['all_declined'])
            ->setTop100Difference($data['all_difference'])
            ->setTop100Left($data['all_left'])
            ->setTop100Entered($data['all_entered'])
            ->setTop3($data['top3'])
            ->setTop3Improved($data['top3_improved'])
            ->setTop3Declined($data['top3_declined'])
            ->setTop3Difference($data['top3_difference'])
            ->setTop3Left($data['top3_left'])
            ->setTop3Entered($data['top3_entered'])
            ->setTop10($data['top10'])
            ->setTop10Improved($data['top10_improved'])
            ->setTop10Declined($data['top10_declined'])
            ->setTop10Difference($data['top10_difference'])
            ->setTop10Left($data['top10_left'])
            ->setTop10Entered($data['top10_entered'])
            ->setTop20($data['top20'])
            ->setTop20Improved($data['top20_improved'])
            ->setTop20Declined($data['top20_declined'])
            ->setTop20Difference($data['top20_difference'])
            ->setTop20Left($data['top20_left'])
            ->setTop20Entered($data['top20_entered'])
            ->setData(json_encode($data['data'], JSON_FORCE_OBJECT));

        return $check;
    }

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

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

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

        return $this;
    }

    public function getTotal(): ?int
    {
        return $this->total;
    }

    public function setTotal(int $total): self
    {
        $this->total = $total;

        return $this;
    }

    public function getVisibility(): ?float
    {
        return $this->visibility;
    }

    public function setVisibility(float $visibility): self
    {
        $this->visibility = $visibility;

        return $this;
    }

    public function getDifferenceVisibility(): ?float
    {
        return $this->differenceVisibility;
    }

    public function setDifferenceVisibility(float $differenceVisibility): self
    {
        $this->differenceVisibility = $differenceVisibility;

        return $this;
    }

    public function getTop100(): ?int
    {
        return $this->top100;
    }

    public function setTop100(int $top100): self
    {
        $this->top100 = $top100;

        return $this;
    }

    public function getTop100Improved(): ?int
    {
        return $this->top100Improved;
    }

    public function setTop100Improved(int $top100Improved): self
    {
        $this->top100Improved = $top100Improved;

        return $this;
    }

    public function getTop100Declined(): ?int
    {
        return $this->top100Declined;
    }

    public function setTop100Declined(int $top100Declined): self
    {
        $this->top100Declined = $top100Declined;

        return $this;
    }

    public function getTop100Difference(): ?int
    {
        return $this->top100Difference;
    }

    public function setTop100Difference(int $top100Difference): self
    {
        $this->top100Difference = $top100Difference;

        return $this;
    }

    public function getTop100Left(): ?int
    {
        return $this->top100Left;
    }

    public function setTop100Left(int $top100Left): self
    {
        $this->top100Left = $top100Left;

        return $this;
    }

    public function getTop100Entered(): ?int
    {
        return $this->top100Entered;
    }

    public function setTop100Entered(int $top100Entered): self
    {
        $this->top100Entered = $top100Entered;

        return $this;
    }

    public function getTop3(): ?int
    {
        return $this->top3;
    }

    public function setTop3(int $top3): self
    {
        $this->top3 = $top3;

        return $this;
    }

    public function getTop3Improved(): ?int
    {
        return $this->top3Improved;
    }

    public function setTop3Improved(int $top3Improved): self
    {
        $this->top3Improved = $top3Improved;

        return $this;
    }

    public function getTop3Declined(): ?int
    {
        return $this->top3Declined;
    }

    public function setTop3Declined(int $top3Declined): self
    {
        $this->top3Declined = $top3Declined;

        return $this;
    }

    public function getTop3Difference(): ?int
    {
        return $this->top3Difference;
    }

    public function setTop3Difference(int $top3Difference): self
    {
        $this->top3Difference = $top3Difference;

        return $this;
    }

    public function getTop3Left(): ?int
    {
        return $this->top3Left;
    }

    public function setTop3Left(int $top3Left): self
    {
        $this->top3Left = $top3Left;

        return $this;
    }

    public function getTop3Entered(): ?int
    {
        return $this->top3Entered;
    }

    public function setTop3Entered(int $top3Entered): self
    {
        $this->top3Entered = $top3Entered;

        return $this;
    }

    public function getTop10(): ?int
    {
        return $this->top10;
    }

    public function setTop10(int $top10): self
    {
        $this->top10 = $top10;

        return $this;
    }

    public function getTop10Improved(): ?string
    {
        return $this->top10Improved;
    }

    public function setTop10Improved(string $top10Improved): self
    {
        $this->top10Improved = $top10Improved;

        return $this;
    }

    public function getTop10Declined(): ?int
    {
        return $this->top10Declined;
    }

    public function setTop10Declined(int $top10Declined): self
    {
        $this->top10Declined = $top10Declined;

        return $this;
    }

    public function getTop10Difference(): ?int
    {
        return $this->top10Difference;
    }

    public function setTop10Difference(int $top10Difference): self
    {
        $this->top10Difference = $top10Difference;

        return $this;
    }

    public function getTop10Left(): ?int
    {
        return $this->top10Left;
    }

    public function setTop10Left(int $top10Left): self
    {
        $this->top10Left = $top10Left;

        return $this;
    }

    public function getTop10Entered(): ?int
    {
        return $this->top10Entered;
    }

    public function setTop10Entered(int $top10Entered): self
    {
        $this->top10Entered = $top10Entered;

        return $this;
    }

    public function getTop20(): ?int
    {
        return $this->top20;
    }

    public function setTop20(int $top20): self
    {
        $this->top20 = $top20;

        return $this;
    }

    public function getTop20Improved(): ?int
    {
        return $this->top20Improved;
    }

    public function setTop20Improved(int $top20Improved): self
    {
        $this->top20Improved = $top20Improved;

        return $this;
    }

    public function getTop20Declined(): ?int
    {
        return $this->top20Declined;
    }

    public function setTop20Declined(int $top20Declined): self
    {
        $this->top20Declined = $top20Declined;

        return $this;
    }

    public function getTop20Difference(): ?int
    {
        return $this->top20Difference;
    }

    public function setTop20Difference(int $top20Difference): self
    {
        $this->top20Difference = $top20Difference;

        return $this;
    }

    public function getTop20Left(): ?int
    {
        return $this->top20Left;
    }

    public function setTop20Left(int $top20Left): self
    {
        $this->top20Left = $top20Left;

        return $this;
    }

    public function getTop20Entered(): ?int
    {
        return $this->top20Entered;
    }

    public function setTop20Entered(int $top20Entered): self
    {
        $this->top20Entered = $top20Entered;

        return $this;
    }

    public function getData(): ?array
    {
        return json_decode($this->data, true);
    }

    public function setData(?string $data): self
    {
        $this->data = $data;

        return $this;
    }
}
