<?php
/**
 * Admin Dashboard
 *
 * Registers all admin pages, enqueues assets,
 * and handles AJAX/POST actions from the UI.
 *
 * Pages:
 *  - guardian-shield         → Overview / Security Score
 *  - guardian-shield-logs    → Attack & Login Logs
 *  - guardian-shield-scanner → Malware Scanner
 *  - guardian-shield-monitor → File Integrity
 *  - guardian-shield-firewall→ Firewall / IP Rules
 *  - guardian-shield-settings→ Settings
 *
 * @package GuardianShield\Admin
 */

namespace GuardianShield\Admin;

use GuardianShield\Plugin;

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

class Dashboard {

	private Plugin $plugin;

	public function __construct( Plugin $plugin ) {
		$this->plugin = $plugin;

		add_action( 'admin_menu',            [ $this, 'register_pages' ] );
		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );

		// AJAX handlers.
		add_action( 'wp_ajax_gs_run_scan',           [ $this, 'ajax_run_scan' ] );
		add_action( 'wp_ajax_gs_build_baseline',     [ $this, 'ajax_build_baseline' ] );
		add_action( 'wp_ajax_gs_manage_ip',          [ $this, 'ajax_manage_ip' ] );
		add_action( 'wp_ajax_gs_save_settings',      [ $this, 'ajax_save_settings' ] );
		add_action( 'wp_ajax_gs_clear_logs',         [ $this, 'ajax_clear_logs' ] );
		add_action( 'wp_ajax_gs_clear_lockout',      [ $this, 'ajax_clear_lockout' ] );
		add_action( 'wp_ajax_gs_get_dashboard_stats',[ $this, 'ajax_dashboard_stats' ] );
	}

	// ── Menu Registration ────────────────────────
	public function register_pages(): void {
		$capability = 'manage_options';

		add_menu_page(
			esc_html__( 'Guardian Shield', 'guardian-shield' ),
			esc_html__( 'Guardian Shield', 'guardian-shield' ),
			$capability,
			'guardian-shield',
			[ $this, 'page_overview' ],
			'dashicons-shield',
			80
		);

		$subpages = [
			[ 'guardian-shield',           esc_html__( 'Overview',       'guardian-shield' ), [ $this, 'page_overview' ] ],
			[ 'guardian-shield-firewall',  esc_html__( 'Firewall',       'guardian-shield' ), [ $this, 'page_firewall' ] ],
			[ 'guardian-shield-logs',      esc_html__( 'Attack Logs',    'guardian-shield' ), [ $this, 'page_logs' ] ],
			[ 'guardian-shield-scanner',   esc_html__( 'Malware Scanner','guardian-shield' ), [ $this, 'page_scanner' ] ],
			[ 'guardian-shield-monitor',   esc_html__( 'File Monitor',   'guardian-shield' ), [ $this, 'page_monitor' ] ],
			[ 'guardian-shield-settings',  esc_html__( 'Settings',       'guardian-shield' ), [ $this, 'page_settings' ] ],
		];

		foreach ( $subpages as [ $slug, $label, $callback ] ) {
			add_submenu_page( 'guardian-shield', $label, $label, $capability, $slug, $callback );
		}
	}

	// ── Asset Enqueuing ──────────────────────────
	public function enqueue_assets( string $hook ): void {
		if ( ! str_contains( $hook, 'guardian-shield' ) ) {
			return;
		}

		wp_enqueue_style(
			'gs-admin',
			GS_PLUGIN_URL . 'admin/css/admin.css',
			[],
			GS_VERSION
		);

		wp_enqueue_script(
			'gs-admin',
			GS_PLUGIN_URL . 'admin/js/admin.js',
			[ 'jquery', 'wp-util' ],
			GS_VERSION,
			true
		);

		wp_localize_script( 'gs-admin', 'gs_admin', [
			'ajax_url' => admin_url( 'admin-ajax.php' ),
			'nonce'    => wp_create_nonce( 'gs_admin_action' ),
			'strings'  => [
				'confirm_scan'      => esc_html__( 'Start malware scan? This may take a few minutes.', 'guardian-shield' ),
				'confirm_baseline'  => esc_html__( 'Rebuild the file integrity baseline? This will overwrite current hashes.', 'guardian-shield' ),
				'confirm_clear'     => esc_html__( 'Clear all logs? This cannot be undone.', 'guardian-shield' ),
				'scanning'          => esc_html__( 'Scanning…', 'guardian-shield' ),
				'done'              => esc_html__( 'Done!', 'guardian-shield' ),
			],
		] );

		// Chart.js for dashboard graphs.
		wp_enqueue_script(
			'chartjs',
			'https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js',
			[],
			'4.4.0',
			true
		);
	}

	// ── Page: Overview ───────────────────────────
	public function page_overview(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Unauthorized.', 'guardian-shield' ) );
		}

		$score      = gs_calculate_security_score();
		$deductions = get_transient( 'gs_score_deductions' ) ?: [];
		$stats      = $this->plugin->logger->get_total_stats();
		$attacks    = $this->plugin->logger->get_attack_count_by_type( 7 );

		include GS_ADMIN_DIR . 'views/overview.php';
	}

	// ── Page: Firewall ───────────────────────────
	public function page_firewall(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Unauthorized.', 'guardian-shield' ) );
		}

		global $wpdb;
		$ip_rules = $wpdb->get_results(
			"SELECT * FROM `{$wpdb->prefix}gs_ip_rules` ORDER BY created_at DESC LIMIT 100",
			ARRAY_A
		);
		$fw_events = $wpdb->get_results(
			"SELECT * FROM `{$wpdb->prefix}gs_firewall_events` ORDER BY created_at DESC LIMIT 50",
			ARRAY_A
		);

		include GS_ADMIN_DIR . 'views/firewall.php';
	}

	// ── Page: Logs ───────────────────────────────
	public function page_logs(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Unauthorized.', 'guardian-shield' ) );
		}

		$tab     = sanitize_key( $_GET['tab'] ?? 'attacks' );
		$attacks = $this->plugin->logger->get_recent_attacks( 100 );
		$logins  = $this->plugin->logger->get_login_attempts( 100 );

		include GS_ADMIN_DIR . 'views/logs.php';
	}

	// ── Page: Scanner ────────────────────────────
	public function page_scanner(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Unauthorized.', 'guardian-shield' ) );
		}

		global $wpdb;
		$scan_results = $wpdb->get_results(
			"SELECT * FROM `{$wpdb->prefix}gs_scan_results` ORDER BY scan_at DESC LIMIT 100",
			ARRAY_A
		);

		include GS_ADMIN_DIR . 'views/scanner.php';
	}

	// ── Page: Monitor ────────────────────────────
	public function page_monitor(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Unauthorized.', 'guardian-shield' ) );
		}

		global $wpdb;
		$changes = $wpdb->get_results(
			"SELECT * FROM `{$wpdb->prefix}gs_file_hashes`
			  WHERE status != 'clean'
			  ORDER BY last_checked DESC
			  LIMIT 100",
			ARRAY_A
		);

		$last_check = get_option( 'gs_last_integrity_check', 'Never' );

		include GS_ADMIN_DIR . 'views/monitor.php';
	}

	// ── Page: Settings ───────────────────────────
	public function page_settings(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Unauthorized.', 'guardian-shield' ) );
		}

		include GS_ADMIN_DIR . 'views/settings.php';
	}

	// ── AJAX: Run Scan ───────────────────────────
	public function ajax_run_scan(): void {
		check_ajax_referer( 'gs_admin_action', 'nonce' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( 'Unauthorized', 403 );
		}

		$threats = $this->plugin->scanner->scan_uploads();

		wp_send_json_success( [
			'message' => sprintf( esc_html__( 'Scan complete. %d threat(s) found.', 'guardian-shield' ), count( $threats ) ),
			'count'   => count( $threats ),
			'threats' => $threats,
		] );
	}

	// ── AJAX: Build Baseline ─────────────────────
	public function ajax_build_baseline(): void {
		check_ajax_referer( 'gs_admin_action', 'nonce' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( 'Unauthorized', 403 );
		}

		$count = $this->plugin->file_monitor->build_baseline_for_directory( ABSPATH, 'core', true );

		wp_send_json_success( [
			'message' => sprintf( esc_html__( 'Baseline built for %d files.', 'guardian-shield' ), $count ),
		] );
	}

	// ── AJAX: Manage IP ──────────────────────────
	public function ajax_manage_ip(): void {
		check_ajax_referer( 'gs_admin_action', 'nonce' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( 'Unauthorized', 403 );
		}

		$action    = sanitize_text_field( $_POST['ip_action'] ?? '' );
		$ip        = sanitize_text_field( $_POST['ip'] ?? '' );
		$reason    = sanitize_text_field( $_POST['reason'] ?? '' );
		$rule_type = sanitize_key( $_POST['rule_type'] ?? 'blacklist' );
		$rule_id   = absint( $_POST['rule_id'] ?? 0 );
		$user_id   = get_current_user_id();

		switch ( $action ) {
			case 'add':
				if ( ! filter_var( $ip, FILTER_VALIDATE_IP ) ) {
					wp_send_json_error( esc_html__( 'Invalid IP address.', 'guardian-shield' ) );
				}
				if ( $rule_type === 'whitelist' ) {
					$this->plugin->firewall->whitelist_ip( $ip, $reason, $user_id );
				} else {
					$this->plugin->firewall->blacklist_ip( $ip, $reason, $user_id );
				}
				wp_send_json_success( [ 'message' => sprintf( esc_html__( 'IP %s added as %s.', 'guardian-shield' ), $ip, $rule_type ) ] );
				break;

			case 'remove':
				global $wpdb;
				if ( $rule_id > 0 ) {
					$wpdb->delete( $wpdb->prefix . 'gs_ip_rules', [ 'id' => $rule_id ], [ '%d' ] );
				} elseif ( filter_var( $ip, FILTER_VALIDATE_IP ) ) {
					$wpdb->delete( $wpdb->prefix . 'gs_ip_rules', [ 'ip_address' => $ip ], [ '%s' ] );
				} else {
					wp_send_json_error( esc_html__( 'No valid ID or IP to remove.', 'guardian-shield' ) );
				}
				wp_send_json_success( [ 'message' => esc_html__( 'IP rule removed.', 'guardian-shield' ) ] );
				break;

			default:
				wp_send_json_error( esc_html__( 'Unknown action.', 'guardian-shield' ) );
		}
	}

	// ── AJAX: Save Settings ──────────────────────
	public function ajax_save_settings(): void {
		check_ajax_referer( 'gs_admin_action', 'nonce' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( 'Unauthorized', 403 );
		}

		// Define allowed settings keys and their sanitise callbacks.
		$allowed = [
			'gs_firewall_enabled'     => 'boolval',
			'gs_block_sqli'           => 'boolval',
			'gs_block_xss'            => 'boolval',
			'gs_block_bad_bots'       => 'boolval',
			'gs_block_xmlrpc'         => 'boolval',
			'gs_rate_limit_enabled'   => 'boolval',
			'gs_rate_limit_requests'  => 'absint',
			'gs_rate_limit_window'    => 'absint',
			'gs_max_login_attempts'   => 'absint',
			'gs_lockout_duration'     => 'absint',
			'gs_hide_login_url'       => 'boolval',
			'gs_custom_login_slug'    => 'sanitize_title',
			'gs_headers_enabled'      => 'boolval',
			'gs_hsts_enabled'         => 'boolval',
			'gs_csp_enabled'          => 'boolval',
			'gs_file_monitor_enabled' => 'boolval',
			'gs_monitor_core'         => 'boolval',
			'gs_monitor_plugins'      => 'boolval',
			'gs_monitor_themes'       => 'boolval',
			'gs_scan_enabled'         => 'boolval',
			'gs_quarantine_enabled'   => 'boolval',
			'gs_email_alerts'         => 'boolval',
			'gs_alert_email'          => 'sanitize_email',
			'gs_alert_on_bruteforce'  => 'boolval',
			'gs_alert_on_malware'     => 'boolval',
			'gs_alert_on_file_change' => 'boolval',
			'gs_alert_on_username_rename' => 'boolval',
			'gs_rename_admin_user'    => 'boolval',
			'gs_cloudflare_mode'      => 'boolval',
			'gs_log_retention_days'   => 'absint',
		];

		$post_data = $_POST;

		foreach ( $allowed as $key => $sanitizer ) {
			if ( array_key_exists( $key, $post_data ) ) {
				$raw   = wp_unslash( $post_data[ $key ] );
				$value = $sanitizer( $raw );
				update_option( $key, $value, false );
			} elseif ( in_array( $sanitizer, [ 'boolval' ], true ) ) {
				// Unchecked checkboxes are not submitted — treat as false.
				update_option( $key, false, false );
			}
		}

		wp_send_json_success( [ 'message' => esc_html__( 'Settings saved.', 'guardian-shield' ) ] );
	}

	// ── AJAX: Clear Logs ─────────────────────────
	public function ajax_clear_logs(): void {
		check_ajax_referer( 'gs_admin_action', 'nonce' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( 'Unauthorized', 403 );
		}

		global $wpdb;
		$type = sanitize_key( $_POST['log_type'] ?? 'attacks' );

		$tables = [
			'attacks'  => $wpdb->prefix . 'gs_attack_logs',
			'logins'   => $wpdb->prefix . 'gs_login_attempts',
			'firewall' => $wpdb->prefix . 'gs_firewall_events',
			'scan'     => $wpdb->prefix . 'gs_scan_results',
		];

		if ( isset( $tables[ $type ] ) ) {
			$wpdb->query( "TRUNCATE TABLE `{$tables[$type]}`" ); // phpcs:ignore
			wp_send_json_success( [ 'message' => esc_html__( 'Logs cleared.', 'guardian-shield' ) ] );
		} else {
			wp_send_json_error( esc_html__( 'Unknown log type.', 'guardian-shield' ) );
		}
	}

	// ── AJAX: Clear IP Lockout ───────────────────
	public function ajax_clear_lockout(): void {
		check_ajax_referer( 'gs_admin_action', 'nonce' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( 'Unauthorized', 403 );
		}

		$ip = sanitize_text_field( $_POST['ip'] ?? '' );
		if ( filter_var( $ip, FILTER_VALIDATE_IP ) ) {
			$this->plugin->login_security->clear_lockout( $ip );
			wp_send_json_success( [ 'message' => sprintf( esc_html__( 'Lockout cleared for %s.', 'guardian-shield' ), $ip ) ] );
		} else {
			wp_send_json_error( esc_html__( 'Invalid IP.', 'guardian-shield' ) );
		}
	}

	// ── AJAX: Live Dashboard Stats ───────────────
	public function ajax_dashboard_stats(): void {
		check_ajax_referer( 'gs_admin_action', 'nonce' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( 'Unauthorized', 403 );
		}

		wp_send_json_success( $this->plugin->logger->get_total_stats() );
	}
}
