<?php

declare(strict_types=1);

namespace App\ApiResources\Organization;

use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Post;
use App\Enum\Organization\LegalEnum;
use App\Enum\Organization\OrganizationIdsEnum;
use App\Enum\Organization\PrincipalTypeEnum;
use App\Enum\Organization\SettingsProductEnum;
use App\State\Processor\Organization\OrganizationCreationRequestProcessor;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Requête de création d'une nouvelle organisation.
 */
#[ApiResource(
    operations: [
        new Post(
            uriTemplate: '/internal/organization/create',
        ),
    ],
    processor: OrganizationCreationRequestProcessor::class
)]
class OrganizationCreationRequest
{
    private const FRANCE_COUNTRY_INTERNAL_ID = 72;

    public const STATUS_PENDING = 'pending';
    public const STATUS_OK = 'ok';
    public const STATUS_OK_WITH_ERRORS = 'ok with errors';

    /**
     * Id 'bidon' ajouté par défaut pour permettre la construction
     * de l'IRI par api platform.
     */
    #[ApiProperty(identifier: true)]
    private int $id = 0;

    /**
     * A quelle adresse email notifier la création de l'organisation, ou d'éventuelles erreurs ?
     */
    #[Assert\Email(message: 'The email {{ value }} is not a valid email.')]
    private ?string $sendConfirmationEmailAt = null;

    private string $name;

    /**
     * Matricule (obligatoire dans le réseau CMF).
     */
    #[Assert\Regex(pattern: '/^|(FR\d{3}\w\d{8})$/')]
    private string $identifier = '';

    #[Assert\Regex(pattern: '/^|(\d+)$/')]
    private string $siretNumber = '';

    #[Assert\Regex(pattern: '/^|(W\d+)$/')]
    private string $waldecNumber = '';

    private LegalEnum $legalStatus;

    private SettingsProductEnum $product;

    #[Assert\Length(
        min: 1,
        minMessage: 'Street address must be at least {{ limit }} characters long',
    )]
    private string $streetAddress1;

    private ?string $streetAddress2 = null;

    private ?string $streetAddress3 = null;

    #[Assert\Length(
        min: 3,
        minMessage: 'Postal code must be at least {{ limit }} characters long',
    )]
    private string $postalCode;

    #[Assert\Length(
        min: 1,
        minMessage: 'City must be at least {{ limit }} characters long',
    )]
    private string $city;

    private int $countryId = self::FRANCE_COUNTRY_INTERNAL_ID;

    #[Assert\Length(
        min: 10,
        minMessage: 'Phone number must be at least {{ limit }} characters long',
    )]
    private string $phoneNumber;

    #[Assert\Email(
        message: 'The email {{ value }} is not a valid email.',
    )]
    private string $email;

    #[Assert\Length(
        min: 2,
        minMessage: 'Subdomain must be at least {{ limit }} characters long',
    )]
    private string $subdomain;

    #[Assert\Positive]
    private int $parentId = OrganizationIdsEnum::_2IOS->value;

    private PrincipalTypeEnum $principalType;

    /**
     * Id d'une Person existante ou requête de création d'un nouvel access qui aura le
     * rôle de président(e) de la nouvelle structure.
     */
    private int|OrganizationMemberCreationRequest|null $president = null;

    /**
     * Id d'une Person existante ou requête de création d'un nouvel access qui aura le
     * rôle de directeur / directrice de la nouvelle structure.
     */
    private int|OrganizationMemberCreationRequest|null $director = null;

    /**
     * Faut-il créer un site typo3 pour la nouvelle structure.
     */
    private bool $createWebsite = true;

    /**
     * La structure est-elle cliente de Opentalent.
     */
    private bool $client = false;

    /**
     * Statut de l'opération.
     */
    private string $status = self::STATUS_PENDING;

    private ?\DateTime $creationDate = null;
    private ?int $authorId = null;

    /**
     * For testing purposes only.
     */
    private bool $async = true;

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

    public function setId(int $id): self
    {
        $this->id = $id;

        return $this;
    }

    public function getSendConfirmationEmailAt(): ?string
    {
        return $this->sendConfirmationEmailAt;
    }

    public function setSendConfirmationEmailAt(?string $sendConfirmationEmailAt): self
    {
        $this->sendConfirmationEmailAt = $sendConfirmationEmailAt;

        return $this;
    }

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

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

        return $this;
    }

    public function getIdentifier(): string
    {
        return $this->identifier;
    }

    public function setIdentifier(string $identifier): self
    {
        $this->identifier = $identifier;

        return $this;
    }

    public function getSiretNumber(): string
    {
        return $this->siretNumber;
    }

    public function setSiretNumber(string $siretNumber): self
    {
        $this->siretNumber = $siretNumber;

        return $this;
    }

    public function getWaldecNumber(): string
    {
        return $this->waldecNumber;
    }

    public function setWaldecNumber(string $waldecNumber): self
    {
        $this->waldecNumber = $waldecNumber;

        return $this;
    }

    public function getLegalStatus(): LegalEnum
    {
        return $this->legalStatus;
    }

    public function setLegalStatus(LegalEnum $legalStatus): self
    {
        $this->legalStatus = $legalStatus;

        return $this;
    }

    public function getProduct(): SettingsProductEnum
    {
        return $this->product;
    }

    public function setProduct(SettingsProductEnum $product): self
    {
        $this->product = $product;

        return $this;
    }

    public function getStreetAddress1(): string
    {
        return $this->streetAddress1;
    }

    public function setStreetAddress1(string $streetAddress1): self
    {
        $this->streetAddress1 = $streetAddress1;

        return $this;
    }

    public function getStreetAddress2(): ?string
    {
        return $this->streetAddress2;
    }

    public function setStreetAddress2(?string $streetAddress2): self
    {
        $this->streetAddress2 = $streetAddress2;

        return $this;
    }

    public function getStreetAddress3(): ?string
    {
        return $this->streetAddress3;
    }

    public function setStreetAddress3(?string $streetAddress3): self
    {
        $this->streetAddress3 = $streetAddress3;

        return $this;
    }

    public function getPostalCode(): string
    {
        return $this->postalCode;
    }

    public function setPostalCode(string $postalCode): self
    {
        $this->postalCode = $postalCode;

        return $this;
    }

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

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

        return $this;
    }

    public function getCountryId(): int
    {
        return $this->countryId;
    }

    public function setCountryId(int $countryId): self
    {
        $this->countryId = $countryId;

        return $this;
    }

    public function getPhoneNumber(): string
    {
        return $this->phoneNumber;
    }

    public function setPhoneNumber(string $phoneNumber): self
    {
        $this->phoneNumber = $phoneNumber;

        return $this;
    }

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

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

        return $this;
    }

    public function getSubdomain(): string
    {
        return $this->subdomain;
    }

    public function setSubdomain(string $subdomain): self
    {
        $this->subdomain = $subdomain;

        return $this;
    }

    public function getParentId(): int
    {
        return $this->parentId;
    }

    public function setParentId(int $parentId): self
    {
        $this->parentId = $parentId;

        return $this;
    }

    public function getPrincipalType(): PrincipalTypeEnum
    {
        return $this->principalType;
    }

    public function setPrincipalType(PrincipalTypeEnum $principalType): self
    {
        $this->principalType = $principalType;

        return $this;
    }

    public function getPresident(): int|OrganizationMemberCreationRequest|null
    {
        return $this->president;
    }

    public function setPresident(int|OrganizationMemberCreationRequest|null $president): self
    {
        $this->president = $president;

        return $this;
    }

    public function getDirector(): int|OrganizationMemberCreationRequest|null
    {
        return $this->director;
    }

    public function setDirector(int|OrganizationMemberCreationRequest|null $director): self
    {
        $this->director = $director;

        return $this;
    }

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

    public function setCreateWebsite(bool $createWebsite): self
    {
        $this->createWebsite = $createWebsite;

        return $this;
    }

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

    public function setClient(bool $client): self
    {
        $this->client = $client;

        return $this;
    }

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

    public function setStatus(string $status): self
    {
        $this->status = $status;

        return $this;
    }

    public function getCreationDate(): \DateTime
    {
        return $this->creationDate;
    }

    public function setCreationDate(?\DateTime $creationDate): self
    {
        $this->creationDate = $creationDate;

        return $this;
    }

    public function getAuthorId(): ?int
    {
        return $this->authorId;
    }

    public function setAuthorId(?int $authorId): self
    {
        $this->authorId = $authorId;

        return $this;
    }

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

    public function setAsync(bool $async): self
    {
        $this->async = $async;

        return $this;
    }
}
