<?php

defined( 'ABSPATH' ) || exit;

class ZACLS_Main {

	private $twofa;
	private $limiter;
	private $blocker;
	private $login_url;
	private $notifier;
	private $admin;
	private $session;
	private $device;
	private $password_policy;
	private $emergency;
	private $notifications;
	private $branding;
	private $webauthn;
	private $rest_api;

	public function __construct() {
		$this->init_components();
		$this->register_hooks();
		ZACLS_Privacy::init();
	}

	private function init_components() {
		$this->twofa           = new ZACLS_TwoFA();
		$this->limiter         = new ZACLS_Login_Limiter();
		$this->blocker         = new ZACLS_IP_Blocker();
		$this->login_url       = new ZACLS_Login_URL();
		$this->notifier        = new ZACLS_Email_Notifications();
		$this->session         = new ZACLS_Session();
		$this->device          = new ZACLS_Device();
		$this->password_policy = new ZACLS_Password_Policy();
		$this->emergency       = new ZACLS_Emergency();
		$this->notifications   = new ZACLS_Notifications();
		$this->branding        = new ZACLS_Branding();
		$this->webauthn        = new ZACLS_WebAuthn();
		$this->rest_api        = new ZACLS_REST_API();
		$this->admin           = new ZACLS_Admin();
	}

	private function register_hooks() {
		add_filter( 'plugin_action_links_' . plugin_basename( ZACLS_PLUGIN_FILE ), array( $this, 'add_action_links' ) );
		add_action( 'zacls_daily_cleanup', array( $this, 'cleanup_expired_data' ) );
		add_action( 'admin_init', array( $this, 'redirect_onboarding' ) );
		add_filter( 'cron_schedules', array( $this, 'add_cron_schedules' ) );
		add_action( 'zacls_daily_report', array( $this, 'send_scheduled_report' ) );
		add_action( 'zacls_weekly_report', array( $this, 'send_scheduled_report' ) );
		add_action( 'zacls_monthly_report', array( $this, 'send_scheduled_report' ) );
		add_action( 'wp_dashboard_setup', array( $this, 'register_dashboard_widgets' ) );
		add_action( 'zacls_successful_login', array( $this, 'record_successful_login' ), 10, 2 );
		add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_menu' ), 100 );
	}

	public function add_action_links( $links ) {
		$settings_link = sprintf(
			'<a href="%s">%s</a>',
			esc_url( admin_url( 'admin.php?page=zacls' ) ),
			esc_html__( 'Dashboard', 'za-creative-login-shield' )
		);
		array_unshift( $links, $settings_link );

		$links[] = sprintf(
			'<a href="%s" style="color:#00a32a;font-weight:600;">%s</a>',
			esc_url( admin_url( 'admin.php?page=zacls&tab=wizard' ) ),
			esc_html__( 'Security Wizard', 'za-creative-login-shield' )
		);

		return $links;
	}

	public function add_cron_schedules( $schedules ) {
		$schedules['weekly']  = array(
			'interval' => WEEK_IN_SECONDS,
			'display'  => esc_html__( 'Once Weekly', 'za-creative-login-shield' ),
		);
		$schedules['monthly'] = array(
			'interval' => MONTH_IN_SECONDS,
			'display'  => esc_html__( 'Once Monthly', 'za-creative-login-shield' ),
		);
		return $schedules;
	}

	public function cleanup_expired_data() {
		global $wpdb;

		$now = current_time( 'mysql' );

		$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}zacls_2fa_codes WHERE expires_at < %s", $now ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}zacls_blocked_ips WHERE expires_at IS NOT NULL AND expires_at < %s", $now ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}zacls_login_attempts WHERE attempt_time < %s - INTERVAL 60 DAY", $now ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}zacls_risk_scores WHERE created_at < %s - INTERVAL 30 DAY", $now ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}zacls_webauthn_challenges WHERE expires_at < %s", $now ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching

		ZACLS_Session::cleanup_expired();
		ZACLS_Device::cleanup_old_devices();

		$wpdb->query( "OPTIMIZE TABLE {$wpdb->prefix}zacls_login_attempts" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->query( "OPTIMIZE TABLE {$wpdb->prefix}zacls_audit_log" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
	}

	public function redirect_onboarding() {
		if ( ! get_transient( 'zacls_onboarding_redirect' ) ) {
			return;
		}
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
		if ( 'zacls' === $page ) {
			return;
		}

		$screen = get_current_screen();
		if ( $screen && 'plugins' === $screen->id ) {
			delete_transient( 'zacls_onboarding_redirect' );
			$wizard_url = admin_url( 'admin.php?page=zacls&tab=wizard&onboarding=1' );
			wp_safe_redirect( esc_url_raw( $wizard_url ) );
			exit;
		}
	}

	public static function get_ip() {
		$remote_addr = '';
		if ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
			$remote_addr = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );
		}
		if ( ! filter_var( $remote_addr, FILTER_VALIDATE_IP ) ) {
			return '127.0.0.1';
		}

		$trusted_proxies = self::get_trusted_proxies();

		// Forwarded headers are only honored when the direct peer is trusted.
		if ( ! self::ip_in_trusted_list( $remote_addr, $trusted_proxies ) ) {
			return $remote_addr;
		}

		$cloudflare_enabled = 'yes' === get_option( 'zacls_cloudflare_enabled', 'no' );
		if ( $cloudflare_enabled && isset( $_SERVER['HTTP_CF_CONNECTING_IP'] ) ) {
			$cf_ip = sanitize_text_field( wp_unslash( $_SERVER['HTTP_CF_CONNECTING_IP'] ) );
			if ( filter_var( $cf_ip, FILTER_VALIDATE_IP ) && self::ip_in_trusted_list( $remote_addr, self::cloudflare_prefixes() ) ) {
				return $cf_ip;
			}
		}

		if ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
			$candidates = array_map( 'trim', explode( ',', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) );
			$candidates = array_reverse( $candidates );
			foreach ( $candidates as $candidate ) {
				if ( ! filter_var( $candidate, FILTER_VALIDATE_IP ) ) {
					continue;
				}
				if ( self::ip_in_trusted_list( $candidate, $trusted_proxies ) ) {
					continue;
				}
				return $candidate;
			}
		}

		if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) {
			$real_ip = sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_REAL_IP'] ) );
			if ( filter_var( $real_ip, FILTER_VALIDATE_IP ) ) {
				return $real_ip;
			}
		}

		return $remote_addr;
	}

	/**
	 * List of trusted proxy addresses/CIDRs for forwarded-header processing.
	 *
	 * @return string[]
	 */
	private static function get_trusted_proxies() {
		$proxies = (array) get_option( 'zacls_trusted_proxy_ips', array() );
		if ( 'yes' === get_option( 'zacls_cloudflare_enabled', 'no' ) ) {
			$proxies = array_merge( $proxies, self::cloudflare_prefixes() );
		}
		$proxies = array_values( array_unique( array_filter( array_map( 'trim', $proxies ) ) ) );
		return $proxies;
	}

	/**
	 * Well-known Cloudflare edge prefixes (curated).
	 *
	 * @return string[]
	 */
	private static function cloudflare_prefixes() {
		return array(
			'173.245.48.0/20',
			'103.21.244.0/22',
			'103.22.200.0/22',
			'103.31.4.0/22',
			'141.101.64.0/18',
			'108.162.192.0/18',
			'190.93.240.0/20',
			'188.114.96.0/20',
			'197.234.240.0/22',
			'198.41.128.0/17',
			'162.158.0.0/15',
			'104.16.0.0/13',
			'104.24.0.0/14',
			'172.64.0.0/13',
			'131.0.72.0/22',
			'2400:cb00::/32',
			'2606:4700::/32',
			'2803:f800::/32',
			'2405:b500::/32',
			'2405:8100::/32',
			'2a06:98c0::/29',
			'2c0f:f248::/32',
		);
	}

	/**
	 * Whether an IP is covered by a list of exact addresses and CIDR ranges.
	 *
	 * @param string   $ip   IP address.
	 * @param string[] $list Trusted entries.
	 * @return bool
	 */
	private static function ip_in_trusted_list( $ip, $list ) {
		foreach ( (array) $list as $entry ) {
			if ( is_string( $entry ) && false !== strpos( $entry, '/' ) ) {
				$parts = explode( '/', $entry, 2 );
				if ( self::ip_in_cidr( $ip, $parts[0], (int) $parts[1] ) ) {
					return true;
				}
			} elseif ( is_string( $entry ) && $ip === $entry ) {
				return true;
			}
		}
		return false;
	}

	/**
	 * CIDR range match for IPv4 and IPv6.
	 *
	 * @param string $ip      IP address.
	 * @param string $subnet  Subnet address.
	 * @param int    $mask    Prefix length.
	 * @return bool
	 */
	private static function ip_in_cidr( $ip, $subnet, $mask ) {
		if ( ! filter_var( $ip, FILTER_VALIDATE_IP ) || ! filter_var( $subnet, FILTER_VALIDATE_IP ) ) {
			return false;
		}

		if ( false !== strpos( $ip, ':' ) ) {
			if ( $mask < 0 || $mask > 128 ) {
				return false;
			}
			$ip_bin     = inet_pton( $ip );
			$subnet_bin = inet_pton( $subnet );
			if ( false === $ip_bin || false === $subnet_bin || strlen( $ip_bin ) !== strlen( $subnet_bin ) ) {
				return false;
			}
			$full_bytes = intdiv( $mask, 8 );
			for ( $i = 0; $i < $full_bytes; $i++ ) {
				if ( $ip_bin[ $i ] !== $subnet_bin[ $i ] ) {
					return false;
				}
			}
			$remaining = $mask % 8;
			if ( $remaining > 0 ) {
				$mask_byte = chr( 0xFF << ( 8 - $remaining ) );
				if ( ( $ip_bin[ $full_bytes ] & $mask_byte ) !== ( $subnet_bin[ $full_bytes ] & $mask_byte ) ) {
					return false;
				}
			}
			return true;
		}

		if ( $mask < 0 || $mask > 32 ) {
			return false;
		}
		$ip_bin     = ip2long( $ip );
		$subnet_bin = ip2long( $subnet );
		if ( false === $ip_bin || false === $subnet_bin ) {
			return false;
		}
		if ( 0 === $mask ) {
			return true;
		}
		$shift = 32 - $mask;
		return ( $ip_bin >> $shift ) === ( $subnet_bin >> $shift );
	}

	public static function lookup_country( $ip ) {
		if ( ! filter_var( $ip, FILTER_VALIDATE_IP ) || '127.0.0.1' === $ip ) {
			return '';
		}

		if ( 'yes' !== get_option( 'zacls_geoip_enabled', 'no' ) ) {
			return '';
		}

		$cache_key = 'zacls_country_' . hash( 'sha256', $ip );
		$cached    = get_transient( $cache_key );
		if ( false !== $cached ) {
			return $cached;
		}

		$retry_key = 'zacls_geoip_retry_' . hash( 'sha256', $ip );
		if ( get_transient( $retry_key ) ) {
			return '';
		}

		$response = wp_remote_get(
			"https://ip-api.com/json/{$ip}?fields=countryCode",
			array(
				'timeout'    => 5,
				'user-agent' => 'ZA Creative Login Shield/' . ZACLS_VERSION,
			)
		);

		if ( is_wp_error( $response ) ) {
			set_transient( $retry_key, '1', HOUR_IN_SECONDS );
			return '';
		}

		$code = wp_remote_retrieve_response_code( $response );
		if ( 200 !== $code ) {
			set_transient( $retry_key, '1', HOUR_IN_SECONDS );
			return '';
		}

		$body = json_decode( wp_remote_retrieve_body( $response ), true );
		if ( ! is_array( $body ) || empty( $body['countryCode'] ) ) {
			return '';
		}

		$code = strtoupper( sanitize_text_field( $body['countryCode'] ) );
		if ( strlen( $code ) > 5 ) {
			return '';
		}

		set_transient( $cache_key, $code, DAY_IN_SECONDS * 7 );
		return $code;
	}

	public function record_successful_login( $user ) {
		global $wpdb;

		ZACLS_Login_Limiter::ensure_table_exists();

		$ip      = self::get_ip();
		$country = self::lookup_country( $ip );

		$data = array(
			'ip'           => $ip,
			'username'     => $user->user_login,
			'user_id'      => $user->ID,
			'status'       => 'success',
			'user_agent'   => isset( $_SERVER['HTTP_USER_AGENT'] )
				? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) )
				: '',
			'attempt_time' => current_time( 'mysql' ),
		);
		$format = array( '%s', '%s', '%d', '%s', '%s', '%s' );

		if ( self::column_exists_in_attempts( 'country_code' ) ) {
			$data['country_code'] = $country;
			$format[] = '%s';
		}
		if ( self::column_exists_in_attempts( 'device_id' ) ) {
			$data['device_id'] = substr( ZACLS_Device::get_device_id(), 0, 64 );
			$format[] = '%s';
		}
		if ( self::column_exists_in_attempts( 'session_id' ) ) {
			$data['session_id'] = substr( ZACLS_Session::get_session_id_from_cookie(), 0, 64 );
			$format[] = '%s';
		}

		$result = $wpdb->insert( $wpdb->prefix . 'zacls_login_attempts', $data, $format ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching

		if ( false === $result ) {
			error_log( '[ZACLS] record_successful_login insert failed: ' . $wpdb->last_error );
		}
	}

	private static function column_exists_in_attempts( $column ) {
		global $wpdb;
		$exists = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
			$wpdb->prepare( "SHOW COLUMNS FROM {$wpdb->prefix}zacls_login_attempts LIKE %s", $column )
		);
		return (bool) $exists;
	}

	public function send_scheduled_report() {
		$frequency = get_option( 'zacls_report_frequency', 'none' );
		if ( 'none' === $frequency ) {
			return;
		}

		$hook = current_action();

		if ( 'zacls_daily_report' === $hook && 'daily' !== $frequency ) return;
		if ( 'zacls_weekly_report' === $hook && 'weekly' !== $frequency ) return;
		if ( 'zacls_monthly_report' === $hook && 'monthly' !== $frequency ) return;

		$interval_days  = 'zacls_daily_report' === $hook ? 1 : ( 'zacls_weekly_report' === $hook ? 7 : 30 );
		$interval_label = 'zacls_daily_report' === $hook ? __( 'Daily', 'za-creative-login-shield' )
			: ( 'zacls_weekly_report' === $hook ? __( 'Weekly', 'za-creative-login-shield' ) : __( 'Monthly', 'za-creative-login-shield' ) );

		$stats = ZACLS_Analytics::get_summary_stats( $interval_days );
		$health = ZACLS_Health::calculate_score();

		$to      = get_option( 'zacls_admin_email', get_option( 'admin_email' ) );
		$blogname = get_option( 'blogname' );
		$subject = sprintf( esc_html__( '[%1$s] Security Report - %2$s', 'za-creative-login-shield' ), esc_html( $interval_label ), esc_html( $blogname ) );

		$vars = array(
			'stats'          => $stats,
			'health_score'   => $health['score'],
			'health_grade'   => $health['grade'],
			'interval_label' => $interval_label,
			'site_name'      => $blogname,
		);

		$message = ZACLS_Email_Templates::get_template( 'security-report', $vars );

		$headers = array( 'Content-Type: text/html; charset=UTF-8' );
		wp_mail( $to, $subject, $message, $headers );

		update_option( 'zacls_last_report_sent', current_time( 'mysql' ) );
		ZACLS_Audit_Trail::log( 'report_sent', sprintf( esc_html__( 'Sent %1$s security report to %2$s', 'za-creative-login-shield' ), strtolower( $interval_label ), $to ) );
	}

	public function register_dashboard_widgets() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		wp_add_dashboard_widget(
			'zacls_security_score_widget',
			esc_html__( 'ZA Creative Security Score', 'za-creative-login-shield' ),
			array( $this, 'render_dashboard_score_widget' )
		);

		wp_add_dashboard_widget(
			'zacls_recent_activity_widget',
			esc_html__( 'ZA Creative Recent Activity', 'za-creative-login-shield' ),
			array( $this, 'render_dashboard_activity_widget' )
		);
	}

	public function render_dashboard_score_widget() {
		$score_data = ZACLS_Health::calculate_score();
		$score      = $score_data['score'];
		$grade      = $score_data['grade'];
		$stars      = $score >= 90 ? 5 : ( $score >= 75 ? 4 : ( $score >= 60 ? 3 : ( $score >= 40 ? 2 : 1 ) ) );
		$color      = $score >= 80 ? '#00a32a' : ( $score >= 50 ? '#dba617' : '#d63638' );
		$color_class = $score >= 80 ? 'score-high' : ( $score >= 50 ? 'score-medium' : 'score-low' );
		$stats      = ZACLS_Analytics::get_summary_stats( 1 );
		?>
		<div class="zacls-widget-score <?php echo esc_attr( $color_class ); ?>">
			<div class="zacls-widget-score-value" style="color:<?php echo esc_attr( $color ); ?>"><?php echo esc_html( $score ); ?><span style="font-size:14px">%</span></div>
			<div style="font-size:18px;letter-spacing:3px;color:<?php echo esc_attr( $color ); ?>;margin:2px 0 6px">
				<?php echo wp_kses( str_repeat( '&#9733;', $stars ) . str_repeat( '&#9734;', 5 - $stars ), array() ); ?>
			</div>
			<div class="zacls-widget-score-label"><?php echo esc_html( ucfirst( $grade ) ); ?></div>
			<hr style="margin:8px 0">
			<div style="display:flex;justify-content:space-around;font-size:12px">
				<div><strong style="color:#d63638"><?php echo esc_html( $stats['failed'] ); ?></strong> <?php esc_html_e( 'Failed', 'za-creative-login-shield' ); ?></div>
				<div><strong style="color:#2271b1"><?php echo esc_html( $stats['blocked'] ); ?></strong> <?php esc_html_e( 'Blocked', 'za-creative-login-shield' ); ?></div>
				<div><strong style="color:#00a32a"><?php echo esc_html( $stats['twofa_enabled'] ); ?></strong> <?php esc_html_e( '2FA', 'za-creative-login-shield' ); ?></div>
			</div>
			<hr style="margin:8px 0">
			<p style="margin:0"><a href="<?php echo esc_url( admin_url( 'admin.php?page=zacls' ) ); ?>"><?php esc_html_e( 'View Full Dashboard', 'za-creative-login-shield' ); ?></a></p>
		</div>
		<?php
	}

	public function render_dashboard_activity_widget() {
		global $wpdb;

		$failed_24h = ZACLS_Login_Limiter::get_total_attempts( 'failed', 1 );
		$success_24h = ZACLS_Login_Limiter::get_total_attempts( 'success', 1 );
		$blocked    = ZACLS_IP_Blocker::get_blocked_count();
		$total_24h  = $failed_24h + $success_24h;
		$recent     = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
			$wpdb->prepare(
				"SELECT ip, username, status, attempt_time FROM {$wpdb->prefix}zacls_login_attempts ORDER BY attempt_time DESC LIMIT %d",
				5
			),
			ARRAY_A
		);

		$briefing = ZACLS_AI_Assistant::get_briefing( 1 );
		$summary  = $briefing['summary'];
		?>
		<div style="white-space:pre-line;font-size:12px;line-height:1.5;padding:6px 0 8px;color:#50575e">
			<?php echo esc_html( wp_trim_words( $summary, 30, '...' ) ); ?>
		</div>
		<div style="display:flex;gap:8px;margin-bottom:8px">
			<span style="flex:1;text-align:center;padding:6px;background:#fcf0f1;border-radius:4px">
				<strong style="color:#d63638;font-size:16px;display:block"><?php echo esc_html( $failed_24h ); ?></strong>
				<small><?php esc_html_e( 'Failed', 'za-creative-login-shield' ); ?></small>
			</span>
			<span style="flex:1;text-align:center;padding:6px;background:#edfaef;border-radius:4px">
				<strong style="color:#00a32a;font-size:16px;display:block"><?php echo esc_html( $success_24h ); ?></strong>
				<small><?php esc_html_e( 'Success', 'za-creative-login-shield' ); ?></small>
			</span>
			<span style="flex:1;text-align:center;padding:6px;background:#e5f5fa;border-radius:4px">
				<strong style="color:#2271b1;font-size:16px;display:block"><?php echo esc_html( $blocked ); ?></strong>
				<small><?php esc_html_e( 'Blocked', 'za-creative-login-shield' ); ?></small>
			</span>
		</div>
		<?php if ( ! empty( $recent ) ) : ?>
			<ul style="margin:0;padding:0;list-style:none;">
				<?php foreach ( $recent as $entry ) : ?>
					<li style="padding:4px 0;border-bottom:1px solid #f0f0f1;font-size:12px;">
						<code><?php echo esc_html( $entry['ip'] ); ?></code>
						<?php echo esc_html( $entry['username'] ?: '-' ); ?>
						<span style="color:<?php echo esc_attr( 'failed' === $entry['status'] ? '#d63638' : '#00a32a' ); ?>;font-weight:600"><?php echo esc_html( $entry['status'] ); ?></span>
						<span style="color:#a7aaad;float:right;"><?php echo esc_html( $entry['attempt_time'] ); ?></span>
					</li>
				<?php endforeach; ?>
			</ul>
		<?php else : ?>
			<p class="description"><?php esc_html_e( 'No recent login activity.', 'za-creative-login-shield' ); ?></p>
		<?php endif; ?>
		<p><a href="<?php echo esc_url( admin_url( 'admin.php?page=zacls&tab=logs' ) ); ?>"><?php esc_html_e( 'View All Logs', 'za-creative-login-shield' ); ?></a></p>
		<?php
	}

	public function add_admin_bar_menu( $wp_admin_bar ) {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		$health = ZACLS_Health::calculate_score();
		$notif_count = ZACLS_Notifications::count_unread();

		$wp_admin_bar->add_node( array(
			'id'    => 'zacls',
			'title' => '<span class="ab-icon dashicons-shield" style="font-family:dashicons;font-size:18px;line-height:1.3"></span> '
				. esc_html( $health['score'] ) . '%'
				. ( $notif_count > 0 ? ' <span class="ab-label" style="background:#d63638;color:#fff;border-radius:50%;padding:1px 6px;font-size:10px;margin-left:4px">' . $notif_count . '</span>' : '' ),
			'href'  => admin_url( 'admin.php?page=zacls' ),
		) );
	}
}
