<?php
/**
 * @author Daniel Knudsen <d.knudsen@spawntree.de>
 * @date 12.12.23
 */


namespace App\ApiResource;

use ApiPlatform\Doctrine\Orm\Filter\ExistsFilter;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Doctrine\Orm\State\Options;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use App\Entity\Posting;
use App\Enum\PartnerType;
use App\Interface\OwnerInterface;
use App\State\EntityClassDtoStateProcessor;
use App\State\EntityToDtoStateProvider;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use Symfony\Component\PropertyInfo\Type;
use Symfony\Component\Serializer\Attribute\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Constraints\NotBlank;

#[ApiResource(
    shortName: 'Post',
    operations: [
        new Get(
            security: 'is_granted("ROLE_USER")',
        ),
        new GetCollection(
            security: 'is_granted("ROLE_USER")',
        ),
        new Post(
            denormalizationContext: ['groups' => 'posting:create'],
            security: 'is_granted("ROLE_USER")',
        ),
        new Patch(
            denormalizationContext: ['groups' => 'posting:patch'],
            security: 'is_granted("EDIT", object)',
        ),
//        new Delete(
//            security: 'is_granted("ROLE_ADMIN")',
//        )
    ],
    order: ['createdAt' => 'DESC'],
    security: 'is_granted("ROLE_USER")',
    provider: EntityToDtoStateProvider::class,
    processor: EntityClassDtoStateProcessor::class,
    stateOptions: new Options(entityClass: Posting::class)
)]
#[ApiFilter(SearchFilter::class, properties: [
    'partner' => 'exact',
    'contact' => 'exact',
    'sale' => 'exact',
    'owner' => 'exact'
])]
#[ApiFilter(ExistsFilter::class, properties: [
    'contact',
    'sale'
])]
class PostingApi implements OwnerInterface
{
    #[ApiProperty(readable: false, writable: false, identifier: true)]
    public ?int $id = null;

    #[NotBlank]
    #[Groups(['posting:create', 'posting:patch'])]
    public ?string $headline = null;

    #[NotBlank]
    #[Groups(['posting:create', 'posting:patch'])]
    public ?string $message = null;

    /**
     * @var $owner ?UserApi
     */
    #[ApiProperty(
        writable: false,
        readableLink: true,
        writableLink: false,
        builtinTypes: [
            new Type(
                'object',
                class: UserApi::class,
            )
        ]
    )]
    public ?UserApi $owner = null;

    /**
     * @var $partner ?PartnerApi
     */
    #[ApiProperty(
        writable: false,
        readableLink: true,
        writableLink: false,
        builtinTypes: [
            new Type(
                'object',
                class: PartnerApi::class,
            )
        ]
    )]
    public ?PartnerApi $partner = null;


    #[Groups(['posting:create'])]
    #[Assert\NotBlank(groups: ['posting:create'])]
    public ?PartnerApi $partnerIri = null;

    /**
     * @var $product ?ProductApi
     */
    #[ApiProperty(
        writable: false,
        readableLink: true,
        writableLink: false,
        builtinTypes: [
            new Type(
                'object',
                class: ProductApi::class,
            )
        ]
    )]
    public ?ProductApi $product = null;

    #[Groups(['posting:create'])]
    #[Assert\NotBlank(groups: ['posting:create'])]
    public ?ProductApi $productIri = null;

    /**
     * @var $contact ?ContactApi
     */
    #[ApiProperty(
        writable: false,
        readableLink: true,
        writableLink: false,
        builtinTypes: [
            new Type(
                'object',
                class: ContactApi::class,
            )
        ]
    )]
    public ?ContactApi $contact = null;

    #[Groups(['posting:create'])]
    public ?ContactApi $contactIri = null;

    /**
     * @var $sale ?SaleApi
     */
    #[ApiProperty(
        writable: false,
        readableLink: true,
        writableLink: false,
        builtinTypes: [
            new Type(
                'object',
                class: ContactApi::class,
            )
        ]
    )]
    public ?SaleApi $sale = null;

    #[Groups(['posting:create'])]
    public ?SaleApi $saleIri = null;

    #[ApiProperty(writable: false)]
    public ?int $numComments = null;

    #[ApiProperty(writable: false)]
    public ?\DateTimeImmutable $createdAt = null;

    public function getOwner(): ?UserApi
    {
        return $this->owner;
    }
}