<?php

declare(strict_types=1);

namespace App\Framework\StateManagement;

use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\StateManagement\Database\StateHistoryEntry;

/**
 * State History Manager Interface
 *
 * Manages historical snapshots of component state changes.
 * Used for audit trails, debugging, and state recovery.
 */
interface StateHistoryManager
{
    /**
     * Add a history entry for a state change
     *
     * @param string $componentId Component identifier
     * @param string $stateData Serialized state data
     * @param string $stateClass State class name
     * @param int $version State version number
     * @param string $changeType Type of change (created/updated/deleted)
     * @param array $context Additional context (user_id, session_id, ip_address, user_agent, etc.)
     * @param array|null $changedProperties List of changed property names
     * @param string|null $previousChecksum Checksum before change
     * @param string $currentChecksum Checksum after change
     */
    public function addHistoryEntry(
        string $componentId,
        string $stateData,
        string $stateClass,
        int $version,
        string $changeType,
        array $context = [],
        ?array $changedProperties = null,
        ?string $previousChecksum = null,
        string $currentChecksum = ''
    ): void;

    /**
     * Get history for a component
     *
     * @param string $componentId Component identifier
     * @param int $limit Maximum number of entries to return
     * @param int $offset Offset for pagination
     * @return array<StateHistoryEntry> History entries ordered by created_at DESC
     */
    public function getHistory(string $componentId, int $limit = 100, int $offset = 0): array;

    /**
     * Get specific version of state from history
     *
     * @param string $componentId Component identifier
     * @param int $version Version number
     * @return StateHistoryEntry|null History entry or null if not found
     */
    public function getHistoryByVersion(string $componentId, int $version): ?StateHistoryEntry;

    /**
     * Get history entries since a specific timestamp
     *
     * @param string $componentId Component identifier
     * @param Timestamp $since Timestamp to start from
     * @param int $limit Maximum number of entries
     * @return array<StateHistoryEntry> History entries ordered by created_at ASC
     */
    public function getHistorySince(string $componentId, Timestamp $since, int $limit = 100): array;

    /**
     * Get history entries for a specific user
     *
     * @param string $userId User identifier
     * @param int $limit Maximum number of entries
     * @return array<StateHistoryEntry> History entries ordered by created_at DESC
     */
    public function getHistoryByUser(string $userId, int $limit = 100): array;

    /**
     * Cleanup old history entries for a component
     *
     * Keep only the last N entries, delete older ones.
     *
     * @param string $componentId Component identifier
     * @param int $keepLast Number of entries to keep
     * @return int Number of entries deleted
     */
    public function cleanup(string $componentId, int $keepLast): int;

    /**
     * Cleanup all history entries older than a specific timestamp
     *
     * @param Timestamp $olderThan Delete entries older than this timestamp
     * @return int Number of entries deleted
     */
    public function cleanupOlderThan(Timestamp $olderThan): int;

    /**
     * Delete all history for a component
     *
     * @param string $componentId Component identifier
     * @return int Number of entries deleted
     */
    public function deleteHistory(string $componentId): int;

    /**
     * Check if history tracking is enabled for a component
     *
     * @param string $componentClass Component class name
     * @return bool True if component has #[TrackStateHistory] attribute
     */
    public function isHistoryEnabled(string $componentClass): bool;

    /**
     * Get statistics about history storage
     *
     * @return array{total_entries: int, total_components: int, oldest_entry: ?Timestamp, newest_entry: ?Timestamp}
     */
    public function getStatistics(): array;
}
