<?php

declare(strict_types=1);

namespace App\Framework\StateManagement\Database;

use App\Framework\Attributes\Entity;
use App\Framework\Attributes\Id;
use App\Framework\Attributes\Column;
use App\Framework\Core\ValueObjects\Timestamp;

/**
 * State History Entry Entity
 *
 * Represents a historical snapshot of component state change.
 * EntityManager-compatible entity for audit trails and debugging.
 */
#[Entity(table: 'component_state_history')]
final readonly class StateHistoryEntry
{
    public function __construct(
        #[Id]
        #[Column(name: 'id', type: 'integer')]
        public int $id,

        #[Column(name: 'component_id')]
        public string $componentId,

        #[Column(name: 'state_data', type: 'text')]
        public string $stateData,        // Encrypted state snapshot

        #[Column(name: 'state_class')]
        public string $stateClass,

        #[Column(name: 'version', type: 'integer')]
        public int $version,

        #[Column(name: 'change_type')]
        public StateChangeType $changeType,

        #[Column(name: 'changed_properties', type: 'json')]
        public ?array $changedProperties, // Which properties changed

        #[Column(name: 'user_id')]
        public ?string $userId,

        #[Column(name: 'session_id')]
        public ?string $sessionId,

        #[Column(name: 'ip_address')]
        public ?string $ipAddress,

        #[Column(name: 'user_agent', type: 'text')]
        public ?string $userAgent,

        #[Column(name: 'previous_checksum')]
        public ?string $previousChecksum,

        #[Column(name: 'current_checksum')]
        public string $currentChecksum,

        #[Column(name: 'created_at', type: 'datetime')]
        public Timestamp $createdAt,
    ) {}

    /**
     * Create from database row
     */
    public static function fromRow(array $row): self
    {
        return new self(
            id: (int) $row['id'],
            componentId: $row['component_id'],
            stateData: $row['state_data'],
            stateClass: $row['state_class'],
            version: (int) $row['version'],
            changeType: StateChangeType::from($row['change_type']),
            changedProperties: isset($row['changed_properties'])
                ? json_decode($row['changed_properties'], true)
                : null,
            userId: $row['user_id'] ?? null,
            sessionId: $row['session_id'] ?? null,
            ipAddress: $row['ip_address'] ?? null,
            userAgent: $row['user_agent'] ?? null,
            previousChecksum: $row['previous_checksum'] ?? null,
            currentChecksum: $row['current_checksum'],
            createdAt: Timestamp::fromString($row['created_at']),
        );
    }

    /**
     * Convert to database row
     */
    public function toRow(): array
    {
        return [
            'component_id' => $this->componentId,
            'state_data' => $this->stateData,
            'state_class' => $this->stateClass,
            'version' => $this->version,
            'change_type' => $this->changeType->value,
            'changed_properties' => $this->changedProperties ? json_encode($this->changedProperties) : null,
            'user_id' => $this->userId,
            'session_id' => $this->sessionId,
            'ip_address' => $this->ipAddress,
            'user_agent' => $this->userAgent,
            'previous_checksum' => $this->previousChecksum,
            'current_checksum' => $this->currentChecksum,
            'created_at' => $this->createdAt->format('Y-m-d H:i:s'),
        ];
    }

    /**
     * Check if this is a creation event
     */
    public function isCreation(): bool
    {
        return $this->changeType === StateChangeType::CREATED;
    }

    /**
     * Check if this is an update event
     */
    public function isUpdate(): bool
    {
        return $this->changeType === StateChangeType::UPDATED;
    }

    /**
     * Check if this is a deletion event
     */
    public function isDeletion(): bool
    {
        return $this->changeType === StateChangeType::DELETED;
    }
}
