<?php

namespace App\Entity;

use App\Repository\CustomerRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;

#[ORM\Entity(repositoryClass: CustomerRepository::class)]
class Customer implements UserInterface, PasswordAuthenticatedUserInterface
{
    public const ROLE_CUSTOMER = 'ROLE_CUSTOMER';

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

    // --- CHAMPS SÉCURITÉ & COMPTE ---

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

    #[ORM\Column(nullable: true)]
    private array $roles = [];

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

    #[ORM\Column(options: ["default" => false])]
    private bool $isAccountConfigured = false;


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

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

    // --- CHAMPS IDENTITÉ ---

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

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

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

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

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

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

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

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

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

    // --- RELATIONS ---

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

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

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

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

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

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

    public function __construct()
    {
        $this->customerAddresses = new ArrayCollection();
        $this->devis = new ArrayCollection();
        $this->productReserves = new ArrayCollection();
        $this->contrats = new ArrayCollection();

        // Configuration par défaut
        $this->roles = [self::ROLE_CUSTOMER];
        $this->isAccountConfigured = false;
        $this->customerTrackings = new ArrayCollection();
        $this->orderSessions = new ArrayCollection();
    }

    // --- MÉTHODES INTERFACES (SECURITY) ---

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

    public function getRoles(): array
    {
        $roles = $this->roles;
        $roles[] = self::ROLE_CUSTOMER;
        return array_unique($roles);
    }

    public function setRoles(array $roles): static
    {
        $this->roles = $roles;
        return $this;
    }

    public function getPassword(): ?string
    {
        return $this->password;
    }

    public function setPassword(?string $password): static
    {
        $this->password = $password;
        return $this;
    }

    public function eraseCredentials(): void
    {
    }

    // --- GETTERS & SETTERS PROPRES ---

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

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

    public function setIsAccountConfigured(bool $isAccountConfigured): static
    {
        $this->isAccountConfigured = $isAccountConfigured;
        return $this;
    }

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

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

    public function getCiv(): ?string
    {
        return $this->civ;
    }

    public function setCiv(string $civ): static
    {
        $this->civ = $civ;
        return $this;
    }

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

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

    public function getSurname(): ?string
    {
        return $this->surname;
    }

    public function setSurname(string $surname): static
    {
        $this->surname = $surname;
        return $this;
    }

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

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

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

    public function setType(string $type): static
    {
        $this->type = $type;
        return $this;
    }

    public function getSiret(): ?string
    {
        return $this->siret;
    }

    public function setSiret(?string $siret): static
    {
        $this->siret = $siret;
        return $this;
    }

    public function getTypCompany(): ?string
    {
        return $this->typCompany;
    }

    public function setTypCompany(?string $typCompany): static
    {
        $this->typCompany = $typCompany;
        return $this;
    }

    public function getRaisonSocial(): ?string
    {
        return $this->raisonSocial;
    }

    public function setRaisonSocial(?string $raisonSocial): static
    {
        $this->raisonSocial = $raisonSocial;
        return $this;
    }

    public function getCustomerId(): ?string
    {
        return $this->customerId;
    }

    public function setCustomerId(?string $customerId): static
    {
        $this->customerId = $customerId;
        return $this;
    }

    // --- LOGIQUE DES COLLECTIONS ---

    /** @return Collection<int, CustomerAddress> */
    public function getCustomerAddresses(): Collection
    {
        return $this->customerAddresses;
    }

    public function addCustomerAddress(CustomerAddress $address): static
    {
        if (!$this->customerAddresses->contains($address)) {
            $this->customerAddresses->add($address);
            $address->setCustomer($this);
        }
        return $this;
    }

    /** @return Collection<int, Devis> */
    public function getDevis(): Collection
    {
        return $this->devis;
    }

    public function addDevi(Devis $devi): static
    {
        if (!$this->devis->contains($devi)) {
            $this->devis->add($devi);
            $devi->setCustomer($this);
        }
        return $this;
    }

    /** @return Collection<int, Contrats> */
    public function getContrats(): Collection
    {
        return $this->contrats;
    }

    public function addContrat(Contrats $contrat): static
    {
        if (!$this->contrats->contains($contrat)) {
            $this->contrats->add($contrat);
            $contrat->setCustomer($this);
        }
        return $this;
    }

    /**
     * @return string|null
     */
    public function getVerificationCode(): ?string
    {
        return $this->verificationCode;
    }

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

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

    /**
     * @param string|null $verificationCode
     */
    public function setVerificationCode(?string $verificationCode): void
    {
        $this->verificationCode = $verificationCode;
    }

    /**
     * @return Collection<int, CustomerTracking>
     */
    public function getCustomerTrackings(): Collection
    {
        return $this->customerTrackings;
    }

    public function addCustomerTracking(CustomerTracking $customerTracking): static
    {
        if (!$this->customerTrackings->contains($customerTracking)) {
            $this->customerTrackings->add($customerTracking);
            $customerTracking->setCustomer($this);
        }

        return $this;
    }

    public function removeCustomerTracking(CustomerTracking $customerTracking): static
    {
        if ($this->customerTrackings->removeElement($customerTracking)) {
            // set the owning side to null (unless already changed)
            if ($customerTracking->getCustomer() === $this) {
                $customerTracking->setCustomer(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, OrderSession>
     */
    public function getOrderSessions(): Collection
    {
        return $this->orderSessions;
    }

    public function addOrderSession(OrderSession $orderSession): static
    {
        if (!$this->orderSessions->contains($orderSession)) {
            $this->orderSessions->add($orderSession);
            $orderSession->setCustomer($this);
        }

        return $this;
    }

    public function removeOrderSession(OrderSession $orderSession): static
    {
        if ($this->orderSessions->removeElement($orderSession)) {
            // set the owning side to null (unless already changed)
            if ($orderSession->getCustomer() === $this) {
                $orderSession->setCustomer(null);
            }
        }

        return $this;
    }
}
