<?php

namespace EasyLinkAutomations;

if (!defined('ABSPATH')) {
    exit;
}

use EasyLinkAutomations\Hooks\Hooks;
use EasyLinkAutomations\Migration\MigrationHelper;

/**
 * Plugin installer — validates requirements and wires up activation/uninstall hooks.
 *
 *
 *   $installer = new Installer(
 *       ['php' => '8.0', 'wp' => '6.0', 'version' => '1.0', 'oldVersion' => '0.0', ...],
 *       ['activate' => 'easylink_automations_activate', 'uninstall' => 'easylink_automations_uninstall'],
 *       ['migration' => [...], 'drop' => [...]]
 *   );
 *   $installer->register();
 */
final class Installer
{
    /** @var array<string, mixed> */
    private array $requirements;

    /** @var array<string, string> Hook names for activate/uninstall */
    private array $hooks;

    /** @var array<string, array> Migration/drop configs */
    private array $migrations;

    /**
     * @param array<string, mixed>  $requirements PHP/WP version requirements + plugin metadata
     * @param array<string, string> $hooks        Hook names: 'activate' and 'uninstall'
     * @param array<string, array>  $migrations   Keys 'migration' (up) and 'drop' (down)
     */
    public function __construct(array $requirements, array $hooks, array $migrations)
    {
        $this->requirements = $requirements;
        $this->hooks        = $hooks;
        $this->migrations   = $migrations;
    }

    /**
     * Register activation and uninstall callbacks.
     */
    public function register(): void
    {
        // Activation: check requirements, then run migrations and fire the hook
        Hooks::addAction($this->hooks['activate'] ?? '', [$this, 'onActivate']);

        // Uninstall: drop database tables
        Hooks::addAction($this->hooks['uninstall'] ?? '', [$this, 'onUninstall']);
    }

    /**
     * Fires on plugin activation.
     * Checks PHP and WP version requirements. If requirements are not met,
     * deactivates the plugin and shows an admin notice. Otherwise runs migrations.
     */
    public function onActivate(): void
    {
        if (!$this->meetsRequirements()) {
            return;
        }

        if (!empty($this->migrations['migration'])) {
            MigrationHelper::migrate($this->migrations['migration']);
        }

        // Persist current plugin version to options
        if (!empty($this->requirements['version'])) {
            update_option('easylink_automations_version', $this->requirements['version']);
        }
    }

    /**
     * Fires on plugin uninstall — drops all plugin database tables.
     */
    public function onUninstall(): void
    {
        if (!empty($this->migrations['drop'])) {
            MigrationHelper::drop($this->migrations['drop']);
        }
    }

    // ──────────────────────────────────────────────
    //  Requirements check
    // ──────────────────────────────────────────────

    private function meetsRequirements(): bool
    {
        $requiredPhp = $this->requirements['php'] ?? '8.0';
        $requiredWp  = $this->requirements['wp']  ?? '6.0';

        if (version_compare(PHP_VERSION, $requiredPhp, '<')) {
            add_action('admin_notices', function () use ($requiredPhp) {
                $message = sprintf(
                    '<b>EasyLink Automations</b> requires PHP %s or higher. You are running PHP %s.',
                    esc_html($requiredPhp),
                    esc_html(PHP_VERSION)
                );
                echo '<div class="notice notice-error"><p>' . wp_kses_post($message) . '</p></div>';
            });

            return false;
        }

        global $wp_version;

        if (version_compare($wp_version, $requiredWp, '<')) {
            add_action('admin_notices', function () use ($requiredWp) {
                global $wp_version;
                $message = sprintf(
                    '<b>EasyLink Automations</b> requires WordPress %s or higher. You are running %s.',
                    esc_html($requiredWp),
                    esc_html($wp_version)
                );
                echo '<div class="notice notice-error"><p>' . wp_kses_post($message) . '</p></div>';
            });

            return false;
        }

        return true;
    }
}
