<?php

namespace App\Sms\Entity;

use Doctrine\ORM\Mapping as ORM;
use App\Sms\Repository\SmsTemplateRepository;
use Symfony\Component\Uid\Uuid;

#[ORM\Entity(repositoryClass: SmsTemplateRepository::class)]
#[ORM\Table(name: 'sms_templates')]
class SmsTemplate
{
    public const STATUS_DRAFT    = 'draft';
    public const STATUS_PENDING  = 'pending';
    public const STATUS_APPROVED = 'approved';
    public const STATUS_REJECTED = 'rejected';

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private ?int $id = null;

    #[ORM\Column(type: 'string', length: 36, unique: true)]
    private string $uuid;

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

    #[ORM\Column(type: 'text')]
    private string $body;

    #[ORM\Column(name: 'provider_code', type: 'string', length: 100, nullable: true)]
    private ?string $providerCode = null;

    #[ORM\Column(type: 'string', length: 20)]
    private string $status = self::STATUS_DRAFT;

    #[ORM\Column(name: 'variables', type: 'json')]
    private array $variables = [];

    #[ORM\Column(name: 'admin_note', type: 'string', length: 500, nullable: true)]
    private ?string $adminNote = null;

    #[ORM\Column(name: 'created_at', type: 'integer')]
    private int $createdAt;

    #[ORM\Column(name: 'updated_at', type: 'integer')]
    private int $updatedAt;

    public function __construct(string $name, string $body, array $variables = [])
    {
        $this->uuid      = Uuid::v4()->toRfc4122();
        $this->name      = $name;
        $this->body      = $body;
        $this->variables = $variables;
        $this->createdAt = time();
        $this->updatedAt = time();
    }

    public function getId(): ?int           { return $this->id; }
    public function getUuid(): string       { return $this->uuid; }
    public function getName(): string       { return $this->name; }
    public function getBody(): string       { return $this->body; }
    public function getProviderCode(): ?string { return $this->providerCode; }
    public function getStatus(): string     { return $this->status; }
    public function getVariables(): array   { return $this->variables; }
    public function getAdminNote(): ?string { return $this->adminNote; }

    public function setName(string $v): self          { $this->name = $v; $this->touch(); return $this; }
    public function setBody(string $v): self          { $this->body = $v; $this->touch(); return $this; }
    public function setProviderCode(?string $v): self { $this->providerCode = $v; $this->touch(); return $this; }
    public function setVariables(array $v): self      { $this->variables = $v; $this->touch(); return $this; }

    public function submitForReview(): self { $this->status = self::STATUS_PENDING; $this->touch(); return $this; }

    public function revertToDraft(): self { $this->status = self::STATUS_DRAFT; $this->touch(); return $this; }

    public function approve(?string $note = null): self
    {
        $this->status    = self::STATUS_APPROVED;
        $this->adminNote = $note;
        $this->touch();
        return $this;
    }

    public function reject(string $note): self
    {
        $this->status    = self::STATUS_REJECTED;
        $this->adminNote = $note;
        $this->touch();
        return $this;
    }

    private function touch(): void { $this->updatedAt = time(); }

    public function renderBody(array $vars): string
    {
        $body = $this->body;
        foreach ($vars as $key => $value) {
            $body = str_replace('{{' . $key . '}}', $value, $body);
        }
        return $body;
    }

    public function toArray(): array
    {
        return [
            'uuid'          => $this->uuid,
            'name'          => $this->name,
            'body'          => $this->body,
            'provider_code' => $this->providerCode,
            'variables'     => $this->variables,
            'status'        => $this->status,
            'admin_note'    => $this->adminNote,
            'created_at'    => $this->createdAt,
        ];
    }
}
