<?php

declare(strict_types=1);

namespace App\Entity\Tenant;

use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Table(name: 'advertisements')]
#[ORM\HasLifecycleCallbacks]
class Advertisement
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: Types::INTEGER)]
    private ?int $id = null;

    #[ORM\Column(type: Types::STRING, length: 255)]
    private string $name;

    #[ORM\Column(type: Types::STRING, length: 50)]
    private string $position;

    #[ORM\Column(type: Types::STRING, length: 20)]
    private string $positionCategory;

    #[ORM\Column(type: Types::STRING, length: 20, options: ['default' => 'image'])]
    private string $adType = 'image';

    #[ORM\Column(type: Types::TEXT, nullable: true)]
    private ?string $content = null;

    #[ORM\Column(type: Types::STRING, length: 500, nullable: true)]
    private ?string $imageUrl = null;

    #[ORM\Column(type: Types::STRING, length: 500, nullable: true)]
    private ?string $targetUrl = null;

    #[ORM\Column(type: Types::STRING, length: 10, nullable: true)]
    private ?string $width = null;

    #[ORM\Column(type: Types::STRING, length: 10, nullable: true)]
    private ?string $height = null;

    #[ORM\Column(type: Types::BOOLEAN, options: ['default' => false])]
    private bool $isPinned = false;

    #[ORM\Column(type: Types::STRING, length: 20, options: ['default' => 'draft'])]
    private string $status = 'draft';

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
    private ?\DateTimeImmutable $startsAt = null;

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
    private ?\DateTimeImmutable $endsAt = null;

    #[ORM\Column(type: Types::INTEGER, options: ['default' => 0])]
    private int $impressionCount = 0;

    #[ORM\Column(type: Types::INTEGER, options: ['default' => 0])]
    private int $clickCount = 0;

    #[ORM\Column(type: Types::JSON, nullable: true)]
    private ?array $targetCategories = null;

    #[ORM\Column(type: Types::JSON, nullable: true)]
    private ?array $targetPages = null;

    #[ORM\Column(type: Types::INTEGER, options: ['default' => 0])]
    private int $displayOrder = 0;

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
    private \DateTimeImmutable $createdAt;

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
    private \DateTimeImmutable $updatedAt;

    private const VALID_POSITION_CATEGORIES = ['alan_reklam', 'altsayfa', 'genel', 'paragraf', 'yan'];
    private const VALID_AD_TYPES = ['image', 'adsense', 'custom_html', 'video'];
    private const VALID_STATUSES = ['draft', 'active', 'paused', 'expired'];

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

    public function getName(): string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getPosition(): string
    {
        return $this->position;
    }

    public function setPosition(string $position): self
    {
        $this->position = $position;

        return $this;
    }

    public function getPositionCategory(): string
    {
        return $this->positionCategory;
    }

    public function setPositionCategory(string $positionCategory): self
    {
        if (!in_array($positionCategory, self::VALID_POSITION_CATEGORIES, true)) {
            throw new \InvalidArgumentException(
                sprintf('Invalid position category "%s". Allowed: %s', $positionCategory, implode(', ', self::VALID_POSITION_CATEGORIES))
            );
        }

        $this->positionCategory = $positionCategory;

        return $this;
    }

    public function getAdType(): string
    {
        return $this->adType;
    }

    public function setAdType(string $adType): self
    {
        if (!in_array($adType, self::VALID_AD_TYPES, true)) {
            throw new \InvalidArgumentException(
                sprintf('Invalid ad type "%s". Allowed: %s', $adType, implode(', ', self::VALID_AD_TYPES))
            );
        }

        $this->adType = $adType;

        return $this;
    }

    public function getContent(): ?string
    {
        return $this->content;
    }

    public function setContent(?string $content): self
    {
        $this->content = $content;

        return $this;
    }

    public function getImageUrl(): ?string
    {
        return $this->imageUrl;
    }

    public function setImageUrl(?string $imageUrl): self
    {
        $this->imageUrl = $imageUrl;

        return $this;
    }

    public function getTargetUrl(): ?string
    {
        return $this->targetUrl;
    }

    public function setTargetUrl(?string $targetUrl): self
    {
        $this->targetUrl = $targetUrl;

        return $this;
    }

    public function getWidth(): ?string
    {
        return $this->width;
    }

    public function setWidth(?string $width): self
    {
        $this->width = $width;

        return $this;
    }

    public function getHeight(): ?string
    {
        return $this->height;
    }

    public function setHeight(?string $height): self
    {
        $this->height = $height;

        return $this;
    }

    public function isPinned(): bool
    {
        return $this->isPinned;
    }

    public function setIsPinned(bool $isPinned): self
    {
        $this->isPinned = $isPinned;

        return $this;
    }

    public function getStatus(): string
    {
        return $this->status;
    }

    public function setStatus(string $status): self
    {
        if (!in_array($status, self::VALID_STATUSES, true)) {
            throw new \InvalidArgumentException(
                sprintf('Invalid status "%s". Allowed: %s', $status, implode(', ', self::VALID_STATUSES))
            );
        }

        $this->status = $status;

        return $this;
    }

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

    public function setStartsAt(?\DateTimeImmutable $startsAt): self
    {
        $this->startsAt = $startsAt;

        return $this;
    }

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

    public function setEndsAt(?\DateTimeImmutable $endsAt): self
    {
        $this->endsAt = $endsAt;

        return $this;
    }

    public function getImpressionCount(): int
    {
        return $this->impressionCount;
    }

    public function setImpressionCount(int $impressionCount): self
    {
        $this->impressionCount = $impressionCount;

        return $this;
    }

    public function incrementImpressionCount(): self
    {
        ++$this->impressionCount;

        return $this;
    }

    public function getClickCount(): int
    {
        return $this->clickCount;
    }

    public function setClickCount(int $clickCount): self
    {
        $this->clickCount = $clickCount;

        return $this;
    }

    public function incrementClickCount(): self
    {
        ++$this->clickCount;

        return $this;
    }

    public function getTargetCategories(): ?array
    {
        return $this->targetCategories;
    }

    public function setTargetCategories(?array $targetCategories): self
    {
        $this->targetCategories = $targetCategories;

        return $this;
    }

    public function getTargetPages(): ?array
    {
        return $this->targetPages;
    }

    public function setTargetPages(?array $targetPages): self
    {
        $this->targetPages = $targetPages;

        return $this;
    }

    public function getDisplayOrder(): int
    {
        return $this->displayOrder;
    }

    public function setDisplayOrder(int $displayOrder): self
    {
        $this->displayOrder = $displayOrder;

        return $this;
    }

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

    public function getUpdatedAt(): \DateTimeImmutable
    {
        return $this->updatedAt;
    }

    #[ORM\PrePersist]
    public function onPrePersist(): void
    {
        $now = new \DateTimeImmutable();
        $this->createdAt = $now;
        $this->updatedAt = $now;
    }

    #[ORM\PreUpdate]
    public function onPreUpdate(): void
    {
        $this->updatedAt = new \DateTimeImmutable();
    }
}
