<?php
/**
 * WeCodeArt Framework.
 *
 * WARNING: This file is part of the core WeCodeArt Framework. DO NOT edit this file under any circumstances.
 * Please do all modifications in the form of a child theme.
 *
 * @package 	WeCodeArt Framework
 * @subpackage 	Admin
 * @copyright   Copyright (c) 2025, WeCodeArt Framework
 * @since 		3.8.1
 * @version		6.3.7
 */

namespace WeCodeArt;

defined( 'ABSPATH' ) || exit;

use WeCodeArt\Admin\{ Upgrade, Request, Settings, Installer, Activation, Notifications };
use WeCodeArt\Config\Traits\{ Asset, Singleton };
use function WeCodeArt\Functions\get_prop;

/**
 * Admin Side Functionality
 */
class Admin {

	use Singleton;
	use Asset;

	const NAMESPACE = 'wecodeart/v1';
	CONST CACHE_KEY = 'wecodeart/transient/notifications';

	var $page;

	/**
	 * Send to Constructor
	 */
	public function init() {
		\add_action( 'rest_api_init',	[ $this, 'register_routes' 		] );
		\add_action( 'admin_menu',		[ $this, 'register_menu_page' 	] );
		\add_action( 'admin_init', 		[ $this, 'add_security_notifications' ], 20 );

		Upgrade::get_instance();
		Settings::get_instance();
		Activation::get_instance();
		Notifications::get_instance();

		new Installer\Plugin\Ajax();
		new Installer\Module\Ajax();
		new Installer\Theme\Ajax(); 
	}

	/**
	 * Register Rest Routes
	 *
	 * @since   5.0.0
	 * @version 6.1.2
	 */
	public function register_routes() {
		register_rest_route( self::NAMESPACE, '/settings', [
			'methods'  => \WP_REST_Server::ALLMETHODS,
			'callback' => function( $request ) {
				// Unset Default Params
				$params = array_filter( $request->get_params(), function( $key ) {
					return( ! in_array( $key, [ 'context', '_locale', '_filter' ] ) );
				}, ARRAY_FILTER_USE_KEY );
			
				// Update if params with values
				if( ! empty( $params ) ) {
					wecodeart( 'options' )::set( array_filter( $params ) );
				}

				// Get values, updated above
				$data = wecodeart( 'options' )::all();

				// If params provided, return only their values
				if( $request->get_param( '_filter' ) ) {
					$data = array_intersect_key( $data, $params );
				}

				return rest_ensure_response( $data );
			},
			'permission_callback' => static fn() => current_user_can( 'manage_options' ),
		] );
		
		register_rest_route( self::NAMESPACE, '/notifications', [
			'methods'  => \WP_REST_Server::READABLE,
			'callback' => function( $request ) {
				// Get the response.
				$url 	= 'https://raw.githubusercontent.com/BicanMarianValeriu/wecodeart-framework/master/notifications.json';
				if ( false === ( $data = get_transient( self::CACHE_KEY ) ) ) {
					$request	= new Request( $url, [] );
					$request->send( $request::METHOD_GET );
		
					$results = $request->get_response_body( true );
					
					if( ! empty( $results ) ) {
						// Clear and sanitize data.
						$data = [
							'items' => array_map( [ __CLASS__, 'sanitize_notification' ], get_prop( $results, [ 'items' ], [] ) )
						];
					}
		
					set_transient( self::CACHE_KEY, $data, MINUTE_IN_SECONDS );
				}

				return rest_ensure_response( $data );
			},
			'permission_callback' => static fn() => current_user_can( 'manage_options' ),
		] );
	}

	/**
	 * Register Admin Page
	 *
	 * @since   5.0.0
	 * @version 6.1.2
	 */
	public function register_menu_page() {
		$this->page = add_theme_page(
			__( 'Theme Options', 'wecodeart' ),
			__( 'Theme Options', 'wecodeart' ),
			'manage_options',
			'wecodeart',
			[ $this, 'menu_callback' ]
		);

		add_action( "admin_print_scripts-{$this->page}", [ $this, 'enqueue_assets' ] );
	}

	/**
	 * Register Admin Page
	 *
	 * @since   5.0.0
	 */
	public function menu_callback() {
		?><div id="wecodeart" class="wecodeart-admin"></div><?php
	}

	/**
	 * Load assets for option page.
	 *
	 * @since   1.2.0
	 * @version	6.1.2
	 */
	public function enqueue_assets() {
		$version = wecodeart( 'version' );

		wp_enqueue_style(
			$this->make_handle(),
			$this->get_asset( 'css', 'admin/admin' ),
			[ 'wp-components' ],
			$version
		);

		wp_enqueue_script(
			$this->make_handle(),
			$this->get_asset( 'js', 'admin/admin' ),
			[ 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-plugins', 'wp-components', 'wp-edit-post', 'wp-api', 'wp-editor', 'wp-hooks' ],
			$version,
			true
		);

		wp_localize_script( $this->make_handle(), 'wecodeart', [
			'theme'			=> [
				'name'		=> wecodeart( 'name' ),
				'version'	=> wecodeart_if( 'is_dev_mode' ) ? esc_html__( 'Developer Mode', 'wecodeart' ) : $version,
			],
			'currentUser'	=> wp_get_current_user()->display_name,
			'adminUrl'		=> untrailingslashit( esc_url_raw( admin_url() ) ),
			'restUrl' 		=> untrailingslashit( esc_url_raw( rest_url( 'wecodeart/v1' ) ) ),
			'adminEmail'	=> get_bloginfo( 'admin_email' ),
			'themeDirs'		=> wecodeart_config( 'paths' )
		] );
		
		wp_set_script_translations( $this->make_handle(), 'wecodeart', wecodeart_config( 'directories' )['languages'] );
	}

	/**
     * Sanitize
	 *
	 * @param	array $json
     *
     * @return 	array
     */
	protected static function sanitize_notification( array $json = [] ): array {
		// Remove invalid properties.
		$json = wp_array_slice_assoc( $json, [ 'type', 'title', 'content' ] );

		$sanitized = [];

		foreach( $json as $key => $value ) {
			switch( $key ) :
				// Strings
				case 'type':
				case 'title':
					$sanitized[$key] = sanitize_text_field( $value );
				break;
				// Content
				case 'content':
					$sanitized[$key] = wp_kses_post( $value );
				break;
				// Unfiltered
				default:
					$sanitized[$key] = $value;
				break;
			endswitch;
		}

		return $sanitized;
	}

	/**
	 * Add security notifications
	 *
	 * @since 	6.7.0
	 *
	 * @return 	void
	 */
	public function add_security_notifications(): void {
		// Only show on theme admin page
		if ( ! wecodeart_if( 'is_theme_admin' ) ) {
			return;
		}

		$modules 		= wecodeart_option( 'modules', [] );
		$security 		= \WeCodeArt\Support\Modules\Security::get_instance();
		$notifications 	= Notifications::get_instance();

		foreach ( $modules as $module ) {
			$module_name = get_prop( $module, 'destination', '' );
			if ( ! $module_name ) {
				continue;
			}

			$issues = $security->get_security_issues( $module_name );
			if ( ! empty( $issues ) ) {
				$this->create_security_notification( $module_name, $issues, $notifications );
			}
		}
	}

	/**
	 * Create security notification for a module
	 *
	 * @param  string $module_name
	 * @param  array  $issues
	 * @param  Notifications $notifications
	 * @return void
	 */
	private function create_security_notification( string $module_name, array $issues, Notifications $notifications ): void {
		$notification_id = 'wecodeart-security-' . sanitize_title( $module_name );
		
		// Check if notification already exists
		$existing = $notifications->get_notification_by_id( $notification_id );
		if ( $existing ) {
			return;
		}

		// Create notification message
		$message = sprintf( 
			__( 'Security issues detected in module "%s". Please review the module files for security concerns.', 'wecodeart' ),
			esc_html( $module_name )
		);

		// Add issue details
		if ( count( $issues ) > 0 ) {
			$message .= '<ul>';
			foreach ( $issues as $issue ) {
				$message .= '<li>' . esc_html( $issue['message'] ) . '</li>';
			}
			$message .= '</ul>';
		}

		// Create notification
		$notification = new \WeCodeArt\Admin\Notifications\Notification(
			$message,
			[
				'id'            => $notification_id,
				'type'          => 'warning',
				'priority'      => 0.8,
				'dismissal_key' => 'wecodeart_security_' . sanitize_title( $module_name ),
				'capabilities'  => [ 'manage_options' ],
			]
		);

		$notifications->add_notification( $notification );
	}
}