<?php
namespace core;

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


/**
 * Abstract class for admin pages.
 * Provides a base structure for creating admin pages with common functionality.
 */
abstract class AdminAbstract {
    protected const NOTICE_CLASS = FC_ABBR . '-notice';
    protected $session;
    private $slug = null;
    protected $parent_slug = null;
    protected $title = null;
    protected $allowed_capabilities = ['manage_options' /*, MANAGE_REGISTRATION_CAP*/ ];
    protected $nounce = null;   // the hidden nounce field name
    protected $action = null;   // the action name for the form submission


    public function __construct($session, $slug, $title, $parent_slug) {
        $this->session = $session;
        $this->slug = $slug;
        $this->title = $title;
        $this->parent_slug = $parent_slug;
        $this->nounce = "{$this->slug}_nonce";
        $this->action = "{$this->slug}_action";

        add_action('admin_menu', [$this, 'add_sub_menu'], 20);
        add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts']);
        add_action("admin_post_{$this->action}", [$this, 'handle_post_action']);
        add_action("admin_post_nopriv_{$this->action}", [$this, 'handle_post_action']);
    }

    abstract protected function enqueue_scripts_internal($hook);
    abstract protected function render_page_internal();
    abstract protected function handle_post_action_internal();

    public function get_slug() {
        return $this->slug;
    }

    public function add_sub_menu() {

        // The first sub-menu uses the same slug as the parent, and share the same menu item.
        // This is the root page of the admin section.
        if($this->parent_slug != $this->slug) {
            add_submenu_page(
                $this->parent_slug,
                $this->title,
                $this->title,
                'manage_options',
                $this->slug,
                [$this, 'render_page']
            );
        }
    }

    public function enqueue_scripts($hook) {
        // Ensure we only enqueue scripts on the correct admin page
        if ($this->is_enqueue_page($hook)) {
            $this->enqueue_scripts_internal($hook);
        }
    }

    protected function is_enqueue_page($hook) {
        return strpos($hook, $this->get_slug()) !== false;
    }

    public function render_page() {

        // Ensure the admin notice is always visible
        $mynotice = self::NOTICE_CLASS;
        echo "<style>.notice.$mynotice { display: block !important; opacity: 1 !important; visibility: visible !important; }</style>";

        try {
            // check if the user has permission to access this page
            if (!$this->can_do()) {
                throw new \Exception('You do not have sufficient permissions to access this page.');
            }

            // disable the admin bar for this page
            if (!empty($_GET['success']) && $_GET['success'] !== "0") {
                $msg = esc_html($_GET['message'] ?? 'Action completed successfully.');
                echo "<div class='notice notice-success {$mynotice}'><p>{$msg}</p></div>";
            } elseif (!empty($_GET['error']) || ($_GET['success'] ?? null) === "0") {
                $msg = esc_html($_GET['error'] ?? 'Action failed.');
                echo "<div class='notice notice-error {$mynotice}'><p>Error: {$msg}</p></div>";
            }

            // render the page
            echo '<div class="wrap">';
            $this->render_page_internal();
            echo '</div>';
        } catch (\Exception $e) {
            error_log("Exception: " . $e->getMessage());
            echo "<div class='notice notice-error $mynotice'><p>!ERROR!</p><p>{$e->getMessage()}</p></div>";
            // wp_die('An error occurred while processing your request.');
        }
    }

    public function handle_post_action() {
        error_log("handle_post_action - slug: " . $this->slug);

        $redirect_url = null;
        try {
            // Check if the user has permission
            if (!$this->can_do()) {
                throw new \Exception('You do not have sufficient permissions to perform this action.');
            }
            // Verify the nonce
            if (!$this->verify_nonce($this->nounce, $this->action)) {
                throw new \Exception('Invalid nonce specified.');
            }
            // Handle the post action
            $redirect_url = $this->handle_post_action_internal();
        } catch (\Exception $e) {
            error_log("Post-action error: " . $e->getMessage());
            $redirect_url = admin_url('admin.php?page=' . $this->slug . '&success=0&error=' . urlencode($e->getMessage()) );
        }
        if ($redirect_url) {
            wp_redirect($redirect_url);
            exit;
        }
    }


    protected function verify_nonce($nounce, $action) {
        return isset($_POST[$nounce]) && wp_verify_nonce($_POST[$nounce], $action);
    }

    protected function can_do(): bool {
        foreach ($this->allowed_capabilities as $capability) {
            if (current_user_can($capability)) {
                return true;
            }
        }
        return false;
    }
}

