<?php
/**
 * Mersal Notifications — Mersal Suite screens.
 *
 * Renders the new-design Notifications screens inside the shared Suite shell,
 * wired to the real Mersal_Notif_Core rules engine, stats and delivery log.
 *
 * @package Mersal_Notif
 */

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

/**
 * Notifications screens for the Suite.
 */
class Mersal_Notif_Suite_Pages {

	/** @var bool */
	private static $js_printed = false;

	/**
	 * Route => callback map.
	 *
	 * @return array
	 */
	public static function routes() {
		$self   = array( __CLASS__, 'dispatch' );
		$map    = array();
		$leaves = array(
			// Native new-design Suite screens.
			'dash', 'triggers', 'editor', 'segments', 'log',
			// Full standalone screens mirrored into the Suite.
			'rules', 'edit', 'events', 'sending', 'connect', 'logs', 'updates',
			'cart', 'widget', 'emails',
		);
		foreach ( $leaves as $r ) {
			$map[ 'nt.' . $r ] = $self;
		}
		return $map;
	}

	/**
	 * Map a Suite route leaf to the legacy standalone sub-page it embeds.
	 *
	 * @param string $leaf Suite leaf (after `nt.`).
	 * @return string|null Standalone sub-page id, or null for native screens.
	 */
	private static function embed_page_for( $leaf ) {
		$map = array(
			'rules'   => 'rules',
			'edit'    => 'edit',
			// Merged into the rule wizard: the event picker (with inline custom
			// events) and the message step (with the embedded email builder)
			// replaced the old separate Triggers / Events / Editor screens.
			'events'  => 'edit',
			'triggers'=> 'edit',
			'editor'  => 'edit',
			'sending' => 'sending',
			'connect' => 'mersal',
			'logs'    => 'logs',
			'updates' => 'updates',
			'cart'    => 'cart',
			'widget'  => 'widget',
			'emails'  => 'emails',
		);
		return isset( $map[ $leaf ] ) ? $map[ $leaf ] : null;
	}

	/**
	 * Shared Mersal_Notif_Admin instance to embed the full standalone pages.
	 *
	 * @return Mersal_Notif_Admin
	 */
	private static function admin() {
		static $admin = null;
		if ( null === $admin ) {
			$connect = new Mersal_Notif_Connect();
			$core    = new Mersal_Notif_Core( $connect );
			$admin   = new Mersal_Notif_Admin( $core, $connect );
		}
		return $admin;
	}

	/**
	 * Hook filters + AJAX.
	 */
	public static function init() {
		add_filter( 'mersal_suite_hub_stats', array( __CLASS__, 'hub_stats' ) );
		add_filter( 'mersal_suite_hub_activity', array( __CLASS__, 'hub_activity' ) );
		add_filter( 'mersal_suite_plugin_stat', array( __CLASS__, 'plugin_stat' ), 10, 2 );
		add_action( 'wp_ajax_mnotif_suite_trigger', array( __CLASS__, 'ajax_trigger' ) );
	}

	/** @return Mersal_Notif_Core */
	private static function core() {
		return new Mersal_Notif_Core();
	}

	/**
	 * Order-status display meta (icon + solid colour + default message).
	 *
	 * @param bool $ar Arabic.
	 * @return array slug => [icon, color, default_msg]
	 */
	private static function status_meta( $ar ) {
		return array(
			'pending'    => array( 'schedule', '#64748b', $ar ? 'مرحباً {{customer_name}}، استلمنا طلبك #{{order_id}} وفي انتظار إتمام الدفع.' : 'Hi {{customer_name}}, we received order #{{order_id}} and await payment.' ),
			'processing' => array( 'autorenew', '#2f86c9', $ar ? 'طلبك #{{order_id}} قيد التجهيز الآن 🎉 هنبلّغك أول ما يتشحن.' : 'Order #{{order_id}} is being prepared 🎉' ),
			'on-hold'    => array( 'pause_circle', '#f0a93b', $ar ? 'طلبك #{{order_id}} مُعلّق مؤقتاً لحين تأكيد الدفع.' : 'Order #{{order_id}} is on hold pending payment.' ),
			'shipped'    => array( 'local_shipping', '#8b5cf6', $ar ? 'طلبك #{{order_id}} في الطريق إليك 🚚' : 'Order #{{order_id}} is on its way 🚚' ),
			'completed'  => array( 'check_circle', '#0f7a4a', $ar ? 'تم تسليم طلبك #{{order_id}} ✅ نتمنى لك تجربة سعيدة!' : 'Order #{{order_id}} delivered ✅' ),
			'refunded'   => array( 'undo', '#ea7c39', $ar ? 'تم استرجاع مبلغ طلبك #{{order_id}} وهيوصل حسابك خلال أيام.' : 'Your refund for order #{{order_id}} has been processed.' ),
			'failed'     => array( 'error', '#d8524a', $ar ? 'لم يكتمل دفع طلبك #{{order_id}}. حاول مرة أخرى لإتمامه.' : 'Payment for order #{{order_id}} failed. Please try again.' ),
			'cancelled'  => array( 'cancel', '#94a3b8', $ar ? 'تم إلغاء طلبك #{{order_id}}. لو ده حصل بالغلط تواصل معانا.' : 'Order #{{order_id}} was cancelled.' ),
		);
	}

	/**
	 * Default channels per WC status when no rule exists yet.
	 *
	 * @param string $slug Status slug.
	 * @return string[]
	 */
	private static function status_default_channels( $slug ) {
		$map = array(
			'pending'    => array( 'push', 'email' ),
			'processing' => array( 'email', 'whatsapp' ),
			'on-hold'    => array( 'email' ),
			'shipped'    => array( 'push', 'whatsapp' ),
			'completed'  => array( 'whatsapp', 'email' ),
		);
		return $map[ $slug ] ?? array( 'whatsapp', 'email' );
	}

	/**
	 * Find the rule that backs a WC order-status trigger.
	 *
	 * @param string $slug Status slug (no wc- prefix).
	 * @return array|null
	 */
	private static function status_rule( $slug ) {
		$key = 'wc_status_' . $slug;
		foreach ( self::core()->get_rules() as $r ) {
			if ( ( $r['trigger_key'] ?? '' ) === $key ) {
				return $r;
			}
		}
		return null;
	}

	/* ------------------------------------------------------------------ */
	/* Suite filters                                                      */
	/* ------------------------------------------------------------------ */

	/**
	 * Hub stats.
	 *
	 * @param array $stats Stats.
	 * @return array
	 */
	public static function hub_stats( $stats ) {
		$ar = 'ar' === Mersal_Suite::instance()->lang();
		$ov = self::core()->get_overview();
		$stats[] = array( 'label' => $ar ? 'إشعارات اليوم' : 'Notifications today', 'val' => number_format_i18n( $ov['today'] ), 'icon' => 'notifications_active', 'tone' => 'info' );
		$stats[] = array( 'label' => $ar ? 'مُحفزات نشطة' : 'Active triggers', 'val' => number_format_i18n( $ov['enabled'] ), 'icon' => 'bolt', 'tone' => 'accent' );
		return $stats;
	}

	/**
	 * Hub activity.
	 *
	 * @param array $activity Activity.
	 * @return array
	 */
	public static function hub_activity( $activity ) {
		$ar = 'ar' === Mersal_Suite::instance()->lang();
		foreach ( self::core()->get_log( 3 ) as $row ) {
			$ok = 'failed' !== ( $row['status'] ?? '' );
			$activity[] = array(
				'icon' => 'notifications_active',
				'tone' => $ok ? 'info' : 'danger',
				'txt'  => sprintf( $ar ? 'إشعار «%1$s» عبر %2$s إلى %3$s' : 'Notification "%1$s" via %2$s to %3$s', $row['rule'] ?? '', ucfirst( $row['channel'] ?? '' ), $row['to'] ?? '' ),
				'time' => isset( $row['time'] ) ? human_time_diff( $row['time'] ) . ( $ar ? '' : ' ago' ) : '',
			);
		}
		return $activity;
	}

	/**
	 * Plugin card stat.
	 *
	 * @param string $stat Stat.
	 * @param string $id   Plugin id.
	 * @return string
	 */
	public static function plugin_stat( $stat, $id ) {
		if ( 'nt' !== $id ) {
			return $stat;
		}
		$ar = 'ar' === Mersal_Suite::instance()->lang();
		$ov = self::core()->get_overview();
		return sprintf( $ar ? '%d مُحفز نشط' : '%d active triggers', $ov['enabled'] );
	}

	/* ------------------------------------------------------------------ */
	/* AJAX: trigger find-or-create + toggle + message                    */
	/* ------------------------------------------------------------------ */

	/**
	 * Save / toggle the rule behind a WC order-status trigger.
	 */
	public static function ajax_trigger() {
		check_ajax_referer( 'mnotif_rule', 'nonce' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'forbidden' ), 403 );
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- verified above.
		$slug = isset( $_POST['status'] ) ? sanitize_key( wp_unslash( $_POST['status'] ) ) : '';
		if ( '' === $slug ) {
			wp_send_json_error( array( 'message' => 'bad status' ), 400 );
		}
		$core = self::core();
		$ar   = 'ar' === Mersal_Suite::instance()->lang();
		$rule = self::status_rule( $slug );
		$meta = self::status_meta( $ar );
		$def  = isset( $meta[ $slug ] ) ? $meta[ $slug ][2] : '';

		$payload = array(
			'id'          => $rule ? $rule['id'] : '',
			'trigger_key' => 'wc_status_' . $slug,
			'name'        => $rule['name'] ?? ( $ar ? 'حالة الطلب: ' . $slug : 'Order status: ' . $slug ),
			'channels'    => ( $rule && ! empty( $rule['channels'] ) ) ? $rule['channels'] : self::status_default_channels( $slug ),
			'recipients'  => $rule['recipients'] ?? array( 'customer' ),
			'message'     => $rule['message'] ?? $def,
			'enabled'     => $rule ? ( $rule['enabled'] ?? 0 ) : 0,
		);
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- verified above.
		if ( isset( $_POST['enabled'] ) ) {
			$payload['enabled'] = absint( $_POST['enabled'] );
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- verified above.
		if ( isset( $_POST['message'] ) ) {
			$payload['message'] = wp_kses_post( wp_unslash( $_POST['message'] ) );
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- verified above.
		if ( isset( $_POST['channels'] ) && is_array( $_POST['channels'] ) ) {
			$payload['channels'] = array_values(
				array_unique(
					array_filter(
						array_map( 'sanitize_key', wp_unslash( $_POST['channels'] ) )
					)
				)
			);
			if ( empty( $payload['channels'] ) ) {
				$payload['channels'] = self::status_default_channels( $slug );
			}
		}
		if ( '' === trim( wp_strip_all_tags( $payload['message'] ) ) ) {
			$payload['message'] = $def ? $def : ( $ar ? 'تحديث على طلبك #{{order_id}}.' : 'Update on your order #{{order_id}}.' );
		}
		$res = $core->save_rule( $payload );
		if ( ! empty( $res['ok'] ) ) {
			wp_send_json_success( array( 'id' => $res['id'] ) );
		}
		wp_send_json_error( array( 'message' => $res['message'] ?? 'error' ) );
	}

	/* ------------------------------------------------------------------ */
	/* Dispatch                                                           */
	/* ------------------------------------------------------------------ */

	/**
	 * Render a notifications route.
	 *
	 * @param Mersal_Suite $ctx Context.
	 */
	public static function dispatch( $ctx ) {
		$leaf = substr( $ctx->route(), 3 ); // after 'nt.'
		$ar   = 'ar' === $ctx->lang();
		echo '<script>window.MNOTIF_SUITE=' . wp_json_encode(
			array(
				'ajax'  => admin_url( 'admin-ajax.php' ),
				'nonce' => wp_create_nonce( 'mnotif_rule' ),
				'lang'  => $ctx->lang(),
			)
		) . ';</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

		// Full standalone screens mirrored into the Suite shell.
		$embed = self::embed_page_for( $leaf );
		if ( null !== $embed ) {
			self::admin()->render_suite_page( $embed, $ctx );
			return;
		}

		switch ( $leaf ) {
			case 'dash':
				self::page_dash( $ctx, $ar );
				break;
			case 'segments':
				self::page_segments( $ctx, $ar );
				break;
			case 'log':
				self::page_log( $ctx, $ar );
				break;
		}
		self::print_js();
	}

	/**
	 * Status colour pair for a delivery status.
	 *
	 * @param string $st Status.
	 * @return array
	 */
	private static function log_tone( $st ) {
		if ( 'failed' === $st ) {
			return array( 'var(--danger-soft)', 'var(--danger)' );
		}
		return array( 'var(--accent-soft)', 'var(--accent)' );
	}

	/* ------------------------------------------------------------------ */
	/* Dashboard                                                          */
	/* ------------------------------------------------------------------ */

	/**
	 * Notifications dashboard.
	 *
	 * @param Mersal_Suite $ctx Context.
	 * @param bool         $ar  Arabic.
	 */
	private static function page_dash( $ctx, $ar ) {
		$ctx->page_head( $ar ? 'لوحة الإشعارات' : 'Notifications Dashboard', $ar ? 'أداء المُحفزات والتسليم' : 'Trigger & delivery performance' );
		$core = self::core();
		$ov   = $core->get_overview();
		$cards = array(
			array( $ar ? 'إشعارات اليوم' : 'Sent today', number_format_i18n( $ov['today'] ), 'send', 'info' ),
			array( $ar ? 'مُحفزات نشطة' : 'Active triggers', number_format_i18n( $ov['enabled'] ), 'bolt', 'accent' ),
			array( $ar ? 'إجمالي الإرسال' : 'Total sent', number_format_i18n( $ov['sent'] ), 'mark_email_read', 'violet' ),
			array( $ar ? 'إجمالي المُحفزات' : 'Total triggers', number_format_i18n( $ov['rules'] ), 'rule', 'hi' ),
		);
		echo '<div style="display:grid; grid-template-columns:repeat(4,1fr); gap:10px; margin-bottom:13px;">';
		foreach ( $cards as $c ) {
			list( $bg, $fg ) = $ctx->tone( $c[3] );
			echo '<div style="background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:13px; box-shadow:var(--shadow);">';
			echo '<div style="width:32px; height:32px; border-radius:11px; display:grid; place-items:center; background:' . esc_attr( $bg ) . '; color:' . esc_attr( $fg ) . ';"><span class="msym fill" style="font-size:20px;">' . esc_html( $c[2] ) . '</span></div>';
			echo '<div style="font-size:19px; font-weight:800; margin-top:13px; color:var(--fg-1);">' . esc_html( $c[1] ) . '</div>';
			echo '<div style="font-size:12px; color:var(--fg-2); margin-top:2px;">' . esc_html( $c[0] ) . '</div></div>';
		}
		echo '</div>';

		echo '<div style="display:grid; grid-template-columns:1fr 1fr; gap:12px; align-items:start;">';

		// Active triggers.
		echo '<div style="background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:14px; box-shadow:var(--shadow);">';
		echo '<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:14px;"><h3 style="font-size:13.5px; font-weight:800; margin:0; color:var(--fg-1);">' . esc_html( $ar ? 'المُحفزات' : 'Triggers' ) . '</h3><a href="' . esc_url( $ctx->url( 'nt.triggers' ) ) . '" style="font-size:12px; font-weight:700; color:var(--accent);">' . esc_html( $ar ? 'عرض الكل' : 'View all' ) . '</a></div>';
		echo '<div style="display:flex; flex-direction:column; gap:9px;">';
		$rules = array_slice( $core->get_rules(), 0, 5 );
		if ( empty( $rules ) ) {
			echo '<p style="font-size:12.5px; color:var(--fg-3); margin:0;">' . esc_html( $ar ? 'لا توجد مُحفزات بعد — افتح «محفّزات الطلبات».' : 'No triggers yet — open Order triggers.' ) . '</p>';
		}
		foreach ( $rules as $r ) {
			$on = ! empty( $r['enabled'] );
			echo '<div style="display:flex; align-items:center; gap:12px; padding:11px; border-radius:12px; background:var(--surface-3); border:1px solid var(--border);">';
			echo '<div style="width:34px; height:34px; border-radius:10px; display:grid; place-items:center; background:var(--accent-soft); color:var(--accent); flex:0 0 34px;"><span class="msym fill" style="font-size:18px;">bolt</span></div>';
			echo '<div style="flex:1; min-width:0;"><b style="font-size:13px; color:var(--fg-1);">' . esc_html( $r['name'] ) . '</b><div style="font-size:11px; color:var(--fg-3);">' . esc_html( implode( ' · ', array_map( 'ucfirst', (array) ( $r['channels'] ?? array() ) ) ) ) . '</div></div>';
			$sbg = $on ? 'var(--accent-soft)' : 'var(--surface-3)';
			$sfg = $on ? 'var(--accent)' : 'var(--fg-3)';
			echo '<span style="font-size:10.5px; font-weight:700; padding:3px 9px; border-radius:99px; background:' . esc_attr( $sbg ) . '; color:' . esc_attr( $sfg ) . ';">' . esc_html( $on ? ( $ar ? 'نشط' : 'Live' ) : ( $ar ? 'موقوف' : 'Off' ) ) . '</span>';
			echo '</div>';
		}
		echo '</div></div>';

		// Delivery log.
		echo '<div style="background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:14px; box-shadow:var(--shadow);">';
		echo '<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:14px;"><h3 style="font-size:13.5px; font-weight:800; margin:0; color:var(--fg-1);">' . esc_html( $ar ? 'سجل التسليم' : 'Delivery log' ) . '</h3><a href="' . esc_url( $ctx->url( 'nt.log' ) ) . '" style="font-size:12px; font-weight:700; color:var(--accent);">' . esc_html( $ar ? 'عرض الكل' : 'View all' ) . '</a></div>';
		echo '<div style="display:flex; flex-direction:column;">';
		$log = $core->get_log( 6 );
		if ( empty( $log ) ) {
			echo '<p style="font-size:12.5px; color:var(--fg-3); margin:0;">' . esc_html( $ar ? 'لا يوجد نشاط بعد.' : 'No activity yet.' ) . '</p>';
		}
		foreach ( $log as $l ) {
			$st = $l['status'] ?? 'sent';
			list( $sbg, $sfg ) = self::log_tone( $st );
			echo '<div style="display:flex; align-items:center; gap:11px; padding:10px 0; border-bottom:1px solid var(--border);">';
			echo '<div style="flex:1; min-width:0;"><div style="font-size:12.5px; font-weight:600; color:var(--fg-1); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">' . esc_html( $l['rule'] ?? '' ) . '</div><div style="font-size:11px; color:var(--fg-3);">' . esc_html( ucfirst( $l['channel'] ?? '' ) ) . ' · ' . esc_html( isset( $l['time'] ) ? date_i18n( 'H:i', $l['time'] ) : '' ) . '</div></div>';
			echo '<span style="font-size:10.5px; font-weight:700; padding:3px 9px; border-radius:99px; background:' . esc_attr( $sbg ) . '; color:' . esc_attr( $sfg ) . ';">' . esc_html( 'failed' === $st ? ( $ar ? 'فشل' : 'Failed' ) : ( $ar ? 'تم الإرسال' : 'Sent' ) ) . '</span>';
			echo '</div>';
		}
		echo '</div></div>';
		echo '</div>';
	}

	/* ------------------------------------------------------------------ */
	/* Triggers (WooCommerce order statuses)                              */
	/* ------------------------------------------------------------------ */

	/**
	 * Channel icon + colour.
	 *
	 * @param string $c Channel.
	 * @return array
	 */
	private static function chan_meta( $c ) {
		$m = array(
			'whatsapp' => array( 'chat', '#25d366' ),
			'email'    => array( 'mail', '#7c3aed' ),
			'sms'      => array( 'sms', '#0f7a4a' ),
			'push'     => array( 'notifications', '#16a34a' ),
		);
		return isset( $m[ $c ] ) ? $m[ $c ] : array( 'bolt', '#64748b' );
	}

	/**
	 * Render one order-status trigger card (list view).
	 *
	 * @param array $row  Row data.
	 * @param bool  $ar   Arabic.
	 * @param bool  $rtl  RTL layout.
	 * @param bool  $path Path view fragment (unused; kept for future reuse).
	 */
	private static function render_trigger_card( $row, $ar, $rtl, $path = false ) {
		$on   = $row['on'];
		$m    = $row['m'];
		$chs  = $row['chs'];
		$swbg = $on ? 'var(--accent)' : 'var(--border-strong)';
		$knob = $on ? ( $rtl ? '-20px' : '20px' ) : '0px';
		$stats = $on
			? ( $ar ? 'فوري · ' : 'Instant · ' ) . number_format_i18n( $row['wk'] ) . ( $ar ? ' هذا الأسبوع' : ' this week' )
			: ( $ar ? 'موقوف' : 'Off' );

		echo '<div class="nt-trig-card' . ( $on ? ' is-on' : ' is-off' ) . '" data-nt-row="' . esc_attr( $row['slug'] ) . '" data-nt-rule-id="' . esc_attr( $row['id'] ) . '">';
		echo '<div class="nt-trig-row">';
		echo '<div class="nt-trig-icon" style="background:color-mix(in srgb,' . esc_attr( $m[1] ) . ' 16%,transparent);color:' . esc_attr( $m[1] ) . ';"><span class="msym fill">' . esc_html( $m[0] ) . '</span></div>';
		echo '<div class="nt-trig-body' . ( $on ? '' : ' is-off' ) . '">';
		echo '<div class="nt-trig-title"><b>' . esc_html( $row['label'] ) . '</b><span class="nt-trig-slug">wc-' . esc_html( $row['slug'] ) . '</span></div>';
		echo '<div class="nt-trig-meta"><div class="nt-trig-chans" data-nt-chans-display="' . esc_attr( $row['slug'] ) . '">';
		foreach ( $chs as $c ) {
			$cm = self::chan_meta( $c );
			echo '<span class="nt-trig-chan" title="' . esc_attr( ucfirst( $c ) ) . '" style="background:color-mix(in srgb,' . esc_attr( $cm[1] ) . ' 15%,transparent);color:' . esc_attr( $cm[1] ) . ';"><span class="msym fill">' . esc_html( $cm[0] ) . '</span></span>';
		}
		echo '</div><span class="nt-trig-stats" data-nt-stats="' . esc_attr( $row['slug'] ) . '">' . esc_html( $stats ) . '</span></div>';
		echo '</div>';
		echo '<button type="button" class="nt-trig-edit" data-nt-edit="' . esc_attr( $row['slug'] ) . '"><span class="msym" style="font-size:16px;">edit</span>' . esc_html( $ar ? 'تعديل' : 'Edit' ) . '</button>';
		echo '<button type="button" class="nt-trig-sw" data-nt-toggle="' . esc_attr( $row['slug'] ) . '" data-on="' . ( $on ? '1' : '0' ) . '" style="background:' . esc_attr( $swbg ) . ';"><span style="transform:translateX(' . esc_attr( $knob ) . ');"></span></button>';
		echo '</div>';

		echo '<div class="nt-trig-editbox" data-nt-editbox="' . esc_attr( $row['slug'] ) . '" style="display:none;">';
		echo '<label>' . esc_html( $ar ? 'طرق الإرسال' : 'Delivery channels' ) . '</label>';
		echo '<div class="nt-trig-chpick" data-nt-chpick="' . esc_attr( $row['slug'] ) . '">';
		$all_ch = array( 'push', 'email', 'whatsapp', 'sms' );
		$labels = array(
			'push'     => $ar ? 'إشعار' : 'Push',
			'email'    => $ar ? 'بريد' : 'Email',
			'whatsapp' => 'WhatsApp',
			'sms'      => 'SMS',
		);
		foreach ( $all_ch as $cid ) {
			$active = in_array( $cid, $chs, true );
			$cm     = self::chan_meta( $cid );
			echo '<button type="button" data-nt-ch="' . esc_attr( $cid ) . '" data-on="' . ( $active ? '1' : '0' ) . '" style="color:' . esc_attr( $cm[1] ) . ';"><span class="msym fill" style="font-size:16px;">' . esc_html( $cm[0] ) . '</span>' . esc_html( $labels[ $cid ] ?? ucfirst( $cid ) ) . '</button>';
		}
		echo '</div>';
		echo '<label>' . esc_html( $ar ? 'نص الرسالة' : 'Message body' ) . '</label>';
		echo '<textarea data-nt-msg="' . esc_attr( $row['slug'] ) . '" rows="3" style="width:100%;box-sizing:border-box;resize:vertical;background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:10px 12px;font-size:13px;color:var(--fg-1);line-height:1.6;">' . esc_textarea( $row['msg'] ) . '</textarea>';
		echo '</div></div>';
	}

	/* ------------------------------------------------------------------ */
	/* Editor                                                             */
	/* ------------------------------------------------------------------ */

	/* ------------------------------------------------------------------ */
	/* Segments (real counts)                                             */
	/* ------------------------------------------------------------------ */

	/**
	 * Audience segments with real, cached counts.
	 *
	 * @param Mersal_Suite $ctx Context.
	 * @param bool         $ar  Arabic.
	 */
	private static function page_segments( $ctx, $ar ) {
		echo '<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:18px;">';
		echo '<div><h2 style="font-size:18px; font-weight:800; margin:0; color:var(--fg-1);">' . esc_html( $ar ? 'شرائح الجمهور' : 'Audience segments' ) . '</h2><p style="margin:4px 0 0; font-size:13px; color:var(--fg-2);">' . esc_html( $ar ? 'مجموعات ديناميكية تُحدّث تلقائياً من بيانات متجرك' : 'Dynamic groups computed from your store data' ) . '</p></div>';
		echo '</div>';

		$segs = self::segment_counts();
		echo '<div style="display:grid; grid-template-columns:repeat(3,1fr); gap:10px;">';
		foreach ( $segs as $s ) {
			list( $bg, $fg ) = $ctx->tone( $s['tone'] );
			echo '<div style="background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:13px; box-shadow:var(--shadow);">';
			echo '<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:12px;"><div style="width:42px; height:42px; border-radius:12px; display:grid; place-items:center; background:' . esc_attr( $bg ) . '; color:' . esc_attr( $fg ) . ';"><span class="msym fill" style="font-size:19px;">' . esc_html( $s['icon'] ) . '</span></div></div>';
			echo '<b style="font-size:15px; color:var(--fg-1);">' . esc_html( $s['name'] ) . '</b>';
			echo '<div style="font-size:22px; font-weight:800; color:var(--fg-1); margin-top:8px;">' . esc_html( number_format_i18n( $s['count'] ) ) . ' <span style="font-size:12px; font-weight:600; color:var(--fg-3);">' . esc_html( $ar ? 'عميل' : 'customers' ) . '</span></div>';
			echo '<div style="display:flex; align-items:center; gap:6px; margin-top:12px; padding:8px 11px; border-radius:9px; background:var(--surface-3); border:1px solid var(--border);"><span class="msym" style="font-size:15px; color:var(--fg-3);">filter_alt</span><span style="font-size:11.5px; color:var(--fg-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">' . esc_html( $s['rule'] ) . '</span></div>';
			echo '</div>';
		}
		echo '</div>';
	}

	/**
	 * Compute real segment counts (cached 1h).
	 *
	 * @return array
	 */
	private static function segment_counts() {
		$ar     = 'ar' === Mersal_Suite::instance()->lang();
		$cached = get_transient( 'mnotif_segment_counts_' . ( $ar ? 'ar' : 'en' ) );
		if ( is_array( $cached ) ) {
			return $cached;
		}
		$has_wc = class_exists( 'WooCommerce' );

		// New customers (last 30 days).
		$new_q = new WP_User_Query(
			array(
				'date_query' => array( array( 'after' => '30 days ago' ) ),
				'fields'     => 'ID',
				'number'     => 1,
				'count_total' => true,
			)
		);
		$new_count = (int) $new_q->get_total();

		// All customers.
		$all = count_users();
		$all_count = (int) ( $all['total_users'] ?? 0 );

		// WhatsApp opt-ins (users with a stored phone meta).
		$wa_q = new WP_User_Query(
			array(
				'meta_query' => array(
					'relation' => 'OR',
					array( 'key' => 'billing_phone', 'compare' => 'EXISTS' ),
					array( 'key' => 'motp_phone', 'compare' => 'EXISTS' ),
				),
				'fields'      => 'ID',
				'number'      => 1,
				'count_total' => true,
			)
		);
		$wa_count = (int) $wa_q->get_total();

		// VIP (WC money spent > 5000).
		$vip_count = 0;
		if ( $has_wc ) {
			$vip_q = new WP_User_Query(
				array(
					'meta_query'  => array( array( 'key' => '_money_spent', 'value' => 5000, 'compare' => '>', 'type' => 'NUMERIC' ) ),
					'fields'      => 'ID',
					'number'      => 1,
					'count_total' => true,
				)
			);
			$vip_count = (int) $vip_q->get_total();
		}

		$segs = array(
			array( 'id' => 'all', 'name' => $ar ? 'كل العملاء' : 'All customers', 'count' => $all_count, 'icon' => 'public', 'tone' => 'info', 'rule' => $ar ? 'كل المستخدمين' : 'All users' ),
			array( 'id' => 'new', 'name' => $ar ? 'عملاء جدد' : 'New customers', 'count' => $new_count, 'icon' => 'fiber_new', 'tone' => 'accent', 'rule' => $ar ? 'سجّلوا خلال ٣٠ يوم' : 'Joined in last 30 days' ),
			array( 'id' => 'wa', 'name' => $ar ? 'لديهم رقم هاتف' : 'Have a phone', 'count' => $wa_count, 'icon' => 'chat', 'tone' => 'accent', 'rule' => $ar ? 'لديهم رقم محفوظ' : 'Have a stored phone' ),
			array( 'id' => 'vip', 'name' => $ar ? 'عملاء VIP' : 'VIP customers', 'count' => $vip_count, 'icon' => 'workspace_premium', 'tone' => 'hi', 'rule' => $ar ? 'أنفقوا أكثر من ٥٬٠٠٠' : 'Spent > 5,000' ),
		);
		set_transient( 'mnotif_segment_counts_' . ( $ar ? 'ar' : 'en' ), $segs, HOUR_IN_SECONDS );
		return $segs;
	}

	/* ------------------------------------------------------------------ */
	/* Delivery log                                                       */
	/* ------------------------------------------------------------------ */

	/**
	 * Delivery log table.
	 *
	 * @param Mersal_Suite $ctx Context.
	 * @param bool         $ar  Arabic.
	 */
	private static function page_log( $ctx, $ar ) {
		$ctx->page_head( $ar ? 'سجل التسليم' : 'Delivery log', $ar ? 'حالة كل رسالة لحظة بلحظة' : 'Real-time status of every message' );
		$rows = self::core()->get_log( 50 );
		echo '<div style="background:var(--surface); border:1px solid var(--border); border-radius:12px; overflow:hidden; box-shadow:var(--shadow);">';
		echo '<div style="display:grid; grid-template-columns:.7fr 1.5fr 2fr 1fr 1fr; gap:10px; padding:13px 18px; background:var(--surface-3); font-size:11.5px; font-weight:800; color:var(--fg-2); border-bottom:1px solid var(--border);">';
		echo '<span>' . esc_html( $ar ? 'الوقت' : 'Time' ) . '</span><span>' . esc_html( $ar ? 'المستلم' : 'Recipient' ) . '</span><span>' . esc_html( $ar ? 'المُحفز' : 'Trigger' ) . '</span><span>' . esc_html( $ar ? 'القناة' : 'Channel' ) . '</span><span>' . esc_html( $ar ? 'الحالة' : 'Status' ) . '</span></div>';
		if ( empty( $rows ) ) {
			echo '<div style="padding:30px 18px; text-align:center; font-size:13px; color:var(--fg-3);">' . esc_html( $ar ? 'لا يوجد سجل بعد.' : 'No log entries yet.' ) . '</div>';
		}
		foreach ( $rows as $l ) {
			$st = $l['status'] ?? 'sent';
			list( $sbg, $sfg ) = self::log_tone( $st );
			echo '<div style="display:grid; grid-template-columns:.7fr 1.5fr 2fr 1fr 1fr; gap:10px; padding:13px 18px; font-size:12.5px; color:var(--fg-1); border-bottom:1px solid var(--border); align-items:center;">';
			echo '<span style="color:var(--fg-2); font-family:Inter,monospace; direction:ltr; font-size:11.5px;">' . esc_html( isset( $l['time'] ) ? date_i18n( 'H:i', $l['time'] ) : '' ) . '</span>';
			echo '<span style="font-weight:600; direction:ltr; text-align:start; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">' . esc_html( $l['to'] ?? '' ) . '</span>';
			echo '<span style="color:var(--fg-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">' . esc_html( $l['rule'] ?? '' ) . '</span>';
			echo '<span style="color:var(--fg-2);">' . esc_html( ucfirst( $l['channel'] ?? '' ) ) . '</span>';
			echo '<span><span style="font-size:11px; font-weight:700; padding:3px 9px; border-radius:99px; background:' . esc_attr( $sbg ) . '; color:' . esc_attr( $sfg ) . ';">' . esc_html( 'failed' === $st ? ( $ar ? 'فشل' : 'Failed' ) : ( $ar ? 'تم الإرسال' : 'Sent' ) ) . '</span></span>';
			echo '</div>';
		}
		echo '</div>';
	}

	/* ------------------------------------------------------------------ */
	/* JS                                                                 */
	/* ------------------------------------------------------------------ */

	/**
	 * Print the notifications page JS (once).
	 */
	private static function print_js() {
		if ( self::$js_printed ) {
			return;
		}
		self::$js_printed = true;
		?>
		<script id="mnotif-suite-js">
		(function () {
			var CFG = window.MNOTIF_SUITE || {};
			var root = document.querySelector('.mersal-suite-app');
			if (!root) return;
			var rtl = root.getAttribute('dir') === 'rtl';
			var en = CFG.lang === 'en';

			function post(action, data, cb) {
				var body = new URLSearchParams();
				body.append('action', action);
				body.append('nonce', CFG.nonce);
				for (var k in data) { if (Object.prototype.hasOwnProperty.call(data, k)) { var v = data[k]; if (Array.isArray(v)) { v.forEach(function (x) { body.append(k + '[]', x); }); } else { body.append(k, v); } } }
				fetch(CFG.ajax, { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: body.toString() })
					.then(function (r) { return r.json(); }).then(function (j) { cb && cb(j); }).catch(function () { cb && cb({ success: false }); });
			}
			function toast(msg, ok) {
				var t = document.createElement('div'); t.textContent = msg;
				t.style.cssText = 'position:fixed; inset-inline:0; bottom:90px; z-index:99999; margin:0 auto; width:max-content; max-width:90%; background:' + (ok === false ? 'var(--danger)' : 'var(--fg-1)') + '; color:#fff; padding:10px 18px; border-radius:99px; font-size:13px; font-weight:700; box-shadow:0 10px 30px rgba(0,0,0,.25); font-family:Cairo,Inter,sans-serif;';
				document.body.appendChild(t); setTimeout(function () { t.style.transition = 'opacity .3s'; t.style.opacity = '0'; setTimeout(function () { t.remove(); }, 300); }, 1700);
			}

			/* ---- triggers: toggle (auto-save) + inline edit + save bar ---- */
			var dirty = {};
			var dirtyCh = {};
			function setBar() {
				var bar = root.querySelector('[data-nt-savestatus]');
				var btn = root.querySelector('[data-nt-save]');
				var n = Object.keys(dirty).length + Object.keys(dirtyCh).length;
				if (!bar || !btn) return;
				if (n > 0) {
					bar.style.color = 'var(--hi)';
					bar.innerHTML = '<span class="msym fill" style="font-size:19px;">edit_note</span>' + (en ? 'You have unsaved changes' : 'لديك تغييرات غير محفوظة');
					btn.style.background = 'var(--accent)'; btn.style.color = '#fff'; btn.style.borderColor = 'var(--accent)'; btn.style.cursor = 'pointer';
				} else {
					bar.style.color = 'var(--accent)';
					bar.innerHTML = '<span class="msym fill" style="font-size:19px;">check_circle</span>' + (en ? 'All changes saved' : 'كل التغييرات محفوظة');
					btn.style.background = 'var(--surface-3)'; btn.style.color = 'var(--fg-3)'; btn.style.borderColor = 'var(--border)'; btn.style.cursor = 'default';
				}
			}
			function chanIconHtml(c) {
				var m = { whatsapp: ['chat', '#25d366'], email: ['mail', '#7c3aed'], sms: ['sms', '#0f7a4a'], push: ['notifications', '#16a34a'] };
				var x = m[c] || ['bolt', '#64748b'];
				return '<span class="nt-trig-chan" title="' + c + '" style="background:color-mix(in srgb,' + x[1] + ' 15%,transparent);color:' + x[1] + ';"><span class="msym fill" style="font-size:15px;">' + x[0] + '</span></span>';
			}
			function refreshChanDisplay(slug) {
				var box = root.querySelector('[data-nt-chans-display="' + slug + '"]');
				var pick = root.querySelector('[data-nt-chpick="' + slug + '"]');
				if (!box || !pick) return;
				var chs = [];
				pick.querySelectorAll('[data-nt-ch]').forEach(function (b) { if (b.getAttribute('data-on') === '1') chs.push(b.getAttribute('data-nt-ch')); });
				box.innerHTML = chs.map(chanIconHtml).join('');
			}
			var triggersRoot = root.querySelector('[data-nt-triggers]');
			if (triggersRoot) {
				root.querySelectorAll('[data-nt-view-toggle] button').forEach(function (btn) {
					btn.addEventListener('click', function () {
						var view = btn.getAttribute('data-nt-view');
						root.querySelectorAll('[data-nt-view-toggle] button').forEach(function (b) { b.setAttribute('data-on', b === btn ? '1' : '0'); });
						root.querySelectorAll('[data-nt-view-panel]').forEach(function (p) {
							var on = p.getAttribute('data-nt-view-panel') === view;
							if (p.getAttribute('data-nt-view-panel') === 'list') {
								p.style.display = on ? 'flex' : 'none';
							} else {
								p.setAttribute('data-on', on ? '1' : '0');
							}
						});
					});
				});
				var testTop = root.querySelector('[data-nt-triggers-test]');
				if (testTop) testTop.addEventListener('click', function () {
					var id = triggersRoot.getAttribute('data-nt-test-id');
					if (!id) {
						root.querySelectorAll('[data-nt-row]').forEach(function (row) {
							if (!id && row.classList.contains('is-on')) id = row.getAttribute('data-nt-rule-id');
						});
					}
					if (!id) { toast(en ? 'Enable a trigger first' : 'فعّل محفّزاً أولاً', false); return; }
					post('mnotif_test_rule', { id: id }, function (j) {
						toast((j && j.data && j.data.message) || (en ? 'Test sent' : 'تم الإرسال'), !!(j && j.success));
					});
				});
			}
			root.querySelectorAll('[data-nt-toggle]').forEach(function (btn) {
				btn.addEventListener('click', function () {
					var slug = btn.getAttribute('data-nt-toggle');
					var on = btn.getAttribute('data-on') === '1';
					var next = !on;
					btn.setAttribute('data-on', next ? '1' : '0');
					btn.style.background = next ? 'var(--accent)' : 'var(--border-strong)';
					var knob = btn.querySelector('span'); if (knob) knob.style.transform = 'translateX(' + (next ? (rtl ? '-20px' : '20px') : '0px') + ')';
					var card = btn.closest('[data-nt-row]');
					if (card) {
						card.classList.toggle('is-on', next);
						card.classList.toggle('is-off', !next);
						var body = card.querySelector('.nt-trig-body');
						if (body) body.classList.toggle('is-off', !next);
						var stats = card.querySelector('[data-nt-stats]');
						if (stats) stats.textContent = next ? (en ? 'Instant · 0 this week' : 'فوري · 0 هذا الأسبوع') : (en ? 'Off' : 'موقوف');
					}
					post('mnotif_suite_trigger', { status: slug, enabled: next ? 1 : 0 }, function (j) {
						if (!j || !j.success) { toast(en ? 'Save failed' : 'فشل الحفظ', false); }
						else {
							toast(en ? 'Saved' : 'تم الحفظ');
							if (j.data && j.data.id && card) {
								card.setAttribute('data-nt-rule-id', j.data.id);
								if (triggersRoot) triggersRoot.setAttribute('data-nt-test-id', j.data.id);
							}
						}
					});
				});
			});
			root.querySelectorAll('[data-nt-chpick]').forEach(function (pick) {
				var slug = pick.getAttribute('data-nt-chpick');
				pick.querySelectorAll('[data-nt-ch]').forEach(function (btn) {
					btn.addEventListener('click', function () {
						var on = btn.getAttribute('data-on') === '1';
						btn.setAttribute('data-on', on ? '0' : '1');
						if (!dirtyCh[slug]) dirtyCh[slug] = [];
						dirtyCh[slug] = [];
						pick.querySelectorAll('[data-nt-ch]').forEach(function (b) { if (b.getAttribute('data-on') === '1') dirtyCh[slug].push(b.getAttribute('data-nt-ch')); });
						if (!dirtyCh[slug].length) dirtyCh[slug] = ['whatsapp'];
						refreshChanDisplay(slug);
						setBar();
					});
				});
			});
			root.querySelectorAll('[data-nt-edit]').forEach(function (b) {
				b.addEventListener('click', function () {
					var slug = b.getAttribute('data-nt-edit');
					var box = root.querySelector('[data-nt-editbox="' + slug + '"]');
					if (box) box.style.display = box.style.display === 'none' ? 'block' : 'none';
				});
			});
			root.querySelectorAll('[data-nt-msg]').forEach(function (ta) {
				ta.addEventListener('input', function () { dirty[ta.getAttribute('data-nt-msg')] = ta.value; setBar(); });
			});
			var saveBtn = root.querySelector('[data-nt-save]');
			if (saveBtn) saveBtn.addEventListener('click', function () {
				var slugs = {};
				Object.keys(dirty).forEach(function (s) { slugs[s] = true; });
				Object.keys(dirtyCh).forEach(function (s) { slugs[s] = true; });
				var keys = Object.keys(slugs);
				if (!keys.length) return;
				var done = 0, failed = 0;
				keys.forEach(function (slug) {
					var payload = { status: slug };
					if (dirty[slug] !== undefined) payload.message = dirty[slug];
					if (dirtyCh[slug]) payload.channels = dirtyCh[slug];
					post('mnotif_suite_trigger', payload, function (j) {
						done++; if (!j || !j.success) failed++;
						if (done === keys.length) { dirty = {}; dirtyCh = {}; setBar(); toast(failed ? (en ? 'Some failed' : 'فشل بعضها') : (en ? 'Saved' : 'تم الحفظ'), !failed); }
					});
				});
			});
			var discard = root.querySelector('[data-nt-discard]');
			if (discard) discard.addEventListener('click', function () { if (Object.keys(dirty).length || Object.keys(dirtyCh).length) location.reload(); });

			/* ---- editor ---- */
			var body = root.querySelector('[data-nt-body]');
			var subj = root.querySelector('[data-nt-subject]');
			var pv = root.querySelector('[data-nt-preview]');
			function renderPv() {
				if (!body || !pv) return;
				pv.textContent = body.value.replace(/\{\{customer_name\}\}/g, en ? 'Ahmed' : 'أحمد').replace(/\{\{order_id\}\}/g, '10482').replace(/\{\{order_total\}\}/g, '99.00').replace(/\{\{order_status_label\}\}/g, en ? 'Processing' : 'قيد التنفيذ');
			}
			if (body) body.addEventListener('input', renderPv);
			root.querySelectorAll('[data-nt-var]').forEach(function (v) {
				v.addEventListener('click', function () {
					if (!body) return;
					var t = v.getAttribute('data-nt-var');
					var s = body.selectionStart || body.value.length;
					body.value = body.value.slice(0, s) + t + body.value.slice(body.selectionEnd || s);
					body.focus(); renderPv();
				});
			});
			root.querySelectorAll('[data-nt-chtab]').forEach(function (tab) {
				tab.addEventListener('click', function () {
					// toggle channel inclusion + active styling
					var on = tab.getAttribute('data-on') === '1';
					var active = tab.getAttribute('data-active') === '1';
					if (active) { // clicking active toggles inclusion off/on
						tab.setAttribute('data-on', on ? '0' : '1');
						tab.style.opacity = on ? '.45' : '1';
					} else {
						root.querySelectorAll('[data-nt-chtab]').forEach(function (o) { o.setAttribute('data-active', '0'); o.style.background = 'transparent'; o.style.borderColor = 'transparent'; o.style.color = 'var(--fg-3)'; });
						tab.setAttribute('data-active', '1'); tab.setAttribute('data-on', '1'); tab.style.opacity = '1';
						tab.style.background = 'var(--surface)'; tab.style.borderColor = 'var(--border)'; tab.style.color = 'var(--fg-1)';
					}
					var sw = root.querySelector('[data-nt-subjectwrap]');
					if (sw) sw.style.display = (tab.getAttribute('data-nt-chtab') === 'email' && tab.getAttribute('data-active') === '1') ? 'block' : sw.style.display;
				});
			});
			function selectedChannels() {
				var out = [];
				root.querySelectorAll('[data-nt-chtab]').forEach(function (t) { if (t.getAttribute('data-on') === '1') out.push(t.getAttribute('data-nt-chtab')); });
				return out.length ? out : ['whatsapp'];
			}
			var lastId = '';
			var saveN = root.querySelector('[data-nt-savenotif]');
			if (saveN) saveN.addEventListener('click', function () {
				var trig = root.querySelector('[data-nt-trigger]');
				post('mnotif_save_rule', {
					id: lastId, trigger_key: trig ? trig.value : '', channels: selectedChannels(),
					message: body ? body.value : '', email_subject: subj ? subj.value : '', enabled: 1, recipients: ['customer']
				}, function (j) {
					if (j && j.success) { lastId = (j.data && j.data.id) || lastId; toast(en ? 'Notification saved' : 'تم حفظ الإشعار'); }
					else { toast((j && j.data && j.data.message) || (en ? 'Save failed' : 'فشل الحفظ'), false); }
				});
			});
			var testB = root.querySelector('[data-nt-test]');
			if (testB) testB.addEventListener('click', function () {
				if (!lastId) { toast(en ? 'Save the notification first' : 'احفظ الإشعار أولاً', false); return; }
				post('mnotif_test_rule', { id: lastId }, function (j) {
					toast((j && j.data && j.data.message) || (en ? 'Test sent' : 'تم الإرسال'), !(j && j.data && j.data.message && !j.success));
				});
			});
		})();
		</script>
		<?php
	}
}
