<?php

declare(strict_types=1);

namespace CliqThemes\UI\Admin;

/**
 * Immutable value object defining the metadata required to register a WordPress admin page.
 */
final class AdminPage
{
    public const DEFAULT_SCRIPT_HANDLE = 'cliqthemes-ui-app';

    private string $slug;

    private string $pageTitle;

    private string $menuTitle;

    private string $capability;

    private ?string $parentSlug;

    private ?int $position;

    private ?string $iconUrl;

    private string $scriptHandle;

    private ?string $dataProvider;

    private ?string $description;

    /**
     * Convenience factory for constructing an admin page from configuration arrays.
     *
     * @param array<string,mixed> $config
     */
    public static function make(array $config): self
    {
        return new self(
            (string) $config['slug'],
            (string) ($config['page_title'] ?? $config['title'] ?? $config['menu_title'] ?? $config['slug']),
            (string) ($config['menu_title'] ?? $config['page_title'] ?? $config['slug']),
            (string) ($config['capability'] ?? 'manage_options'),
            isset($config['parent']) ? (string) $config['parent'] : ($config['parent_slug'] ?? null),
            array_key_exists('position', $config) ? (int) $config['position'] : null,
            isset($config['icon_url']) ? (string) $config['icon_url'] : ($config['icon'] ?? null),
            isset($config['script_handle']) ? (string) $config['script_handle'] : null,
            isset($config['data_provider']) ? (string) $config['data_provider'] : null,
            isset($config['description']) ? (string) $config['description'] : null
        );
    }

    /**
     * @param string               $slug         Unique slug used for routing and menu registration.
     * @param string               $pageTitle    Heading displayed on the admin screen.
     * @param string               $menuTitle    Label used in the WordPress menu.
     * @param string               $capability   Capability required to access the page.
     * @param string|null          $parentSlug   Optional parent slug if the page is a submenu.
     * @param int|null             $position     Menu position hint forwarded to WordPress.
     * @param string|null          $iconUrl      Dashicon class or custom icon URL.
     * @param string|null          $scriptHandle Script handle that should be enqueued when rendering.
     * @param string|null          $dataProvider Identifier of the default data provider for the page.
     * @param string|null          $description  Optional summary displayed above the mount point.
     */
    public function __construct(
        string $slug,
        string $pageTitle,
        string $menuTitle,
        string $capability,
        ?string $parentSlug = null,
        ?int $position = null,
        ?string $iconUrl = null,
        ?string $scriptHandle = null,
        ?string $dataProvider = null,
        ?string $description = null
    ) {
        $this->slug = $slug;
        $this->pageTitle = $pageTitle;
        $this->menuTitle = $menuTitle;
        $this->capability = $capability;
        $this->parentSlug = $parentSlug ? trim($parentSlug) : null;
        $this->position = $position;
        $this->iconUrl = $iconUrl ? trim($iconUrl) : null;
        $this->scriptHandle = $scriptHandle ? trim($scriptHandle) : self::DEFAULT_SCRIPT_HANDLE;
        $this->dataProvider = $dataProvider ? trim($dataProvider) : null;
        $this->description = $description;
    }

    /**
     * Unique slug used for menu registration and routing.
     */
    public function slug(): string
    {
        return $this->slug;
    }

    /**
     * Title displayed at the top of the admin screen.
     */
    public function pageTitle(): string
    {
        return $this->pageTitle;
    }

    /**
     * Label used for the WordPress menu item.
     */
    public function menuTitle(): string
    {
        return $this->menuTitle;
    }

    /**
     * Capability required to access the admin page.
     */
    public function capability(): string
    {
        return $this->capability;
    }

    /**
     * Parent slug if the page should be rendered as a submenu.
     */
    public function parentSlug(): ?string
    {
        return $this->parentSlug;
    }

    /**
     * Optional menu position passed through to WordPress.
     */
    public function position(): ?int
    {
        return $this->position;
    }

    /**
     * Dashicon class or URL that should be used for the menu item.
     */
    public function iconUrl(): ?string
    {
        return $this->iconUrl;
    }

    /**
     * Script handle that should be enqueued when the page is displayed.
     */
    public function scriptHandle(): string
    {
        return $this->scriptHandle;
    }

    /**
     * Identifier of the default data provider that should hydrate the page.
     */
    public function dataProvider(): ?string
    {
        return $this->dataProvider;
    }

    /**
     * Optional page description rendered above the React mount point.
     */
    public function description(): ?string
    {
        return $this->description;
    }

    /**
     * Returns a cloned instance with an overridden script handle.
     */
    public function withScriptHandle(string $handle): self
    {
        $clone = clone $this;
        $clone->scriptHandle = $handle;

        return $clone;
    }
}
