<?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 DealTask extends CommonEntity
{
    public const TABLE_NAME = 'dealflow_deal_tasks';

    public const PRIORITY_LOW = 'low';
    public const PRIORITY_NORMAL = 'normal';
    public const PRIORITY_HIGH = 'high';
    public const PRIORITY_URGENT = 'urgent';

    private ?int $id = null;

    private ?Deal $deal = null;

    private string $title = '';

    private ?string $description = null;

    private string $status = 'open';

    private string $priority = self::PRIORITY_NORMAL;

    private ?int $ownerId = null;

    private ?\DateTimeInterface $dueAt = null;

    private ?\DateTimeInterface $reminderAt = null;

    private ?int $createdBy = 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(DealTaskRepository::class)
            ->addIndex(['status'], 'dealflow_task_status_idx');

        $builder->addId();

        $builder->createManyToOne('deal', Deal::class)
            ->inversedBy('tasks')
            ->addJoinColumn('deal_id', 'id', false, false, 'CASCADE')
            ->build();

        $builder->createField('title', Types::STRING)
            ->length(191)
            ->build();

        $builder->createField('description', Types::TEXT)
            ->nullable()
            ->build();

        $builder->createField('status', Types::STRING)
            ->length(32)
            ->build();

        $builder->createField('priority', Types::STRING)
            ->length(32)
            ->build();

        $builder->createField('ownerId', Types::INTEGER)
            ->columnName('owner_id')
            ->nullable()
            ->build();

        $builder->createField('dueAt', Types::DATETIME_MUTABLE)
            ->columnName('due_at')
            ->nullable()
            ->build();

        $builder->createField('reminderAt', Types::DATETIME_MUTABLE)
            ->columnName('reminder_at')
            ->nullable()
            ->build();

        $builder->createField('createdBy', Types::INTEGER)
            ->columnName('created_by')
            ->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 getDeal(): ?Deal
    {
        return $this->deal;
    }

    public function setDeal(Deal $deal): self
    {
        $this->deal = $deal;

        return $this;
    }

    public function getTitle(): string
    {
        return $this->title;
    }

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

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(?string $description): self
    {
        $this->isChanged('description', $description);
        $this->description = $description;

        return $this;
    }

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

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

        return $this;
    }

    public function getPriority(): string
    {
        return $this->priority;
    }

    public function setPriority(string $priority): self
    {
        if (!in_array($priority, self::getPriorityValues(), true)) {
            $priority = self::PRIORITY_NORMAL;
        }

        $this->isChanged('priority', $priority);
        $this->priority = $priority;

        return $this;
    }

    public function getOwnerId(): ?int
    {
        return $this->ownerId;
    }

    public function setOwnerId(?int $ownerId): self
    {
        $this->isChanged('ownerId', $ownerId);
        $this->ownerId = $ownerId;

        return $this;
    }

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

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

        return $this;
    }

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

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

        return $this;
    }

    public function getCreatedBy(): ?int
    {
        return $this->createdBy;
    }

    public function setCreatedBy(?int $createdBy): self
    {
        $this->createdBy = $createdBy;

        return $this;
    }

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

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

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

        return $this;
    }

    /**
     * @return list<string>
     */
    public static function getPriorityValues(): array
    {
        return [
            self::PRIORITY_LOW,
            self::PRIORITY_NORMAL,
            self::PRIORITY_HIGH,
            self::PRIORITY_URGENT,
        ];
    }
}
