<?php

namespace App\Entity;

use App\Repository\ProductRepository;
use Cocur\Slugify\Slugify;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Attribute\Uploadable;
use Vich\UploaderBundle\Mapping\Attribute\UploadableField;

#[ORM\Entity(repositoryClass: ProductRepository::class)]
#[Uploadable]
class Product
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

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

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

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

    #[ORM\Column]
    private ?float $priceDay = null;

    #[ORM\Column(nullable: true)]
    private ?float $priceSup = null;

    #[ORM\Column]
    private ?float $caution = null;


    #[UploadableField(mapping: 'image_product', fileNameProperty: 'imageName', size: 'imageSize')]
    private ?File $imageFile = null;
    #[ORM\Column(nullable: true)]
    private ?string $imageName = null;

    #[ORM\Column(nullable: true)]
    private ?int $imageSize = null;

    #[ORM\Column(nullable: true)]
    private ?\DateTimeImmutable $updatedAt = null;

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

    /**
     * @var Collection<int, ProductReserve>
     */
    #[ORM\OneToMany(targetEntity: ProductReserve::class, mappedBy: 'product')]
    private Collection $productReserves;

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

    #[ORM\Column(nullable: true)]
    private ?int $qt = null;

    /**
     * @var Collection<int, ProductDoc>
     */
    #[ORM\OneToMany(targetEntity: ProductDoc::class, mappedBy: 'product')]
    private Collection $productDocs;

    #[ORM\Column(nullable: true)]
    private ?float $dimW = null;

    #[ORM\Column(nullable: true)]
    private ?float $dimH = null;

    #[ORM\Column(nullable: true)]
    private ?float $dimP = null;

    /**
     * @var Collection<int, FormulesProductInclus>
     */
    #[ORM\OneToMany(targetEntity: FormulesProductInclus::class, mappedBy: 'PRODUCT')]
    private Collection $formulesProductIncluses;

    /**
     * @var Collection<int, ProductPhotos>
     */
    #[ORM\OneToMany(targetEntity: ProductPhotos::class, mappedBy: 'product')]
    private Collection $productPhotos;

    /**
     * @var Collection<int, ProductVideo>
     */
    #[ORM\OneToMany(targetEntity: ProductVideo::class, mappedBy: 'product')]
    private Collection $productVideos;

    /**
     * @var Collection<int, ProductBlocked>
     */
    #[ORM\OneToMany(targetEntity: ProductBlocked::class, mappedBy: 'product', orphanRemoval: true)]
    private Collection $productBlockeds;

    /**
     * @var Collection<int, ProductPointControll>
     */
    #[ORM\OneToMany(targetEntity: ProductPointControll::class, mappedBy: 'product', orphanRemoval: true)]
    private Collection $productPointControlls;

    #[ORM\Column(nullable: true, options: ['default' => true])]
    private ?bool $isPublish = true;

    /**
     * @var Collection<int, Options>
     */
    #[ORM\ManyToMany(targetEntity: Options::class, inversedBy: 'products')]
    private Collection $options;

    public function __construct()
    {
        $this->productReserves = new ArrayCollection();
        $this->productDocs = new ArrayCollection();
        $this->formulesProductIncluses = new ArrayCollection();
        $this->productPhotos = new ArrayCollection();
        $this->productVideos = new ArrayCollection();
        $this->productBlockeds = new ArrayCollection();
        $this->productPointControlls = new ArrayCollection();
        $this->options = new ArrayCollection();
        $this->isPublish = true;
    }
    public function slug()
    {
        $s = new Slugify();

        return$s->slugify($this->id."-".$this->name);
    }

    public function json()
    {
        return json_encode([
            'id' => $this->id,
            'ref' => $this->ref,
            'name' => $this->name,
        ]);
    }
// ... (omitting existing methods for brevity in replacement search if possible, but replace tool needs exact match or unique context. I will append methods at the end and update constructor separately if needed. Wait, replace needs exact match. I'll do constructor update first)

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

    public function getRef(): ?string
    {
        return $this->ref;
    }

    public function setRef(string $ref): static
    {
        $this->ref = $ref;

        return $this;
    }

    public function getCategory(): ?string
    {
        return $this->category;
    }

    public function setCategory(string $category): static
    {
        $this->category = $category;

        return $this;
    }

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

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

        return $this;
    }

    public function getPriceDay(): ?float
    {
        return $this->priceDay;
    }

    public function setPriceDay(float $priceDay): static
    {
        $this->priceDay = $priceDay;

        return $this;
    }

    public function getPriceSup(): ?float
    {
        return $this->priceSup;
    }

    public function setPriceSup(float $priceSup): static
    {
        $this->priceSup = $priceSup;

        return $this;
    }

    public function getCaution(): ?float
    {
        return $this->caution;
    }

    public function setCaution(float $caution): static
    {
        $this->caution = $caution;

        return $this;
    }

    public function setImageFile(?File $imageFile = null): void
    {
        $this->imageFile = $imageFile;

        if (null !== $imageFile) {
            // 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 \DateTimeImmutable();
        }
    }

    public function getImageFile(): ?File
    {
        return $this->imageFile;
    }

    public function setImageName(?string $imageName): void
    {
        $this->imageName = $imageName;
    }

    public function getImageName(): ?string
    {
        return $this->imageName;
    }

    public function setImageSize(?int $imageSize): void
    {
        $this->imageSize = $imageSize;
    }

    public function getImageSize(): ?int
    {
        return $this->imageSize;
    }

    public function getProductId(): ?string
    {
        return $this->productId;
    }

    public function setProductId(?string $productId): static
    {
        $this->productId = $productId;

        return $this;
    }


    /**
     * @return Collection<int, ProductReserve>
     */
    public function getProductReserves(): Collection
    {
        return $this->productReserves;
    }

    public function addProductReserf(ProductReserve $productReserf): static
    {
        if (!$this->productReserves->contains($productReserf)) {
            $this->productReserves->add($productReserf);
            $productReserf->setProduct($this);
        }

        return $this;
    }

    public function removeProductReserf(ProductReserve $productReserf): static
    {
        if ($this->productReserves->removeElement($productReserf)) {
            // set the owning side to null (unless already changed)
            if ($productReserf->getProduct() === $this) {
                $productReserf->setProduct(null);
            }
        }

        return $this;
    }

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

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

        return $this;
    }

    public function getQt(): ?int
    {
        return $this->qt;
    }

    public function setQt(?int $qt): static
    {
        $this->qt = $qt;

        return $this;
    }

    /**
     * @param \DateTimeImmutable|null $updatedAt
     */
    public function setUpdatedAt(?\DateTimeImmutable $updatedAt): void
    {
        $this->updatedAt = $updatedAt;
    }

    /**
     * @return \DateTimeImmutable|null
     */
    public function getUpdatedAt(): ?\DateTimeImmutable
    {
        return $this->updatedAt;
    }

    /**
     * @return Collection<int, ProductDoc>
     */
    public function getProductDocs(): Collection
    {
        return $this->productDocs;
    }

    public function addProductDoc(ProductDoc $productDoc): static
    {
        if (!$this->productDocs->contains($productDoc)) {
            $this->productDocs->add($productDoc);
            $productDoc->setProduct($this);
        }

        return $this;
    }

    public function removeProductDoc(ProductDoc $productDoc): static
    {
        if ($this->productDocs->removeElement($productDoc)) {
            // set the owning side to null (unless already changed)
            if ($productDoc->getProduct() === $this) {
                $productDoc->setProduct(null);
            }
        }

        return $this;
    }

    public function getDimW(): ?float
    {
        return $this->dimW;
    }

    public function setDimW(float $dimW): static
    {
        $this->dimW = $dimW;

        return $this;
    }

    public function getDimH(): ?float
    {
        return $this->dimH;
    }

    public function setDimH(?float $dimH): static
    {
        $this->dimH = $dimH;

        return $this;
    }

    public function getDimP(): ?float
    {
        return $this->dimP;
    }

    public function setDimP(?float $dimP): static
    {
        $this->dimP = $dimP;

        return $this;
    }

    /**
     * @return Collection<int, FormulesProductInclus>
     */
    public function getFormulesProductIncluses(): Collection
    {
        return $this->formulesProductIncluses;
    }

    public function addFormulesProductInclus(FormulesProductInclus $formulesProductInclus): static
    {
        if (!$this->formulesProductIncluses->contains($formulesProductInclus)) {
            $this->formulesProductIncluses->add($formulesProductInclus);
            $formulesProductInclus->setPRODUCT($this);
        }

        return $this;
    }

    public function removeFormulesProductInclus(FormulesProductInclus $formulesProductInclus): static
    {
        if ($this->formulesProductIncluses->removeElement($formulesProductInclus)) {
            // set the owning side to null (unless already changed)
            if ($formulesProductInclus->getPRODUCT() === $this) {
                $formulesProductInclus->setPRODUCT(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, ProductPhotos>
     */
    public function getProductPhotos(): Collection
    {
        return $this->productPhotos;
    }

    public function addProductPhoto(ProductPhotos $productPhoto): static
    {
        if (!$this->productPhotos->contains($productPhoto)) {
            $this->productPhotos->add($productPhoto);
            $productPhoto->setProduct($this);
        }

        return $this;
    }

    public function removeProductPhoto(ProductPhotos $productPhoto): static
    {
        if ($this->productPhotos->removeElement($productPhoto)) {
            // set the owning side to null (unless already changed)
            if ($productPhoto->getProduct() === $this) {
                $productPhoto->setProduct(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, ProductVideo>
     */
    public function getProductVideos(): Collection
    {
        return $this->productVideos;
    }

    public function addProductVideo(ProductVideo $productVideo): static
    {
        if (!$this->productVideos->contains($productVideo)) {
            $this->productVideos->add($productVideo);
            $productVideo->setProduct($this);
        }

        return $this;
    }

    public function removeProductVideo(ProductVideo $productVideo): static
    {
        if ($this->productVideos->removeElement($productVideo)) {
            // set the owning side to null (unless already changed)
            if ($productVideo->getProduct() === $this) {
                $productVideo->setProduct(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, ProductBlocked>
     */
    public function getProductBlockeds(): Collection
    {
        return $this->productBlockeds;
    }

    public function addProductBlocked(ProductBlocked $productBlocked): static
    {
        if (!$this->productBlockeds->contains($productBlocked)) {
            $this->productBlockeds->add($productBlocked);
            $productBlocked->setProduct($this);
        }

        return $this;
    }

    public function removeProductBlocked(ProductBlocked $productBlocked): static
    {
        if ($this->productBlockeds->removeElement($productBlocked)) {
            // set the owning side to null (unless already changed)
            if ($productBlocked->getProduct() === $this) {
                $productBlocked->setProduct(null);
            }
        }

        return $this;
    }

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

    public function setIsPublish(?bool $isPublish): static
    {
        $this->isPublish = $isPublish;

        return $this;
    }

    /**
     * @return Collection<int, Options>
     */
    public function getOptions(): Collection
    {
        return $this->options;
    }

    public function addOption(Options $option): static
    {
        if (!$this->options->contains($option)) {
            $this->options->add($option);
        }

        return $this;
    }

    public function removeOption(Options $option): static
    {
        $this->options->removeElement($option);

        return $this;
    }

    /**
     * @return Collection<int, ProductPointControll>
     */
    public function getProductPointControlls(): Collection
    {
        return $this->productPointControlls;
    }

    public function addProductPointControll(ProductPointControll $productPointControll): static
    {
        if (!$this->productPointControlls->contains($productPointControll)) {
            $this->productPointControlls->add($productPointControll);
            $productPointControll->setProduct($this);
        }

        return $this;
    }

    public function removeProductPointControll(ProductPointControll $productPointControll): static
    {
        if ($this->productPointControlls->removeElement($productPointControll)) {
            // set the owning side to null (unless already changed)
            if ($productPointControll->getProduct() === $this) {
                $productPointControll->setProduct(null);
            }
        }

        return $this;
    }
}
