<?php
/**
 * Admin Dashboard Integration.
 *
 * Handles the WordPress admin interface integration, including settings pages,
 * chat interface, and admin-specific functionality for the assistant.
 *
 * @package   Agenistrator
 * @since     1.0.0
 * @author    Alex Ruban <alex@maximum.guru>
 * @author    Maximum Software Inc <contact@maximum.software>
 * @license   GPL-3.0-only
 * @link      https://maximum.software/
 *
 * SPDX-FileCopyrightText: 2025-2026 Alex Ruban <alex@maximum.guru>
 * SPDX-FileCopyrightText: 2025-2026 Maximum Software Inc <contact@maximum.software>
 * SPDX-License-Identifier: GPL-3.0-only
 */

namespace Agenistrator;

// Direct access prevention
if ( ! defined( 'ABSPATH' ) ) {
	return;
}

/**
 * Admin class.
 */
class Admin implements Maintenance {
	use Singleton;

	/**
	 * Plugin activation tasks for admin
	 * @since     1.0.0
	 */
	public function activate_plugin() {
		// Let the Settings and Chat classes handle their own activation
		$settings = Settings::get_instance();
		if ( method_exists( $settings, 'activate_plugin' ) ) {
			$settings->activate_plugin();
		}

		$chat = Chat::get_instance();
		if ( method_exists( $chat, 'activate_plugin' ) ) {
			$chat->activate_plugin();
		}
	}

	/**
	 * Plugin deactivation tasks for admin
	 * @since     1.0.0
	 */
	public function deactivate_plugin() {
		// Let the Settings and Chat classes handle their own deactivation
		$settings = Settings::get_instance();
		if ( method_exists( $settings, 'deactivate_plugin' ) ) {
			$settings->deactivate_plugin();
		}

		$chat = Chat::get_instance();
		if ( method_exists( $chat, 'deactivate_plugin' ) ) {
			$chat->deactivate_plugin();
		}
	}

	/**
	 * Uninstall plugin
	 * @since     1.0.0
	 */
	public function uninstall_plugin() {
		// Let the Settings and Chat classes handle their own uninstallation
		$settings = Settings::get_instance();
		if ( method_exists( $settings, 'uninstall_plugin' ) ) {
			$settings->uninstall_plugin();
		}

		$chat = Chat::get_instance();
		if ( method_exists( $chat, 'uninstall_plugin' ) ) {
			$chat->uninstall_plugin();
		}
	}

	/**
	 * Register all admin hooks
	 * @since     1.0.0
	 */
	public function register_hooks() {
		// Admin UI hooks
		add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );

		// AJAX handlers
		add_action( 'wp_ajax_agenistrator_delete_report', array( $this, 'ajax_delete_report' ) );
		add_action( 'wp_ajax_agenistrator_delete_all_reports', array( $this, 'ajax_delete_all_reports' ) );

		// Let the Settings and Chat classes register their own hooks
		Settings::get_instance()->register_hooks();
		Chat::get_instance()->register_hooks();
	}

	/**
	 * Load HTML templates for the admin common script
	 *
	 * @return array Associative array of template name => template content
	 * @since     1.0.0
	 */
	public function load_js_script_templates() {

		$templates = array();

		// Define templates for the common script
		$script_templates = array(
			'notice.html',
		);

		$templates_dir = plugin_dir_path( __DIR__ ) . 'admin/html/';
		foreach ( $script_templates as $template_file ) {
			$template_path = $templates_dir . $template_file;
			if ( file_exists( $template_path ) ) {
				// Get the template name without the .html extension for use as the key
				$template_name = basename( $template_file, '.html' );
				// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
				$templates[ $template_name ] = file_get_contents( $template_path );
			}
		}

		return $templates;
	}

	/**
	 * Get localized strings for the admin common script
	 *
	 * @return array Associative array of string keys => localized values
	 * @since     1.0.0
	 */
	public function get_js_strings() {
		// Define strings for the admin common script
		return array(
			// Console/debug messages for common.js
			'invalid_templates_object' => __( 'Invalid templates object', 'agenistrator' ),
			'template_not_found'       => __( 'Template not found: {template_name}', 'agenistrator' ),
			// Common error messages
			'unknown_error'            => __( 'Unknown error', 'agenistrator' ),
		);
	}

	/**
	 * Register admin styles and scripts
	 *
	 * @param string $hook The current admin page hook
	 * @since     1.0.0
	 */
	public function enqueue_scripts( $hook ) {
		// Register common CSS
		wp_register_style( 'agenistrator-common', plugin_dir_url( __FILE__ ) . 'css/common.css', array(), AGENISTRATOR_VERSION );

		// Register common utilities script
		wp_register_script( 'agenistrator-common', plugin_dir_url( __FILE__ ) . 'js/common.js', array( 'jquery' ), AGENISTRATOR_VERSION, true );

		// Register progress bar script
		wp_register_script( 'agenistrator-progress', plugin_dir_url( __FILE__ ) . 'js/progress.js', array( 'jquery', 'agenistrator-common' ), AGENISTRATOR_VERSION, true );

		// Get localized strings for the common script
		$strings = $this->get_js_strings();

		// Get templates for the common script
		$templates = $this->load_js_script_templates();

		// Prepare data for the common script
		$script_data = array(
			'nonce'     => wp_create_nonce( 'agenistrator_nonce' ),
			'strings'   => $strings,
			'templates' => $templates,
		);

		// Localize and enqueue the common script
		wp_localize_script( 'agenistrator-common', 'agenistrator', $script_data );
		wp_enqueue_script( 'agenistrator-common' );

		// Enqueue scripts and styles for the status page
		if ( 'toplevel_page_agenistrator' === $hook ) {
			// Register admin CSS with common CSS as dependency
			wp_register_style( 'agenistrator-admin', plugin_dir_url( __FILE__ ) . 'css/admin.css', array( 'agenistrator-common' ), AGENISTRATOR_VERSION );
			wp_enqueue_style( 'agenistrator-admin' );

			// Register and enqueue status page script
			wp_register_script( 'agenistrator-status', plugin_dir_url( __FILE__ ) . 'js/status.js', array( 'jquery', 'agenistrator-common' ), AGENISTRATOR_VERSION, true );
			wp_localize_script(
				'agenistrator-status',
				'agenistrator_status',
				array(
					'strings' => array(
						'confirm_delete_report'      => __( 'Are you sure you want to delete this report?', 'agenistrator' ),
						'confirm_delete_all_reports' => __( 'Are you sure you want to delete all reports?', 'agenistrator' ),
						'failed_to_delete_report'    => __( 'Failed to delete report', 'agenistrator' ),
						'failed_to_delete_reports'   => __( 'Failed to delete reports', 'agenistrator' ),
					),
				)
			);
			wp_enqueue_script( 'agenistrator-status' );

			// Enqueue progress bar script
			wp_enqueue_script( 'agenistrator-progress' );
		}
	}

	/**
	 * Add admin menu and global interface
	 * @since     1.0.0
	 */
	public function add_admin_menu() {
		// Main menu
		add_menu_page(
			__( 'Agenistrator Status', 'agenistrator' ),
			__( 'Agenistrator', 'agenistrator' ),
			'manage_options',
			'agenistrator',
			array( $this, 'display_status_page' ),
			'dashicons-businessman',
			30
		);

		// Status submenu (replaces auto-generated first submenu item)
		add_submenu_page(
			'agenistrator',
			__( 'Agenistrator Status', 'agenistrator' ),
			__( 'Status', 'agenistrator' ),
			'manage_options',
			'agenistrator',
			array( $this, 'display_status_page' )
		);

		// Settings submenu - delegate to Settings class
		Settings::get_instance()->add_settings_page();

		// About submenu
		add_submenu_page(
			'agenistrator',
			__( 'About Agenistrator', 'agenistrator' ),
			__( 'About', 'agenistrator' ),
			'manage_options',
			'agenistrator-about',
			array( $this, 'display_about_page' )
		);
	}

	/**
	 * Display status page
	 * @since     1.0.0
	 */
	public function display_status_page() {
		// Get plugin status info
		$embedding_count = Embeddings_Manager::get_instance()->get_embeddings_count( 'content' );

		// Get chat model information
		try {
			$chat_model_obj    = LLM_Manager::get_instance()->get_chat_model();
			$chat_model        = $chat_model_obj->get_model_id();
			$chat_status_text  = __( 'Configured', 'agenistrator' );
			$chat_status_color = 'green';
		} catch ( \Throwable $e ) {
			$chat_model        = __( 'Not configured', 'agenistrator' );
			$chat_status_text  = __( 'Not configured', 'agenistrator' );
			$chat_status_color = 'red';
		}

		// Get embeddings model information
		try {
			$embeddings_model_obj    = LLM_Manager::get_instance()->get_embedding_model();
			$embeddings_model        = $embeddings_model_obj->get_model_id();
			$embeddings_status_text  = __( 'Configured', 'agenistrator' );
			$embeddings_status_color = 'green';
		} catch ( \Throwable $e ) {
			$embeddings_model        = __( 'Not configured', 'agenistrator' );
			$embeddings_status_text  = __( 'Not configured', 'agenistrator' );
			$embeddings_status_color = 'red';
		}

		// Render embeddings progress bars (sync + cleanup)
		$embeddings_progress_bars = $this->render_progress_bars( 'embeddings' ) . $this->render_progress_bars( 'embeddings_cleanup' );

		// Prepare attributes for the template
		$attributes = array(
			'page_title'               => esc_html( get_admin_page_title() ),
			'settings_url'             => esc_url( admin_url( 'admin.php?page=agenistrator-settings' ) ),
			'chat_model'               => esc_html( $chat_model ),
			'chat_status_text'         => esc_html( $chat_status_text ),
			'chat_status_color'        => esc_attr( $chat_status_color ),
			'embeddings_model'         => esc_html( $embeddings_model ),
			'embeddings_status_text'   => esc_html( $embeddings_status_text ),
			'embeddings_status_color'  => esc_attr( $embeddings_status_color ),
			'system_status_title'      => esc_html__( 'System Status', 'agenistrator' ),
			'chat_model_label'         => esc_html__( 'Chat Model:', 'agenistrator' ),
			'embeddings_model_label'   => esc_html__( 'Embeddings Model:', 'agenistrator' ),
			'manage_settings_button'   => esc_html__( 'Manage Settings', 'agenistrator' ),
			'embeddings_title'         => esc_html__( 'Embeddings', 'agenistrator' ),
			'total_embeddings_label'   => esc_html__( 'Total Embeddings:', 'agenistrator' ),
			'total_embeddings_count'   => esc_html( Embeddings_Manager::get_instance()->get_embeddings_count() ),
			'content_embeddings_label' => esc_html__( 'Content Embeddings:', 'agenistrator' ),
			'content_embeddings_count' => esc_html( $embedding_count ),
			'embeddings_progress_bars' => $embeddings_progress_bars,
			'embeddings_description'   => esc_html__( 'Embeddings enable semantic search for WordPress content. New content and content changes are automatically processed.', 'agenistrator' ),
			'embeddings_url'           => esc_url( admin_url( 'admin.php?page=agenistrator-settings#embeddings' ) ),
			'manage_embeddings_button' => esc_html__( 'Manage Embeddings', 'agenistrator' ),
			'available_tools_title'    => esc_html__( 'Available Tools', 'agenistrator' ),
			'tools_url'                => esc_url( admin_url( 'admin.php?page=agenistrator-settings#tools' ) ),
			'manage_tools_button'      => esc_html__( 'Manage Tools', 'agenistrator' ),
		);

		// Generate tool stats and names list using Tool Manager
		$tool_manager = Tool_Manager::get_instance();
		$tools        = $tool_manager->get_tools();

		// Calculate tool stats
		$total_count        = count( $tools );
		$enabled_count      = 0;
		$core_count         = 0;
		$read_only_total    = 0;
		$read_only_enabled  = 0;
		$read_write_total   = 0;
		$read_write_enabled = 0;

		foreach ( $tools as $tool_id => $tool ) {
			if ( $tool->is_always_imported() ) {
				++$core_count;
			}
			$is_enabled = $tool_manager->is_tool_enabled( $tool_id );
			if ( $is_enabled ) {
				++$enabled_count;
			}
			if ( $tool->is_read_only() ) {
				++$read_only_total;
				if ( $is_enabled ) {
					++$read_only_enabled;
				}
			} else {
				++$read_write_total;
				if ( $is_enabled ) {
					++$read_write_enabled;
				}
			}
		}

		// Add tool stats to attributes
		$attributes['total_tools_label']        = esc_html__( 'Total Tools:', 'agenistrator' );
		$attributes['total_tools_count']        = esc_html( $total_count );
		$attributes['enabled_tools_label']      = esc_html__( 'Enabled Tools:', 'agenistrator' );
		$attributes['enabled_tools_count']      = esc_html( $enabled_count );
		$attributes['core_tools_label']         = esc_html__( 'Core Tools:', 'agenistrator' );
		$attributes['core_tools_count']         = esc_html( $core_count );
		$attributes['read_only_tools_label']    = esc_html__( 'Read-Only Tools:', 'agenistrator' );
		$attributes['read_only_total_count']    = esc_html( $read_only_total );
		$attributes['read_only_enabled_count']  = esc_html( $read_only_enabled );
		$attributes['read_write_tools_label']   = esc_html__( 'Read-Write Tools:', 'agenistrator' );
		$attributes['read_write_total_count']   = esc_html( $read_write_total );
		$attributes['read_write_enabled_count'] = esc_html( $read_write_enabled );

		// Render the reports card
		$attributes['reports_card'] = $this->render_reports_card();

		// Render the template
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Template system outputs pre-escaped HTML; all $attributes values are escaped above
		echo String_Utils::render( 'dashboard', $attributes );
	}

	/**
	 * Display about page
	 *
	 * @since 1.0.0
	 */
	public function display_about_page() {
		$attributes = array(
			'page_title'        => esc_html( get_admin_page_title() ),
			'plugin_info_title' => esc_html__( 'Plugin Information', 'agenistrator' ),
			'version_label'     => esc_html__( 'Version:', 'agenistrator' ),
			'version'           => esc_html( AGENISTRATOR_VERSION ),
			'authors_label'     => esc_html__( 'Authors:', 'agenistrator' ),
			'website_label'     => esc_html__( 'Website:', 'agenistrator' ),
			'support_label'     => esc_html__( 'Support:', 'agenistrator' ),
			'license_title'     => esc_html__( 'License', 'agenistrator' ),
			'license_text'      => String_Utils::replace_tags(
				/* translators: {a-href} and {/a} are HTML link tags wrapping the license name */
				esc_html__( 'This plugin is free software licensed under the {a-href}GNU General Public License v3.0{/a}.', 'agenistrator' ),
				array(
					'a-href' => '<a href="https://www.gnu.org/licenses/gpl-3.0.html" target="_blank" rel="noopener noreferrer">',
					'/a'     => '</a>',
				)
			),
			'view_full_license' => String_Utils::replace_tags(
				/* translators: {a-href} and {/a} are HTML link tags */
				esc_html__( '{a-href}View Full License Text{/a}', 'agenistrator' ),
				array(
					'a-href' => '<a href="https://www.gnu.org/licenses/gpl-3.0.txt" target="_blank" rel="noopener noreferrer">',
					'/a'     => '</a>',
				)
			),
			'warranty_title'    => esc_html__( 'Warranty Disclaimer', 'agenistrator' ),
			'credits_title'     => esc_html__( 'Credits', 'agenistrator' ),
			'developed_by'      => String_Utils::replace_tags(
				/* translators: {a-href} and {/a} are HTML link tags wrapping the developer name */
				esc_html__( 'Developed by {a-href}Maximum.Software{/a}', 'agenistrator' ),
				array(
					'a-href' => '<a href="https://maximum.software/" target="_blank" rel="noopener noreferrer">',
					'/a'     => '</a>',
				)
			),
			'credits_desc'      => esc_html__( 'Agenistrator is built with open source libraries and tools. We thank all contributors to the projects that make this plugin possible.', 'agenistrator' ),
		);

		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Template system outputs pre-escaped HTML; all $attributes values are escaped above
		echo String_Utils::render( 'about', $attributes );
	}

	/**
	 * Render the error reports card
	 *
	 * @return string Rendered HTML for the reports card
	 */
	private function render_reports_card() {
		$reporter = Reporter::get_instance();
		$reports  = $reporter->list_reports();

		// Hide card when no reports exist
		if ( empty( $reports ) ) {
			return '';
		}

		// Render report rows
		$report_rows = '';
		foreach ( $reports as $report ) {
			$download_url = $reporter->get_report_url( $report['report_id'] );
			$report_rows .= String_Utils::render(
				'report-list-item',
				array(
					'report_id'       => esc_attr( $report['report_id'] ),
					'size'            => esc_html( size_format( $report['size'] ) ),
					'created'         => esc_html( wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $report['created'] ) ),
					'download_url'    => esc_url( $download_url ),
					'download_button' => esc_html__( 'Download', 'agenistrator' ),
					'delete_button'   => esc_html__( 'Delete', 'agenistrator' ),
				)
			);
		}

		return String_Utils::render(
			'report-card',
			array(
				'reports_title'       => esc_html__( 'Error Reports', 'agenistrator' ),
				'reports_description' => esc_html__( 'Reports generated from the chat widget for debugging.', 'agenistrator' ),
				'report_id_header'    => esc_html__( 'Report ID', 'agenistrator' ),
				'size_header'         => esc_html__( 'Size', 'agenistrator' ),
				'created_header'      => esc_html__( 'Created', 'agenistrator' ),
				'actions_header'      => esc_html__( 'Actions', 'agenistrator' ),
				'report_rows'         => $report_rows,
				'delete_all_button'   => esc_html__( 'Delete All', 'agenistrator' ),
			)
		);
	}

	/**
	 * AJAX handler for deleting a report
	 * @since     1.0.0
	 */
	public function ajax_delete_report() {
		// Verify nonce
		check_ajax_referer( 'agenistrator_nonce', 'nonce' );

		try {
			// Check permissions
			if ( ! current_user_can( 'manage_options' ) ) {
				throw new Ajax_Exception( __( 'You do not have permission to perform this action.', 'agenistrator' ), 403 );
			}

			$report_id = isset( $_POST['report_id'] ) ? sanitize_key( wp_unslash( $_POST['report_id'] ) ) : '';
			if ( empty( $report_id ) ) {
				throw new Ajax_Exception( __( 'Invalid report ID', 'agenistrator' ), 400 );
			}

			Reporter::get_instance()->delete_report( $report_id );
			wp_send_json_success();
		} catch ( \Throwable $e ) {
			WordPress_Utils::send_json_exception( $e );
		}
	}

	/**
	 * AJAX handler for deleting all reports
	 * @since     1.0.0
	 */
	public function ajax_delete_all_reports() {
		// Verify nonce
		check_ajax_referer( 'agenistrator_nonce', 'nonce' );

		try {
			// Check permissions
			if ( ! current_user_can( 'manage_options' ) ) {
				throw new Ajax_Exception( __( 'You do not have permission to perform this action.', 'agenistrator' ), 403 );
			}

			Reporter::get_instance()->delete_all_reports();
			wp_send_json_success();
		} catch ( \Throwable $e ) {
			WordPress_Utils::send_json_exception( $e );
		}
	}

	/**
	 * Render progress bars for all running operations of a given type.
	 *
	 * @param string $operation The operation identifier (e.g., 'embeddings').
	 * @return string Rendered HTML for all progress bars, or empty string if none running.
	 * @since     1.0.0
	 */
	public function render_progress_bars( $operation ) {
		$trackers = Progress_Tracker::get_running( $operation );

		if ( empty( $trackers ) ) {
			return '';
		}

		$labels = array(
			'embeddings'         => array(
				'title'        => __( 'Syncing Embeddings...', 'agenistrator' ),
				'count_format' => __( '{current} of {total} posts processed', 'agenistrator' ),
			),
			'embeddings_cleanup' => array(
				'title'        => __( 'Cleaning up orphan embeddings...', 'agenistrator' ),
				'count_format' => __( '{current} of {total} vectors checked', 'agenistrator' ),
			),
		);

		$default_labels = array(
			'title'        => __( 'Processing...', 'agenistrator' ),
			'count_format' => __( '{current} of {total} items processed', 'agenistrator' ),
		);

		$output = '';
		foreach ( $trackers as $tracker ) {
			$op              = $tracker->get_operation();
			$progress_labels = isset( $labels[ $op ] ) ? $labels[ $op ] : $default_labels;
			$progress_text   = String_Utils::replace_tags(
				$progress_labels['count_format'],
				array(
					'current' => $tracker->get_current(),
					'total'   => $tracker->get_total(),
				)
			);

			$output .= String_Utils::render(
				'progress-bar',
				array(
					'instance_id'      => esc_attr( $tracker->get_instance_id() ),
					'progress_title'   => esc_html( $progress_labels['title'] ),
					'progress_percent' => esc_attr( $tracker->get_percent_complete() ),
					'progress_text'    => esc_html( $progress_text ),
					'cancel_button'    => esc_html__( 'Cancel', 'agenistrator' ),
				)
			);
		}

		return $output;
	}
}
