<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Workflow\Timer;

final class WorkflowTimer
{
    public function __construct(
        private readonly string $timerId,
        private readonly string $workflowInstanceId,
        private readonly string $activityId,
        private readonly string $dueAt,
        private readonly string $status = 'scheduled',
        private readonly array $payload = [],
        private readonly string $createdAt = '',
        private readonly string $updatedAt = ''
    ) {}

    public static function schedule(string $workflowInstanceId, string $activityId, int $delaySeconds = 60, array $payload = []): self
    {
        $dueAt = date('c', time() + max(0, $delaySeconds));
        return new self('workflow_timer_' . substr(hash('sha256', $workflowInstanceId . $activityId . $dueAt), 0, 24), $workflowInstanceId, $activityId, $dueAt, 'scheduled', $payload, date('c'), date('c'));
    }

    public static function dueNow(string $workflowInstanceId, string $activityId, array $payload = []): self
    {
        return new self('workflow_timer_' . substr(hash('sha256', $workflowInstanceId . $activityId . 'due'), 0, 24), $workflowInstanceId, $activityId, date('c', time() - 1), 'scheduled', $payload, date('c'), date('c'));
    }

    public static function fromArray(array $data): self
    {
        return new self((string) ($data['timerId'] ?? ''), (string) ($data['workflowInstanceId'] ?? ''), (string) ($data['activityId'] ?? ''), (string) ($data['dueAt'] ?? date('c')), (string) ($data['status'] ?? 'scheduled'), (array) ($data['payload'] ?? []), (string) ($data['createdAt'] ?? ''), (string) ($data['updatedAt'] ?? ''));
    }

    public function timerId(): string { return $this->timerId; }
    public function workflowInstanceId(): string { return $this->workflowInstanceId; }
    public function activityId(): string { return $this->activityId; }
    public function status(): string { return $this->status; }

    public function isDue(?int $now = null): bool
    {
        $now ??= time();
        return $this->status === 'scheduled' && strtotime($this->dueAt) <= $now;
    }

    public function fire(): self
    {
        return new self($this->timerId, $this->workflowInstanceId, $this->activityId, $this->dueAt, 'fired', $this->payload, $this->createdAt, date('c'));
    }

    public function cancel(): self
    {
        return new self($this->timerId, $this->workflowInstanceId, $this->activityId, $this->dueAt, 'cancelled', $this->payload, $this->createdAt, date('c'));
    }

    public function toArray(): array
    {
        return ['timerId' => $this->timerId, 'workflowInstanceId' => $this->workflowInstanceId, 'activityId' => $this->activityId, 'dueAt' => $this->dueAt, 'status' => $this->status, 'payload' => $this->payload, 'createdAt' => $this->createdAt !== '' ? $this->createdAt : date('c'), 'updatedAt' => $this->updatedAt !== '' ? $this->updatedAt : date('c')];
    }
}
