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


namespace App\ApiResource;

use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
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 ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\Entity\MediaObject;
use App\Entity\User;
use App\Filter\UserNameFilter;
use App\Interface\AdminOrOwnerInterface;
use App\State\EntityClassDtoStateProcessor;
use App\State\EntityToDtoStateProvider;
use Symfony\Component\Validator\Constraints as Assert;

#[ApiResource(
    shortName: 'User',
    operations: [
        new Get(
            security: 'is_granted("ROLE_USER")'
        ),
        new GetCollection(
            security: 'is_granted("ROLE_USER")'
        ),
        new Post(
            security: 'is_granted("ROLE_ADMIN")',
            validationContext: ['groups' => ['Default', 'postValidation']]
        ),
//        new Patch(
//            security: 'is_granted("is_granted("EDIT", object)")'
//        ),
    ],
    security: 'is_granted("ROLE_USER")',
    provider: EntityToDtoStateProvider::class,
    processor: EntityClassDtoStateProcessor::class,
    stateOptions: new Options(entityClass: User::class),

)]
#[ApiFilter(SearchFilter::class, properties: ['firstName' => 'ipartial', 'lastName' => 'ipartial'])]
#[ApiFilter(UserNameFilter::class)]
#[ApiFilter(OrderFilter::class, properties: [
    'firstName',
    'lastName',
], arguments: ['orderParameterName' => 'order'])]

class UserApi
{
    #[ApiProperty(readable: false, writable: false, identifier: true)]
    public ?int $id = null;

    #[Assert\NotBlank]
    #[Assert\Email]
    public ?string $email = null;

    #[Assert\NotBlank]
    public ?string $firstName = null;

    #[Assert\NotBlank]
    public ?string $lastName = null;

    public ?string $goals = null;

    public ?MediaObject $image = null;

    #[ApiProperty(writable: false)]
    public ?string $imageUrl = null;

    #[ApiProperty(writable: false)]
    public ?string $fullName = null;

    /**
     * The plaintext password when being set or changed.
     */
    #[ApiProperty(readable: false)]
    #[Assert\NotBlank(groups: ['postValidation'])]
    public ?string $password = null;

    // Object is null ONLY during deserialization: so this allows isPublished
    // to be writable in ALL cases (which is ok because the operations are secured).
    // During serialization, object will always be a DragonTreasureApi, so our
    // voter is called.
    #[ApiProperty(security: 'object === null or is_granted("EDIT", object)')]
    public bool $active;

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

}
