<?php
/**
 * Full-screen editor shell + asset enqueue.
 *
 * @package AuraBuilder
 */

declare(strict_types=1);

namespace AuraBuilder\Admin;

use AuraBuilder\REST\RestRegistrar;
use AuraBuilder\Theme\ThemeStyles;

final class EditorPage {

	public function hooks(): void {
		add_action( 'admin_menu', array( $this, 'menu' ), 20 );
		add_action( 'admin_init', array( $this, 'redirect_legacy_slug' ) );
		add_action( 'edit_form_after_title', array( $this, 'button' ) );
		add_filter( 'page_row_actions', array( $this, 'row' ), 10, 2 );
		add_filter( 'post_row_actions', array( $this, 'row' ), 10, 2 );
		add_action( 'admin_bar_menu', array( $this, 'bar' ), 80 );
		add_action( 'admin_enqueue_scripts', array( $this, 'assets' ) );
		// Renova nonce REST via admin-ajax (cookies de login bastam; não exige X-WP-Nonce).
		add_action( 'wp_ajax_aptb_rest_nonce', array( $this, 'ajax_rest_nonce' ) );
	}

	/**
	 * Old slug after text-domain rename — keep bookmarks working.
	 */
	public function redirect_legacy_slug(): void {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( empty( $_GET['page'] ) || (string) $_GET['page'] !== 'auranet-page-theme-builder' ) {
			return;
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$args = wp_unslash( $_GET );
		if ( ! is_array( $args ) ) {
			$args = array();
		}
		$args['page'] = 'aura-builder';
		wp_safe_redirect( admin_url( 'admin.php?' . http_build_query( $args ) ) );
		exit;
	}

	/**
	 * Fresh wp_rest nonce for long-lived editor sessions (cookie auth refresh).
	 */
	public function ajax_rest_nonce(): void {
		if ( ! is_user_logged_in() ) {
			wp_send_json_error( array( 'message' => 'Não autenticado' ), 403 );
		}
		if ( ! \AuraBuilder\Support\Capabilities::can_use_builder() ) {
			wp_send_json_error( array( 'message' => 'Sem permissão' ), 403 );
		}
		wp_send_json_success(
			array(
				'nonce' => wp_create_nonce( 'wp_rest' ),
			)
		);
	}

	public function menu(): void {
		// MUST use slug "aura-builder" — all links (Páginas, Theme Builder, bar) use page=aura-builder.
		// Parent must be a real menu slug so WP can resolve capability (null parent → "Sem permissão").
		add_submenu_page(
			'aura-builder-pages',
			'Editor Aura Builder',
			'Editor',
			'edit_pages',
			'aura-builder',
			array( $this, 'render' )
		);
	}

	public function render(): void {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$mode = isset( $_GET['mode'] ) ? sanitize_key( (string) $_GET['mode'] ) : '';
		// Theme Builder: header / footer / single (no post required).
		if ( in_array( $mode, array( 'header', 'footer', 'single' ), true ) ) {
			if ( ! \AuraBuilder\Support\Capabilities::can_edit_theme_parts() ) {
				wp_die(
					esc_html__( 'Sem permissão para editar Header/Footer. Faça login como administrador ou editor de páginas.', 'auranet-page-theme-builder' ),
					esc_html__( 'Sem permissão', 'auranet-page-theme-builder' ),
					array( 'response' => 403 )
				);
			}
			echo '<div id="aura-builder-root" class="ab-root" data-ab-mode="' . esc_attr( $mode ) . '"></div>';
			return;
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0;
		if ( ! $id ) {
			// Missing post id — send user to the pages list (main hub).
			if ( \AuraBuilder\Support\Capabilities::can_use_builder() ) {
				wp_safe_redirect( admin_url( 'admin.php?page=aura-builder-pages' ) );
				exit;
			}
			wp_die(
				esc_html__( 'Sem permissão para acessar o Aura Builder. Faça login como Administrador ou Editor.', 'auranet-page-theme-builder' ),
				esc_html__( 'Sem permissão', 'auranet-page-theme-builder' ),
				array( 'response' => 403 )
			);
		}
		if ( ! \AuraBuilder\Support\Capabilities::can_edit_post( $id ) ) {
			wp_die(
				esc_html__( 'Sem permissão para editar esta página/post. Confirme que está logado com um usuário que pode editar o conteúdo.', 'auranet-page-theme-builder' ),
				esc_html__( 'Sem permissão', 'auranet-page-theme-builder' ),
				array( 'response' => 403 )
			);
		}
		echo '<div id="aura-builder-root" class="ab-root"></div>';
	}

	public function button( \WP_Post $post ): void {
		if ( ! in_array( $post->post_type, array( 'page', 'post' ), true ) ) {
			return;
		}
		if ( ! current_user_can( 'edit_post', $post->ID ) ) {
			return;
		}
		printf(
			'<p><a class="button button-primary button-hero" href="%s">%s</a></p>',
			esc_url( $this->url( (int) $post->ID ) ),
			esc_html__( 'Editar com Aura Builder', 'auranet-page-theme-builder' )
		);
	}

	/**
	 * @param array<string, string> $actions
	 * @return array<string, string>
	 */
	public function row( array $actions, \WP_Post $post ): array {
		if ( ! in_array( $post->post_type, array( 'page', 'post' ), true ) || ! current_user_can( 'edit_post', $post->ID ) ) {
			return $actions;
		}
		$actions['aura_builder'] = '<a href="' . esc_url( $this->url( (int) $post->ID ) ) . '">Aura Builder</a>';
		return $actions;
	}

	/**
	 * @param \WP_Admin_Bar $bar
	 */
	public function bar( $bar ): void {
		if ( ! is_singular() || ! is_admin_bar_showing() ) {
			return;
		}
		$id = get_queried_object_id();
		if ( ! $id || ! current_user_can( 'edit_post', $id ) ) {
			return;
		}
		$bar->add_node(
			array(
				'id'    => 'auranet-page-theme-builder',
				'title' => 'Aura Builder',
				'href'  => $this->url( $id ),
			)
		);
	}

	public function assets( string $hook ): void {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$page = isset( $_GET['page'] ) ? sanitize_key( (string) $_GET['page'] ) : '';
		// Accept legacy slug (renamed after text-domain change) and redirect-safe alias.
		if ( $page !== 'aura-builder' && $page !== 'auranet-page-theme-builder' ) {
			return;
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$mode = isset( $_GET['mode'] ) ? sanitize_key( (string) $_GET['mode'] ) : '';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0;
		$theme_mode = in_array( $mode, array( 'header', 'footer', 'single' ), true );
		if ( ! $id && ! $theme_mode ) {
			return;
		}
		if ( $theme_mode ) {
			$id = 0;
		}

		// Theme styles so the canvas body inherits fonts/colors/spacing from the site.
		$theme = new ThemeStyles();
		foreach ( $theme->links() as $i => $url ) {
			wp_enqueue_style( 'aura-builder-theme-ed-' . $i, $url, array(), null );
		}
		wp_register_style( 'aura-builder-theme-ed-inline', false, array(), AURA_BUILDER_VERSION );
		wp_enqueue_style( 'aura-builder-theme-ed-inline' );
		// Scope variables work on :root; bridge targets .ab-page-body.
		wp_add_inline_style( 'aura-builder-theme-ed-inline', $theme->inline() );

		// Media library for gallery / image picker.
		wp_enqueue_media();

		$built = $this->enqueue_built_editor();
		if ( ! $built ) {
			// Fallback: vanilla editor while Vite build is missing.
			wp_enqueue_style(
				'aura-builder-editor',
				AURA_BUILDER_URL . 'frontend/css/editor-shell.css',
				array( 'aura-builder-theme-ed-inline' ),
				AURA_BUILDER_VERSION
			);
			wp_enqueue_style(
				'aura-builder-front',
				AURA_BUILDER_URL . 'frontend/css/front.css',
				array( 'aura-builder-theme-ed-inline' ),
				AURA_BUILDER_VERSION
			);
			$fallback = AURA_BUILDER_PATH . 'frontend/js/editor-fallback.js';
			wp_enqueue_script(
				'aura-builder-editor',
				AURA_BUILDER_URL . 'frontend/js/editor-fallback.js',
				array( 'jquery', 'media-editor', 'media-views' ),
				is_file( $fallback ) ? (string) filemtime( $fallback ) : AURA_BUILDER_VERSION,
				true
			);
		}

		$script_handle = $built ? 'aura-builder-editor-js' : 'aura-builder-editor';
		// Theme mode: Voltar → página de origem (?return=ID|single) ou lista Theme Builder.
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$return_raw  = isset( $_GET['return'] ) ? sanitize_text_field( wp_unslash( (string) $_GET['return'] ) ) : '';
		$return_post = absint( $return_raw );
		if ( $theme_mode && $return_raw === 'single' ) {
			$back = admin_url( 'admin.php?page=aura-builder&mode=single' );
		} elseif ( $theme_mode && $return_post && current_user_can( 'edit_post', $return_post ) ) {
			$back = $this->url( $return_post );
		} elseif ( $theme_mode ) {
			$back = admin_url( 'admin.php?page=aura-builder-theme' );
		} else {
			$back = admin_url( 'admin.php?page=aura-builder-pages' );
		}
		wp_localize_script(
			$script_handle,
			'AuraBuilderConfig',
			array(
				'postId'      => $id,
				'editorMode'  => $theme_mode ? $mode : 'page',
				'restUrl'     => esc_url_raw( rest_url( RestRegistrar::NS ) ),
				'nonce'       => wp_create_nonce( 'wp_rest' ),
				'ajaxUrl'     => admin_url( 'admin-ajax.php' ),
				'viewUrl'     => $id ? get_permalink( $id ) : home_url( '/' ),
				'editUrl'     => $id ? get_edit_post_link( $id, 'raw' ) : '',
				// "Voltar" → lista do Aura Builder (não o editor de blocos).
				'backUrl'     => $back,
				'version'     => AURA_BUILDER_VERSION,
				'themeStyles' => $theme->for_editor(),
				'hasMedia'    => true,
				'siteName'    => get_bloginfo( 'name' ),
				'siteTagline' => get_bloginfo( 'description' ),
				'homeUrl'     => home_url( '/' ),
				'logoUrl'     => $this->site_logo_url(),
				// Branding do plugin (barra do editor).
				'pluginLogo'  => defined( 'AURA_BUILDER_LOGO_64_URL' ) ? AURA_BUILDER_LOGO_64_URL : '',
				'categories'  => $this->list_categories(),
				// Menus WP com itens (prévia real no editor, não só nome).
				'navMenus'    => $this->list_nav_menus(),
				// Formatos de data/hora iguais a Ajustes → Geral do WordPress.
				'dateFormat'  => (string) get_option( 'date_format', 'd/m/Y' ),
				'timeFormat'  => (string) get_option( 'time_format', 'H:i' ),
			)
		);
	}

	/**
	 * Nested menu tree for editor preview (matches NavMenuWidget::tree_from_wp_menu).
	 *
	 * @return list<array{id:int,name:string,slug:string,count:int,items:list<array<string,mixed>>}>
	 */
	private function list_nav_menus(): array {
		$menus = wp_get_nav_menus();
		$out   = array();
		if ( ! is_array( $menus ) ) {
			return $out;
		}
		foreach ( $menus as $m ) {
			$tree = array();
			try {
				if ( class_exists( \AuraBuilder\Widgets\Basic\NavMenuWidget::class ) ) {
					$tree = \AuraBuilder\Widgets\Basic\NavMenuWidget::tree_from_wp_menu( (int) $m->term_id );
				}
			} catch ( \Throwable $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
				$tree = array();
			}
			if ( ! is_array( $tree ) ) {
				$tree = array();
			}
			$out[] = array(
				'id'    => (int) $m->term_id,
				'name'  => (string) $m->name,
				'slug'  => (string) $m->slug,
				'count' => (int) $m->count,
				'items' => $tree,
			);
		}
		return $out;
	}

	/**
	 * @return list<array{id:int,name:string,slug:string,count:int}>
	 */
	private function list_categories(): array {
		$terms = get_terms(
			array(
				'taxonomy'   => 'category',
				'hide_empty' => false,
				'number'     => 200,
				'orderby'    => 'name',
				'order'      => 'ASC',
			)
		);
		if ( is_wp_error( $terms ) || ! is_array( $terms ) ) {
			return array();
		}
		$out = array();
		foreach ( $terms as $t ) {
			if ( ! $t instanceof \WP_Term ) {
				continue;
			}
			// Skip "Uncategorized" optional — keep all for search.
			$out[] = array(
				'id'    => (int) $t->term_id,
				'name'  => (string) $t->name,
				'slug'  => (string) $t->slug,
				'count' => (int) $t->count,
			);
		}
		return $out;
	}

	private function site_logo_url(): string {
		if ( function_exists( 'has_custom_logo' ) && has_custom_logo() ) {
			$logo_id = (int) get_theme_mod( 'custom_logo' );
			if ( $logo_id ) {
				$url = wp_get_attachment_image_url( $logo_id, 'medium' );
				if ( is_string( $url ) ) {
					return $url;
				}
			}
		}
		return '';
	}

	private function enqueue_built_editor(): bool {
		$manifest_path = AURA_BUILDER_PATH . 'assets/editor/.vite/manifest.json';
		// Vite 6 may put manifest at assets/editor/manifest.json
		if ( ! is_file( $manifest_path ) ) {
			$manifest_path = AURA_BUILDER_PATH . 'assets/editor/manifest.json';
		}
		if ( ! is_file( $manifest_path ) ) {
			return false;
		}
		$manifest = json_decode( (string) file_get_contents( $manifest_path ), true );
		if ( ! is_array( $manifest ) ) {
			return false;
		}

		// Find index entry.
		$entry = $manifest['index.html'] ?? null;
		if ( ! is_array( $entry ) ) {
			foreach ( $manifest as $item ) {
				if ( is_array( $item ) && ! empty( $item['isEntry'] ) ) {
					$entry = $item;
					break;
				}
			}
		}
		if ( ! is_array( $entry ) || empty( $entry['file'] ) ) {
			return false;
		}

		$base = AURA_BUILDER_URL . 'assets/editor/';
		if ( ! empty( $entry['css'] ) && is_array( $entry['css'] ) ) {
			foreach ( $entry['css'] as $i => $css ) {
				wp_enqueue_style( 'aura-builder-editor-css-' . $i, $base . $css, array(), AURA_BUILDER_VERSION );
			}
		}
		wp_enqueue_style( 'aura-builder-front', AURA_BUILDER_URL . 'frontend/css/front.css', array(), AURA_BUILDER_VERSION );
		wp_enqueue_script(
			'aura-builder-editor-js',
			$base . $entry['file'],
			array(),
			AURA_BUILDER_VERSION,
			true
		);
		return true;
	}

	private function url( int $id ): string {
		return add_query_arg(
			array(
				'page' => 'aura-builder',
				'post' => $id,
			),
			admin_url( 'admin.php' )
		);
	}
}
