<?php

namespace _121Digital\Connect\Admin\Styles;

use _121Digital\Connect\Admin\Styles\Alerts\Alerts;
use _121Digital\Connect\Admin\Styles\Buttons\Buttons;
use _121Digital\Connect\Admin\Styles\Dashboard\Dashboard;
use _121Digital\Connect\Admin\Styles\Inputs\Inputs;
use _121Digital\Connect\Admin\Styles\Modals\Modals;
use _121Digital\Connect\Admin\Styles\Sidebar\Sidebar;
use _121Digital\Connect\Admin\Styles\TopBar\TopBar;
use _121Digital\Connect\Admin\Styles\Typeface\Typeface;
use _121Digital\Connect\Core\Plugin;

class AdminInterfaceStyles
{
    /**
     * List of admin interface style submodule classes to load. Add new ones
     * to this array to have them loaded automatically.
     *
     * @var array<string>
     */
    private array $styleModules = [
      Buttons::class,
      Typeface::class,
      Sidebar::class,
      TopBar::class,
      Alerts::class,
      Inputs::class,
      Modals::class,
      // Dashboard::class,
    ];

    /**
     * Instances of the loaded submodules.
     *
     * @var array<string, object>
     */
    private array $components = [];

    /**
     * Instantiate and register all admin interface style submodules.
     */
    public function register(): void
    {
        // only load the admin styles in admin area. This should already be prevented
        // by the hook actions, but its stil efficient to not load the modules if they
        // are never going to be used in the frontend context.
        if (! is_admin()) {
            return;
        }

        $this->loadStyleModules();
    }

    private function loadStyleModules(): void
    {
        foreach ($this->styleModules as $class) {
            try {
                if (! class_exists($class)) {
                    // Faltal error: Missing styles class module should now cause die event...
                    throw new \Exception("Admin interface styles module class '$class' not found.");
                }

                $instance = new $class();

                if (method_exists($instance, 'register')) {
                    $instance->register();
                }

                $short = (new \ReflectionClass($class))->getShortName();
                $this->components[ $short ] = $instance;
            } catch (\Throwable $e) {
                // Throw error through pugin error handling.
                Plugin::die($e->getMessage());
            }
        }
    }

    /**
     * Accessor for instantiated submodules.
     *
     * @return array<string, object>
     */
    public function getComponents(): array
    {
        return $this->components;
    }
}
