<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\Marketing\Model;

use CpCreation\VitiCore\Marketing\Repository\ProductReviewModerationActionRepository;
use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;

#[ORM\Entity(repositoryClass: ProductReviewModerationActionRepository::class)]
#[ORM\Table(name: 'marketing_product_review_moderation_action')]
#[ORM\Index(name: 'marketing_review_action_review_idx', columns: ['review_id', 'occurred_at'])]
class ProductReviewModerationAction
{
    public const string ACTION_SUBMITTED = 'submitted';
    public const string ACTION_RESUBMITTED = 'resubmitted';
    public const string ACTION_PUBLISHED = 'published';
    public const string ACTION_REJECTED = 'rejected';
    public const string ACTION_WITHDRAWN = 'withdrawn';
    public const string ACTION_REPLY_SAVED = 'reply_saved';
    public const string ACTION_REPLY_REMOVED = 'reply_removed';
    public const string ACTION_REPORT_RESOLVED = 'report_resolved';
    public const string ACTION_REPORT_DISMISSED = 'report_dismissed';

    #[ORM\Id]
    #[ORM\Column(type: 'uuid')]
    #[ORM\GeneratedValue(strategy: 'NONE')]
    private UuidInterface $id;

    #[ORM\ManyToOne(targetEntity: ProductReview::class, inversedBy: 'moderationActions')]
    #[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
    private ProductReview $review;

    #[ORM\Column(type: 'string', length: 40)]
    private string $action;

    #[ORM\Column(type: 'string', length: 64, nullable: true)]
    private ?string $reasonCode;

    #[ORM\Column(type: 'text', nullable: true)]
    private ?string $reasonDetail;

    #[ORM\Column(type: 'string', length: 180)]
    private string $actorIdentifier;

    /** @var array<string, bool|int|string|null> */
    #[ORM\Column(type: 'json')]
    private array $snapshot;

    #[ORM\Column(type: 'datetime_immutable')]
    private \DateTimeImmutable $occurredAt;

    /**
     * @param array<string, bool|int|string|null> $snapshot
     */
    public function __construct(
        ProductReview $review,
        string $action,
        string $actorIdentifier,
        array $snapshot,
        ?string $reasonCode = null,
        ?string $reasonDetail = null,
        ?\DateTimeImmutable $occurredAt = null,
    ) {
        $this->id = Uuid::uuid4();
        $this->review = $review;
        $this->action = $action;
        $this->actorIdentifier = mb_substr(mb_trim($actorIdentifier), 0, 180);
        $this->snapshot = $snapshot;
        $this->reasonCode = self::normalizeOptionalText($reasonCode);
        $this->reasonDetail = self::normalizeOptionalText($reasonDetail);
        $this->occurredAt = $occurredAt ?? new \DateTimeImmutable();
        $review->addModerationAction($this);
    }

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

    public function getReview(): ProductReview
    {
        return $this->review;
    }

    public function getAction(): string
    {
        return $this->action;
    }

    public function getReasonCode(): ?string
    {
        return $this->reasonCode;
    }

    public function getReasonDetail(): ?string
    {
        return $this->reasonDetail;
    }

    public function getActorIdentifier(): string
    {
        return $this->actorIdentifier;
    }

    /** @return array<string, bool|int|string|null> */
    public function getSnapshot(): array
    {
        return $this->snapshot;
    }

    public function getOccurredAt(): \DateTimeImmutable
    {
        return $this->occurredAt;
    }

    private static function normalizeOptionalText(?string $text): ?string
    {
        if (null === $text || '' === mb_trim($text)) {
            return null;
        }

        return mb_trim($text);
    }
}
