<?php

declare(strict_types=1);

namespace MauticPlugin\DealFlowBundle\Entity;

use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder;
use Mautic\CoreBundle\Entity\CommonEntity;

class InboundWebhookSource extends CommonEntity
{
    public const TABLE_NAME = 'dealflow_inbound_webhook_sources';

    private ?int $id = null;

    private string $name = '';

    private string $sourceKey = '';

    private string $secret = '';

    private bool $isActive = true;

    private ?string $fieldMapping = null;

    private ?\DateTimeInterface $lastUsedAt = null;

    private \DateTimeInterface $createdAt;

    private \DateTimeInterface $updatedAt;

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

    /** @param ORM\ClassMetadata<static> $metadata */
    public static function loadMetadata(ORM\ClassMetadata $metadata): void
    {
        $builder = new ClassMetadataBuilder($metadata);

        $builder->setTable(self::TABLE_NAME)
            ->setCustomRepositoryClass(InboundWebhookSourceRepository::class)
            ->addIndex(['is_active'], 'dealflow_inbound_webhook_active_idx')
            ->addUniqueConstraint(['source_key'], 'dealflow_inbound_webhook_source_key_unique');

        $builder->addId();

        $builder->createField('name', 'string')
            ->length(191)
            ->build();

        $builder->createField('sourceKey', 'string')
            ->columnName('source_key')
            ->length(64)
            ->build();

        $builder->createField('secret', 'string')
            ->length(191)
            ->build();

        $builder->createField('isActive', 'boolean')
            ->columnName('is_active')
            ->build();

        $builder->createField('fieldMapping', Types::TEXT)
            ->columnName('field_mapping')
            ->nullable()
            ->build();

        $builder->createField('lastUsedAt', 'datetime_immutable')
            ->columnName('last_used_at')
            ->nullable()
            ->build();

        $builder->createField('createdAt', 'datetime_immutable')
            ->columnName('created_at')
            ->build();

        $builder->createField('updatedAt', 'datetime_immutable')
            ->columnName('updated_at')
            ->build();
    }

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

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

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

        return $this;
    }

    public function getSourceKey(): string
    {
        return $this->sourceKey;
    }

    public function setSourceKey(string $sourceKey): self
    {
        $this->isChanged('sourceKey', $sourceKey);
        $this->sourceKey = $sourceKey;

        return $this;
    }

    public function getSecret(): string
    {
        return $this->secret;
    }

    public function setSecret(string $secret): self
    {
        $this->isChanged('secret', $secret);
        $this->secret = $secret;

        return $this;
    }

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

    public function setIsActive(bool $isActive): self
    {
        $this->isChanged('isActive', $isActive);
        $this->isActive = $isActive;

        return $this;
    }

    /**
     * @return array<string, mixed>|null
     */
    public function getFieldMapping(): ?array
    {
        if (null === $this->fieldMapping || '' === $this->fieldMapping) {
            return null;
        }

        return json_decode($this->fieldMapping, true, 512, JSON_THROW_ON_ERROR);
    }

    /**
     * @param array<string, mixed>|null $fieldMapping
     */
    public function setFieldMapping(?array $fieldMapping): self
    {
        $encoded = null !== $fieldMapping ? json_encode($fieldMapping, JSON_THROW_ON_ERROR) : null;
        $this->isChanged('fieldMapping', $encoded);
        $this->fieldMapping = $encoded;

        return $this;
    }

    public function getLastUsedAt(): ?\DateTimeInterface
    {
        return $this->lastUsedAt;
    }

    public function setLastUsedAt(?\DateTimeInterface $lastUsedAt): self
    {
        $this->lastUsedAt = $lastUsedAt;

        return $this;
    }

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

    public function setCreatedAt(\DateTimeInterface $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }

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

    public function setUpdatedAt(\DateTimeInterface $updatedAt): self
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }
}
