<?php

declare(strict_types=1);

namespace App\Framework\Queue\Entities;

use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\Database\Attributes\Column;
use App\Framework\Database\Attributes\Entity;
use App\Framework\Queue\ValueObjects\JobId;
use App\Framework\Queue\ValueObjects\JobStatus;

/**
 * Job History Entry Entity
 *
 * Database entity for job status change audit trail
 */
#[Entity(tableName: 'job_history', idColumn: 'id')]
final readonly class JobHistoryEntry
{
    public function __construct(
        #[Column(name: 'id', primary: true, autoIncrement: true)]
        public ?int $id,
        #[Column(name: 'job_id')]
        public JobId $jobId,
        #[Column(name: 'old_status')]
        public ?JobStatus $oldStatus,
        #[Column(name: 'new_status')]
        public JobStatus $newStatus,
        #[Column(name: 'error_message')]
        public ?string $errorMessage,
        #[Column(name: 'changed_at')]
        public Timestamp $changedAt,
        #[Column(name: 'metadata')]
        public ?string $metadata = null
    ) {
    }

    /**
     * Create status change entry
     */
    public static function forStatusChange(
        JobId $jobId,
        ?JobStatus $oldStatus,
        JobStatus $newStatus,
        ?string $errorMessage = null,
        array $metadata = []
    ): self {
        return new self(
            id: null,
            jobId: $jobId,
            oldStatus: $oldStatus,
            newStatus: $newStatus,
            errorMessage: $errorMessage,
            changedAt: Timestamp::now(),
            metadata: ! empty($metadata) ? json_encode($metadata) : null
        );
    }

    /**
     * Get metadata as array
     */
    public function getMetadataAsArray(): array
    {
        if ($this->metadata === null) {
            return [];
        }

        $decoded = json_decode($this->metadata, true);

        return is_array($decoded) ? $decoded : [];
    }

    /**
     * Convert to array for storage/serialization
     */
    public function toArray(): array
    {
        return [
            'id' => $this->id,
            'job_id' => $this->jobId->toString(),
            'old_status' => $this->oldStatus?->value,
            'new_status' => $this->newStatus->value,
            'error_message' => $this->errorMessage,
            'changed_at' => $this->changedAt->toFloat(),
            'metadata' => $this->metadata,
        ];
    }
}
