<?php

namespace RtmMail;

use Exception;

class Migration
{
    /**
     * OPTION_NAME - the name of the option saved in the "_options" table
     */
    const OPTION_NAME = "rtm_mail_migration_version";
    /**
     * version - current version of the plugin
     * @var string
     */
    private $version;
    /**
     * notice_messages - Array of messages for displaying admin notices
     * @var array
     */
    private $notice_messages;

    public function __construct($plugin_version = null)
    {
        // Set current plugin version
        $this->version = $plugin_version;
    }

    /**
     * check - Check if the migration version is different from the plugin version, if so check voor migration
     */
    public function check()
    {
        $migration_version = get_option(self::OPTION_NAME, '');
        if (empty($migration_version) || $this->version === null || version_compare($this->version, $migration_version, '>')) {
            // Get all the files in the Migrations folder
            $migration_files = array_diff(scandir(__DIR__ . '/Migrations/'), ['..', '.']);
            // List of migration classes
            $migration_classes = [];

            // Loop through each file found in the directory
            foreach ($migration_files as $file) {
                // Remove the php extension
                $file = str_replace('.php', '', $file);
                // Check if the class exists, if so add it to the migration array
                if (class_exists("RtmMail\Migrations\\" . $file)) {
                    $migration_classes[] = "RtmMail\Migrations\\" . $file;
                }
            }

            // Empty current notice messages
            $this->notice_messages = [];
            // Create migrations array (this will contain all migration classes)
            $migrations = [];

            // Loop through all the migration classes
            foreach ($migration_classes as $migration_class) {
                // Check if the migration class implements the migration interface
                if (class_implements($migration_class, 'RtmMail\Migrations\MigrationInterface')) {
                    // Create new instance of the migration class and add it to the array
                    $migrations[] = new $migration_class();
                }
            }

            // Sort array by priority
            usort($migrations, function ($a, $b) {
                return ($a->get_priority() < $b->get_priority()) ? -1 : 1;
            });

            // Boolean to check if the migration is successful
            $success = [];

            // Loop over the sorted migrations
            foreach ($migrations as $migration) {
                // Check if the migration class is already migrated, if not migrate
                if (!$migration->is_migrated()) {
                    try {
                        $migration->migrate();
                        $success[] = true;
                        do_action('rtmmail_migration_success', get_class($migration));
                        $this->notice_messages[] = ['type' => 'success', 'text' => 'Migration of class <code>' . get_class($migration) . '</code> was successful'];
                    } catch (Exception $e) {
                        $success[] = false;
                        do_action('rtmmail_migration_failed', get_class($migration), $e->getMessage());
                        $this->notice_messages[] = ['type' => 'error', 'text' => 'Migration of class <code>' . get_class($migration) . '</code> failed due to an error - <code>' . $e->getMessage() . '</code>'];
                        break;
                    }
                }
            }
            // If there are any messages, output them
            if (!empty($this->notice_messages)) {
                add_action('admin_notices', [$this, 'render_notice']);
            }
            // Only update the version when everything went good
            if (!in_array(false, $success, true)) {
                $this->update_version();
            }
        }
    }

    /**
     * update_version - updates the migration version in the "_options" table
     */
    private function update_version()
    {
        update_option(self::OPTION_NAME, $this->version);
    }

    /**
     * render_notice - Renders admin notices saved in notice_messages
     */
    public function render_notice()
    {
        foreach ($this->notice_messages as $message) {
            echo '<div class="notice notice-' . $message['type'] . ' is-dismissible">';
            echo '<p><strong>WP Mail Logger:</strong> ' . $message['text'] . '</p>';
            echo '</div>';
        }
    }
}