<?php

namespace App\Entity;

use App\Repository\CustomerRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: CustomerRepository::class)]
class Customer
{
    public const TYPE_ASSO = 'association';
    public const TYPE_IE = 'auto-entrepreneur';
    public const TYPE_SAS = 'sas';
    public const TYPE_SARL = 'sarl';
    public const TYPE_EURL = 'eurl';
    public const TYPE_SA = 'sa';
    public const TYPE_SCI = 'sci';
    public const TYPE_PARTICULIER = 'particulier';

    public const TYPES = [
        self::TYPE_ASSO,
        self::TYPE_IE,
        self::TYPE_SAS,
        self::TYPE_SARL,
        self::TYPE_EURL,
        self::TYPE_SA,
        self::TYPE_SCI,
        self::TYPE_PARTICULIER,
    ];

    public const STATE_ACTIVE = 'active';
    public const STATE_SUSPENDED = 'suspended';
    public const STATE_DISABLED = 'disabled';
    public const STATE_PENDING_DELETE = 'pending_delete';

    public const STATES = [
        self::STATE_ACTIVE,
        self::STATE_SUSPENDED,
        self::STATE_DISABLED,
        self::STATE_PENDING_DELETE,
    ];

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

    #[ORM\OneToOne(targetEntity: User::class)]
    #[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
    private User $user;

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

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

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

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

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

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

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

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

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

    #[ORM\Column(type: 'decimal', precision: 10, scale: 7, nullable: true)]
    private ?string $geoLat = null;

    #[ORM\Column(type: 'decimal', precision: 10, scale: 7, nullable: true)]
    private ?string $geoLong = null;

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

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

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

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

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

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

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

    #[ORM\Column(length: 20)]
    private string $state = self::STATE_ACTIVE;

    #[ORM\Column]
    private \DateTimeImmutable $createdAt;

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

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

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

    /** Niveau d'avertissement : null=aucun, 1st=1er avertissement, 2nd=2eme, last=dernier avant suspension */
    #[ORM\Column(length: 10, nullable: true)]
    private ?string $warningLevel = null;

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

    public function __construct(User $user)
    {
        $this->user = $user;
        $this->createdAt = new \DateTimeImmutable();
    }

    public function getCodeComptable(): ?string
    {
        return $this->codeComptable;
    }

    public function setCodeComptable(?string $codeComptable): static
    {
        $this->codeComptable = $codeComptable;

        return $this;
    }

    public function getRevendeurCode(): ?string
    {
        return $this->revendeurCode;
    }

    public function setRevendeurCode(?string $revendeurCode): static
    {
        $this->revendeurCode = $revendeurCode;

        return $this;
    }

    public function generateCodeComptable(): string
    {
        $idPart = str_pad((string) ($this->id ?? 0), 4, '0', STR_PAD_LEFT);
        $namePart = '';

        if (null !== $this->raisonSociale && '' !== $this->raisonSociale) {
            $clean = preg_replace('/[^A-Za-z]/', '', $this->raisonSociale);
            $namePart = strtoupper(substr($clean, 0, 5));
        } elseif (null !== $this->lastName && '' !== $this->lastName) {
            $clean = preg_replace('/[^A-Za-z]/', '', $this->lastName);
            $namePart = strtoupper(substr($clean, 0, 5));
        }

        $namePart = str_pad($namePart, 5, 'X');

        return 'EC-'.$idPart.'-'.$namePart;
    }

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

    public function getUser(): User
    {
        return $this->user;
    }

    public function getRaisonSociale(): ?string
    {
        return $this->raisonSociale;
    }

    public function setRaisonSociale(?string $raisonSociale): static
    {
        $this->raisonSociale = $raisonSociale;

        return $this;
    }

    public function getFirstName(): ?string
    {
        return $this->firstName;
    }

    public function setFirstName(?string $firstName): static
    {
        $this->firstName = $firstName;

        return $this;
    }

    public function getLastName(): ?string
    {
        return $this->lastName;
    }

    public function setLastName(?string $lastName): static
    {
        $this->lastName = $lastName;

        return $this;
    }

    public function getFullName(): string
    {
        if (null !== $this->raisonSociale && '' !== $this->raisonSociale) {
            return $this->raisonSociale;
        }

        return trim(($this->firstName ?? '').' '.($this->lastName ?? ''));
    }

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

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

        return $this;
    }

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

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

        return $this;
    }

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

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

        return $this;
    }

    public function getAddress2(): ?string
    {
        return $this->address2;
    }

    public function setAddress2(?string $address2): static
    {
        $this->address2 = $address2;

        return $this;
    }

    public function getZipCode(): ?string
    {
        return $this->zipCode;
    }

    public function setZipCode(?string $zipCode): static
    {
        $this->zipCode = $zipCode;

        return $this;
    }

    public function getCity(): ?string
    {
        return $this->city;
    }

    public function setCity(?string $city): static
    {
        $this->city = $city;

        return $this;
    }

    public function getGeoLat(): ?string
    {
        return $this->geoLat;
    }

    public function setGeoLat(?string $geoLat): static
    {
        $this->geoLat = $geoLat;

        return $this;
    }

    public function getGeoLong(): ?string
    {
        return $this->geoLong;
    }

    public function setGeoLong(?string $geoLong): static
    {
        $this->geoLong = $geoLong;

        return $this;
    }

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

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

        return $this;
    }

    public function getRcs(): ?string
    {
        return $this->rcs;
    }

    public function setRcs(?string $rcs): static
    {
        $this->rcs = $rcs;

        return $this;
    }

    public function getNumTva(): ?string
    {
        return $this->numTva;
    }

    public function setNumTva(?string $numTva): static
    {
        $this->numTva = $numTva;

        return $this;
    }

    public function getApe(): ?string
    {
        return $this->ape;
    }

    public function setApe(?string $ape): static
    {
        $this->ape = $ape;

        return $this;
    }

    public function getRna(): ?string
    {
        return $this->rna;
    }

    public function setRna(?string $rna): static
    {
        $this->rna = $rna;

        return $this;
    }

    public function getStripeCustomerId(): ?string
    {
        return $this->stripeCustomerId;
    }

    public function setStripeCustomerId(?string $stripeCustomerId): static
    {
        $this->stripeCustomerId = $stripeCustomerId;

        return $this;
    }

    public function getTypeCompany(): ?string
    {
        return $this->typeCompany;
    }

    public function setTypeCompany(?string $typeCompany): static
    {
        $this->typeCompany = $typeCompany;

        return $this;
    }

    public function getState(): string
    {
        return $this->state;
    }

    public function setState(string $state): static
    {
        $this->state = $state;
        $this->updatedAt = new \DateTimeImmutable();

        return $this;
    }

    public function isActive(): bool
    {
        return self::STATE_ACTIVE === $this->state;
    }

    public function isPendingDelete(): bool
    {
        return self::STATE_PENDING_DELETE === $this->state;
    }

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

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

    public function setUpdatedAt(?\DateTimeImmutable $updatedAt): static
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    public function getWarningLevel(): ?string
    {
        return $this->warningLevel;
    }

    public function setWarningLevel(?string $warningLevel): static
    {
        $this->warningLevel = $warningLevel;

        return $this;
    }

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

    public function setWarningAt(?\DateTimeImmutable $warningAt): static
    {
        $this->warningAt = $warningAt;

        return $this;
    }
}
