<?php
/**
 * Wrenio Studio — shared admin menu.
 *
 * SHARED FILE — bundled identically in every Wrenio Studio plugin.
 *
 * The canonical version of this file lives in the wrenio-media-offload repo.
 * See /design.md §2 for the spec. When this file changes, update the
 * canonical version first, then re-sync into every Wrenio plugin.
 *
 * All public functions are wrapped in function_exists() guards so multiple
 * Wrenio plugins loading this file at once cannot crash PHP. Whichever
 * plugin loads first owns the function definitions — they are identical
 * across plugins, so it does not matter which one wins.
 *
 * @package WrenioStudio
 */

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

/* ---------------------------------------------------------------------------
 * Constants — identical across all Wrenio plugins, defined once.
 * ------------------------------------------------------------------------- */

if ( ! defined( 'WRENIO_STUDIO_MENU_SLUG' ) ) {
	// NOTE: 'wrenio-studio' here is the WordPress admin menu slug — the
	// shared parent menu under which every Wrenio plugin registers its
	// pages — NOT a text domain. Do not change it to the host plugin's
	// text domain even if PCP appears to want consistency; the i18n
	// calls below intentionally use the host plugin's text domain
	// ('wrenio-media-offload') while this constant stays as the menu slug.
	define( 'WRENIO_STUDIO_MENU_SLUG', 'wrenio-studio' );
}
if ( ! defined( 'WRENIO_STUDIO_MENU_POSITION' ) ) {
	define( 'WRENIO_STUDIO_MENU_POSITION', '58.7' );
}
if ( ! defined( 'WRENIO_STUDIO_CAPABILITY' ) ) {
	define( 'WRENIO_STUDIO_CAPABILITY', 'manage_options' );
}

/* ---------------------------------------------------------------------------
 * Host plugin path/URL — set by whichever Wrenio plugin loads this file
 * first. Subsequent plugins skip the define() because of the guard. The
 * shared assets (icon, logo, CSS) are identical across plugins, so it is
 * not important which plugin "owns" the resolved URLs at runtime.
 * ------------------------------------------------------------------------- */

if ( ! defined( 'WRENIO_STUDIO_HOST_PATH' ) ) {
	define( 'WRENIO_STUDIO_HOST_PATH', trailingslashit( dirname( __DIR__ ) ) );
}
if ( ! defined( 'WRENIO_STUDIO_HOST_URL' ) ) {
	define( 'WRENIO_STUDIO_HOST_URL', trailingslashit( dirname( plugin_dir_url( __FILE__ ) ) ) );
}

/* ---------------------------------------------------------------------------
 * Public API — function_exists-guarded so duplicate loads are safe.
 * ------------------------------------------------------------------------- */

/**
 * Returns true if the Wrenio Studio parent menu has already been registered
 * by another plugin in this request.
 *
 * @return bool
 */
if ( ! function_exists( 'wrenio_studio_parent_menu_exists' ) ) {
	function wrenio_studio_parent_menu_exists() {
		global $menu;
		if ( ! is_array( $menu ) ) {
			return false;
		}
		foreach ( $menu as $item ) {
			if ( isset( $item[2] ) && WRENIO_STUDIO_MENU_SLUG === $item[2] ) {
				return true;
			}
		}
		return false;
	}
}

/**
 * Registers the Wrenio Studio parent menu (idempotent — only adds it if
 * not already present).
 *
 * Each Wrenio plugin should call this from its own admin_menu hook BEFORE
 * registering its own submenus.
 */
if ( ! function_exists( 'wrenio_studio_register_parent_menu' ) ) {
	function wrenio_studio_register_parent_menu() {
		if ( wrenio_studio_parent_menu_exists() ) {
			return;
		}
		add_menu_page(
			'Wrenio Studio',
			'Wrenio Studio',
			WRENIO_STUDIO_CAPABILITY,
			WRENIO_STUDIO_MENU_SLUG,
			'wrenio_studio_render_dashboard',
			wrenio_studio_get_menu_icon(),
			WRENIO_STUDIO_MENU_POSITION
		);

		// WP auto-generates a duplicate submenu with the parent's label.
		// Re-register the same slug with a different label ("Dashboard") to
		// override that auto-entry. Without this, the sidebar shows two
		// "Wrenio Studio" entries — see design.md §2.
		add_submenu_page(
			WRENIO_STUDIO_MENU_SLUG,
			'Wrenio Studio',
			'Dashboard',
			WRENIO_STUDIO_CAPABILITY,
			WRENIO_STUDIO_MENU_SLUG,
			'wrenio_studio_render_dashboard'
		);
	}
}

/**
 * Returns the WP admin sidebar menu icon as a base64 data URI.
 * Falls back to a Dashicon name if the SVG file cannot be loaded.
 *
 * @return string
 */
if ( ! function_exists( 'wrenio_studio_get_menu_icon' ) ) {
	function wrenio_studio_get_menu_icon() {
		$svg_path = WRENIO_STUDIO_HOST_PATH . 'assets/images/wrenio-menu-icon.svg';
		if ( is_readable( $svg_path ) ) {
			$svg = file_get_contents( $svg_path );
			if ( $svg ) {
				return 'data:image/svg+xml;base64,' . base64_encode( $svg );
			}
		}
		return 'dashicons-screenoptions';
	}
}

/**
 * Returns the URL to the Wrenio Studio full logo SVG.
 *
 * @return string
 */
if ( ! function_exists( 'wrenio_studio_get_logo_url' ) ) {
	function wrenio_studio_get_logo_url() {
		return WRENIO_STUDIO_HOST_URL . 'assets/images/wrenio-logo.svg';
	}
}

/**
 * Returns the URL to the Wrenio brand icon SVG (full color, for plugin pages).
 *
 * @return string
 */
if ( ! function_exists( 'wrenio_studio_get_brand_icon_url' ) ) {
	function wrenio_studio_get_brand_icon_url() {
		return WRENIO_STUDIO_HOST_URL . 'assets/images/wrenio-icon.svg';
	}
}

/**
 * Echoes a small footer signature on every Wrenio plugin admin page.
 *
 * A quiet single-line "Wrenio Studio" link to wrenio.studio. Earlier
 * iterations included a leading em-dash and the host plugin's version
 * — both removed because they competed with the version already shown
 * in the page header strip. See design.md §13.
 */
if ( ! function_exists( 'wrenio_studio_render_footer' ) ) {
	function wrenio_studio_render_footer() {
		?>
		<footer class="wrenio-studio-footer">
			<a
				href="https://wrenio.studio/"
				target="_blank"
				rel="noopener noreferrer"
				class="wrenio-studio-footer__link"
			><?php esc_html_e( 'Wrenio Studio', 'wrenio-media-offload' ); ?></a>
		</footer>
		<?php
	}
}

/**
 * Whether the current user has paid-tier access in this build.
 *
 * Returns true if Freemius reports the user has paid-tier access. This
 * is the runtime check used by views to decide whether to render the
 * live action button. In the Free build this returns false and the
 * gated UI elements are simply not rendered. Note: this is the
 * unsuffixed `can_use_premium_code()` — it works in both the WP.org
 * (free) build and the Pro build. Use the `__premium_only`-suffixed
 * version only at top-level conditional sites where the entire `if`
 * block should be physically stripped from the WP.org build.
 *
 * @return bool
 */
if ( ! function_exists( 'wrenio_studio_can_use_pro' ) ) {
	function wrenio_studio_can_use_pro() {
		return function_exists( 'wrenio_fs' ) && wrenio_fs()->can_use_premium_code();
	}
}

/**
 * Echoes the wren silhouette as inline SVG using currentColor.
 *
 * Used inside plugin page headers, where the mark sits next to the plugin
 * name as a unified wordmark (see design.md §6). Inline SVG lets the mark
 * inherit color from CSS — set --wrenio-jacarta on the parent and the
 * silhouette fills with that color.
 *
 * The path data is read from wrenio-menu-icon.svg (the same simplified
 * silhouette used in the WP admin sidebar). Only the fill is swapped from
 * the file's static color to currentColor.
 */
if ( ! function_exists( 'wrenio_studio_render_mark' ) ) {
	function wrenio_studio_render_mark() {
		$svg_path = WRENIO_STUDIO_HOST_PATH . 'assets/images/wrenio-menu-icon.svg';
		if ( ! is_readable( $svg_path ) ) {
			return;
		}
		$svg = file_get_contents( $svg_path );
		if ( ! $svg ) {
			return;
		}
		// Replace any explicit fill color with currentColor so CSS controls it.
		$svg = preg_replace( '/fill="[^"]*"/', 'fill="currentColor"', $svg );
		// Output through wp_kses with an SVG allowlist. Per design.md §16.3,
		// wp_kses() at the echo site is the canonical way to output a built
		// HTML fragment. The allowlist covers every tag/attribute used by the
		// bundled icon, so nothing is stripped.
		$allowed_svg = array(
			'svg'  => array(
				'xmlns'       => true,
				'viewbox'     => true,
				'width'       => true,
				'height'      => true,
				'fill'        => true,
				'fill-rule'   => true,
				'clip-rule'   => true,
				'role'        => true,
				'aria-hidden' => true,
				'focusable'   => true,
				'class'       => true,
			),
			'g'    => array(
				'fill'      => true,
				'fill-rule' => true,
				'clip-rule' => true,
				'transform' => true,
			),
			'path' => array(
				'd'         => true,
				'fill'      => true,
				'fill-rule' => true,
				'clip-rule' => true,
				'opacity'   => true,
			),
		);
		echo wp_kses( $svg, $allowed_svg );
	}
}

/**
 * Renders the Wrenio Studio landing page (the page shown when the parent
 * menu item is clicked).
 *
 * Three sections per design.md §3:
 *   1. Brief introduction
 *   2. Cards for installed Wrenio plugins
 *   3. Placeholder for "more Wrenio plugins" — live fetch lands in v1.1.0
 */
if ( ! function_exists( 'wrenio_studio_render_dashboard' ) ) {
	function wrenio_studio_render_dashboard() {
		if ( ! current_user_can( WRENIO_STUDIO_CAPABILITY ) ) {
			wp_die( esc_html__( 'You do not have permission to view this page.', 'wrenio-media-offload' ) );
		}

		// Each Wrenio plugin registers itself via this filter.
		// Expected shape per entry:
		//   $plugins[ 'wrenio-media-offload' ] = array(
		//       'name'        => 'Wrenio Media Offload',
		//       'description' => 'Offload WP media to Cloudflare R2.',
		//       'version'     => '1.0.0',
		//       'main_page'   => admin_url( 'admin.php?page=wrenio-media-offload' ),
		//   );
		$plugins = apply_filters( 'wrenio_studio_plugins', array() );

		?>
		<div class="wrap wrenio-studio-dashboard">

			<!-- SECTION 1 — Intro card. Logo carries the brand name; no
			     redundant H1 next to it (see design.md §3). -->
			<section class="wrenio-studio-section wrenio-studio-section--hero">
				<div class="wrenio-studio-hero">
					<div class="wrenio-studio-hero__brand">
						<a
							href="https://wrenio.studio/"
							target="_blank"
							rel="noopener noreferrer"
							class="wrenio-studio-hero__brand-link"
							aria-label="<?php esc_attr_e( 'Wrenio Studio website (opens in a new tab)', 'wrenio-media-offload' ); ?>"
						>
							<img
								src="<?php echo esc_url( wrenio_studio_get_logo_url() ); ?>"
								alt="<?php esc_attr_e( 'Wrenio Studio', 'wrenio-media-offload' ); ?>"
								class="wrenio-studio-hero__logo"
							/>
						</a>
					</div>
					<div class="wrenio-studio-hero__copy">
						<p class="wrenio-studio-eyebrow"><?php esc_html_e( 'A studio for small WordPress tools', 'wrenio-media-offload' ); ?></p>
						<p class="wrenio-studio-lede"><?php esc_html_e( 'Lean WordPress plugins, built for sites that move fast and need to stay light.', 'wrenio-media-offload' ); ?></p>
					</div>
				</div>
			</section>

			<!-- SECTION 2 — Installed Wrenio plugins. -->
			<section class="wrenio-studio-section">
				<p class="wrenio-studio-eyebrow"><?php esc_html_e( 'Installed', 'wrenio-media-offload' ); ?></p>
				<h2 class="wrenio-studio-section__title"><?php esc_html_e( 'Your Wrenio tools', 'wrenio-media-offload' ); ?></h2>

				<?php if ( empty( $plugins ) ) : ?>
					<p class="wrenio-studio-empty">
						<?php esc_html_e( 'No Wrenio plugins are currently registered. If a plugin is active but not appearing here, it may not yet be Wrenio Studio compatible.', 'wrenio-media-offload' ); ?>
					</p>
				<?php else : ?>
					<div class="wrenio-studio-card-grid">
						<?php foreach ( $plugins as $slug => $plugin ) : ?>
							<article class="wrenio-studio-card">
								<header class="wrenio-studio-card__header">
									<h3 class="wrenio-studio-card__name">
										<?php echo esc_html( ! empty( $plugin['name'] ) ? $plugin['name'] : $slug ); ?>
									</h3>
									<?php if ( ! empty( $plugin['version'] ) ) : ?>
										<span class="wrenio-studio-card__version">v<?php echo esc_html( $plugin['version'] ); ?></span>
									<?php endif; ?>
								</header>

								<?php if ( ! empty( $plugin['description'] ) ) : ?>
									<p class="wrenio-studio-card__description">
										<?php echo esc_html( $plugin['description'] ); ?>
									</p>
								<?php endif; ?>

								<?php if ( ! empty( $plugin['main_page'] ) ) : ?>
									<a class="wrenio-studio-button wrenio-studio-button--primary" href="<?php echo esc_url( $plugin['main_page'] ); ?>">
										<?php esc_html_e( 'Open', 'wrenio-media-offload' ); ?>
									</a>
								<?php endif; ?>
							</article>
						<?php endforeach; ?>
					</div>
				<?php endif; ?>
			</section>

			<!-- SECTION 3 — Placeholder for v1.0.0 (live fetch in v1.1.0). -->
			<section class="wrenio-studio-section wrenio-studio-section--muted">
				<p class="wrenio-studio-eyebrow"><?php esc_html_e( 'More from Wrenio Studio', 'wrenio-media-offload' ); ?></p>
				<h2 class="wrenio-studio-section__title"><?php esc_html_e( 'More Wrenio Studio plugins', 'wrenio-media-offload' ); ?></h2>
				<p class="wrenio-studio-lede"><?php esc_html_e( 'Coming soon.', 'wrenio-media-offload' ); ?></p>
			</section>

			<?php wrenio_studio_render_footer(); ?>

		</div>
		<?php
	}
}

/**
 * Enqueues the shared Wrenio Studio admin stylesheet on Wrenio admin pages
 * (the parent landing page and any plugin's submenu page under it).
 *
 * Hooked once at the bottom of this file — WP de-duplicates identical
 * (callback, priority) pairs, so multiple plugins loading this file
 * does not produce multiple invocations.
 *
 * @param string $hook The current admin page hook name.
 */
if ( ! function_exists( 'wrenio_studio_enqueue_admin_assets' ) ) {
	function wrenio_studio_enqueue_admin_assets( $hook ) {
		// The page hook for the top-level menu is "toplevel_page_wrenio-studio".
		// Submenu pages have hooks like "wrenio-studio_page_<submenu-slug>".
		$is_wrenio_page =
			'toplevel_page_' . WRENIO_STUDIO_MENU_SLUG === $hook
			|| 0 === strpos( $hook, WRENIO_STUDIO_MENU_SLUG . '_page_' );

		if ( ! $is_wrenio_page ) {
			return;
		}

		wp_enqueue_style(
			'wrenio-studio-admin',
			WRENIO_STUDIO_HOST_URL . 'assets/css/wrenio-studio-admin.css',
			array(),
			wrenio_studio_get_admin_css_version()
		);
	}
}

/**
 * Returns a cache-busting version string for the admin CSS.
 * Uses the host plugin's CSS file mtime so updates reload immediately
 * during development.
 *
 * @return string
 */
if ( ! function_exists( 'wrenio_studio_get_admin_css_version' ) ) {
	function wrenio_studio_get_admin_css_version() {
		$css_path = WRENIO_STUDIO_HOST_PATH . 'assets/css/wrenio-studio-admin.css';
		if ( is_readable( $css_path ) ) {
			return (string) filemtime( $css_path );
		}
		return '1.0.0';
	}
}

/* ---------------------------------------------------------------------------
 * Hook registration. WP de-duplicates same callback at same priority,
 * so multiple plugins loading this file results in a single registration.
 * ------------------------------------------------------------------------- */

add_action( 'admin_enqueue_scripts', 'wrenio_studio_enqueue_admin_assets' );
