<?php

// documentation : 
// upload file : https://github.com/dustin10/VichUploaderBundle/blob/master/docs/index.md
// enum type : https://knplabs.com/en/blog/how-to-map-a-php-enum-with-doctrine-in-a-symfony-project/

namespace App\Entity;

use App\Entity\SponsorType;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use App\Repository\SponsorRepository;
use App\Entity\Interface\ICachableImage;
use App\Entity\Trait\TimestampableTrait;
use App\Entity\Trait\ForceUpdatableTrait;
use App\Entity\Interface\CachedImageColumn;
use App\Entity\Interface\CachedImageDimensions;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\HttpFoundation\File\File;
use Doctrine\Common\Collections\ArrayCollection;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Table(name: 'sponsor')]
#[ORM\Entity(repositoryClass: SponsorRepository::class)]
#[ORM\HasLifecycleCallbacks]
#[Vich\Uploadable]
class Sponsor implements ICachableImage
{
    use TimestampableTrait;
    use ForceUpdatableTrait;

    const t_root = "admin.sponsor";

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 150)]
    #[Assert\Length(min: 3, minMessage: 'admin.sponsor.fields.@name.errors.min-length')]
    #[Assert\Length(max: 150, maxMessage: 'admin.sponsor.fields.@name.errors.max-length')]
    private ?string $name = null;

    #[ORM\Column(type: "sponsor_type_enum")]
    private ?SponsorType $type = null;

    #[ORM\Column(name: 'logo', length: 255, nullable: true)]
    // #[Assert\File(extensions: ['png', 'jpg', 'jpeg'], extensionsMessage: 'Type de fichier non valide')]
    private ?string $logoFileName = null;

    // NOTE: This is not a mapped field of entity metadata, just a simple property.
    #[Vich\UploadableField(mapping: 'sponsors', fileNameProperty: 'logoFileName')] //, size: 'logoSize')]
    private ?File $logoFile = null;

    #[ORM\OneToMany(mappedBy: 'sponsor', targetEntity: User::class)]
    private Collection $users;

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

    #[Assert\Url(protocols: ['https'], message: self::t_root . ".fields.@url.errors.url-invalid")]
    #[ORM\Column(length: 255, nullable: true)]
    private ?string $url = null;

    #[ORM\OneToMany(mappedBy: 'sponsor', targetEntity: EventSponsor::class, orphanRemoval: true)]
    private Collection $events;

    #[ORM\Column(options: ["default" => true])]
    private ?bool $active = null;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $address = null;

    #[ORM\Column(length: 20, nullable: true)]
    private ?string $phone = null;

    #[ORM\Column(length: 100, nullable: true)]
    private ?string $email = null;

    #[ORM\Column(length: 255)]
    private ?string $sort_name = null;


    // private ?LoggerInterface $logger;

    public function __construct() //LoggerInterface $logger)
    {
        $this->users = new ArrayCollection();
        $this->events = new ArrayCollection();
        // $this->logger = $logger;
    }

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

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

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

        return $this;
    }

    public function getType(): ?SponsorType
    {
        return $this->type;
    }

    public function setType(SponsorType|string $type): static
    {
        // dd($type);
        if ($type instanceof SponsorType) {
            $this->type = $type;
        } else {
            $this->type = SponsorType::from($type);
        }
        return $this;
    }    

    public function getLogoFileName(): ?string
    {
        return $this->logoFileName;
    }

    public function setLogoFileName(?string $logoFileName): static
    {
        $this->logoFileName = $logoFileName;
        // dump($logoFileName);
        // $this->logger->alert("setLogoFileName : " . $logoFileName);

        return $this;
    }

    /**
     * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
     * of 'UploadedFile' is injected into this setter to trigger the update. If this
     * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
     * must be able to accept an instance of 'File' as the bundle will inject one here
     * during Doctrine hydration.
     *
     * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile|null $imageFile
     */
    public function setLogoFile(?File $logoFile = null): static
    {
        $this->logoFile = $logoFile;

        if (null !== $logoFile) {
            // It is required that at least one field changes if you are using doctrine
            // otherwise the event listeners won't be called and the file is lost
            $this->updatedAt = new \DateTime();
        }

        return $this;
    }

    public function getLogoFile(): ?File
    {
        return $this->logoFile;
    }

    
    public function getCachedImages() : array {

        $col = new CachedImageColumn();
        $col->field_name = "logoFile";
        $col->filters = [ "sponsor_logo_filter", "whoarewe_sponsor_logo_filter" ];

        // sponsor_logo_filter : fixed / 500 x 50
        // whoarewe_sponsor_logo_filter : fixed / 1000 x 100

        $col->max_dimensions = new CachedImageDimensions();
        $col->max_dimensions->min_width = 1000;
        $col->max_dimensions->min_height = 100;

        return [ "logoFile" => $col ];
    }
    
    /**
     * @return Collection<int, User>
     */
    public function getUsers(): Collection
    {
        return $this->users;
    }

    public function addUser(User $user): static
    {
        if (!$this->users->contains($user)) {
            $this->users->add($user);
            $user->setSponsor($this);
        }

        return $this;
    }

    public function removeUser(User $user): static
    {
        if ($this->users->removeElement($user)) {
            // set the owning side to null (unless already changed)
            if ($user->getSponsor() === $this) {
                $user->setSponsor(null);
            }
        }

        return $this;
    }

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

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

        return $this;
    }

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

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

        return $this;
    }

    /**
     * @return Collection<int, EventSponsor>
     */
    public function getEvents(): Collection
    {
        return $this->events;
    }

    public function addEvent(EventSponsor $event): static
    {
        if (!$this->events->contains($event)) {
            $this->events->add($event);
            $event->setSponsor($this);
        }

        return $this;
    }

    public function removeEvent(EventSponsor $event): static
    {
        if ($this->events->removeElement($event)) {
            // set the owning side to null (unless already changed)
            if ($event->getSponsor() === $this) {
                $event->setSponsor(null);
            }
        }

        return $this;
    }

    public function isActive(): ?bool
    {
        return $this->active;
    }

    public function setActive(bool $active): static
    {
        $this->active = $active;

        return $this;
    }

    public function getRealRoleForUser(User $user): string
    {
        if (in_array("ROLE_ADMIN", $user->getRoles())) return "ROLE_EDITOR";
        if ($user->getSponsor()->getId() == $this->id) return "ROLE_EDITOR";
        return "ROLE_USER";
    }

    public function __serialize() : array
    {
        return [
            "id"           => $this->id,
            "name"         => $this->name,
            "type"         => $this->type,
            "logo"         => $this->logoFileName,
            "url"          => $this->url,
            "description"  => $this->description,
            "active"       => $this->active,
        ];
    }

    public function __unserialize(array $data)
    {
        $this->id            = $data["id"];
        $this->name          = $data["name"];
        $this->type          = $data["type"];
        $this->logoFileName  = $data["logoFileName"];
        $this->url           = $data["url"];
        $this->description   = $data["description"];
        $this->active        = $data["active"];
    }

    public function getAddress(): ?string
    {
        return $this->address;
    }

    public function setAddress(?string $address): static
    {
        $this->address = $address;

        return $this;
    }

    public function getPhone(): ?string
    {
        return $this->phone;
    }

    public function setPhone(?string $phone): static
    {
        $this->phone = $phone;

        return $this;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function setEmail(?string $email): static
    {
        $this->email = $email;

        return $this;
    }

    public function getSortName(): ?string
    {
        return $this->sort_name;
    }

    public function setSortName(string $sort_name): static
    {
        $this->sort_name = $sort_name;

        return $this;
    }

}
