<?php
/**
 * Migration Trait
 *
 * Provides common functionality for all migrations.
 *
 * @package     Havenlytics
 * @subpackage  Core\Migration\Traits
 * @since       2.1.3
 */

namespace HvnlyNab\Core\Migration\Traits;

// Prevent direct access.
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Trait MigrationTrait
 *
 * Common methods used across all migration handlers.
 *
 * @since 2.1.3
 */
trait MigrationTrait {

    /**
     * Create a backup of an option before migration.
     *
     * @since 2.1.3
     * @param string $option_key Option key to backup.
     * @param string $version    Migration version.
     * @return string|false Backup ID or false on failure.
     */
    protected function backup_option(string $option_key, string $version) {
        $data = get_option($option_key, array());

        if (empty($data)) {
            return false;
        }

        $backup_id = sprintf('_hvnly_backup_%s_%s_%s', $version, $option_key, current_time('timestamp'));

        $backup = array(
            'id'        => $backup_id,
            'version'   => $version,
            'option'    => $option_key,
            'timestamp' => current_time('mysql'),
            'data'      => $data,
        );

        if (update_option($backup_id, $backup, false)) {
            return $backup_id;
        }

        return false;
    }

    /**
     * Restore an option from backup.
     *
     * @since 2.1.3
     * @param string $backup_id Backup ID to restore.
     * @return bool True on success, false on failure.
     */
    protected function restore_from_backup(string $backup_id): bool {
        $backup = get_option($backup_id, null);

        if (!$backup || !is_array($backup) || !isset($backup['option']) || !isset($backup['data'])) {
            return false;
        }

        return update_option($backup['option'], $backup['data']);
    }

    /**
     * Clean up old backups.
     *
     * Uses WordPress options API with caching instead of direct database queries.
     *
     * @since 2.1.3
     * @param int $keep Number of backups to keep per option.
     * @return int Number of backups deleted.
     */
    protected function cleanup_backups(int $keep = 5): int {
        $deleted = 0;

        // Get all backup options using WordPress API with caching.
        $backups = $this->get_backup_options();

        if (empty($backups)) {
            return $deleted;
        }

        $backups_by_option = array();

        foreach ($backups as $backup_name) {
            // Remove the prefix to get the version and option key parts.
            $clean_name = str_replace('_hvnly_backup_', '', $backup_name);
            $parts = explode('_', $clean_name);
            
            if (count($parts) >= 2) {
                // First part is version, rest is the option key.
                $version = $parts[0];
                $option_parts = array_slice($parts, 1);
                $option_key = implode('_', $option_parts);
                
                if (!isset($backups_by_option[$option_key])) {
                    $backups_by_option[$option_key] = array();
                }
                $backups_by_option[$option_key][] = $backup_name;
            }
        }

        foreach ($backups_by_option as $option_backups) {
            if (count($option_backups) > $keep) {
                // Sort by backup name (which contains timestamp) in descending order.
                rsort($option_backups);
                
                // Keep the newest backups, delete the rest.
                $to_delete = array_slice($option_backups, $keep);
                
                foreach ($to_delete as $backup_name) {
                    if (delete_option($backup_name)) {
                        $deleted++;
                    }
                }
            }
        }

        // Clear the backup cache after deletions.
        wp_cache_delete('hvnly_migration_backups', 'options');

        return $deleted;
    }

    /**
     * Get all backup option names using WordPress API with caching.
     *
     * @since 2.1.3
     * @return array Array of backup option names.
     */
    private function get_backup_options(): array {
        // Try to get cached backup list first.
        $cache_key = 'hvnly_migration_backups';
        $backup_list = wp_cache_get($cache_key, 'options');

        if (false !== $backup_list) {
            return $backup_list;
        }

        // Cache miss - load all options and filter for backups.
        $all_options = wp_load_alloptions();
        $backup_list = array();

        if (is_array($all_options)) {
            foreach ($all_options as $option_name => $option_value) {
                if (strpos($option_name, '_hvnly_backup_') === 0) {
                    $backup_list[] = $option_name;
                }
            }
        }

        // Sort by option names in reverse order (newest backups first based on naming convention).
        rsort($backup_list);

        // Cache the backup list for 1 hour.
        wp_cache_set($cache_key, $backup_list, 'options', HOUR_IN_SECONDS);

        return $backup_list;
    }

    /**
     * Log migration message.
     *
     * @since 2.1.3
     * @param string $message Log message.
     * @param string $type    Log type (info, error, warning).
     * @return void
     */
    protected function log(string $message, string $type = 'info'): void {
        if (!defined('WP_DEBUG') || !WP_DEBUG) {
            return;
        }

        $prefix = '[Havenlytics Migration]';
        $log_message = sprintf('%s [%s] %s', $prefix, strtoupper($type), $message);
    }
}