<?php
/**
 * WhatsApp Chat Widget — floating button with multi-agent support.
 *
 * Renders a customizable WhatsApp floating chat button on the front-end:
 * multiple agents with avatars/roles, social links, device + page visibility
 * rules, optional page-URL context in the prefilled message, and rich
 * analytics (impressions, opens, clicks per agent / page / device / OS /
 * hour / weekday) aggregated into a bounded option for the admin dashboard.
 *
 * @package Mersal_Notif
 */

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

class Mersal_Notif_Chat_Widget {

	const SETTINGS_KEY = 'mnotif_chat_widget';
	const STATS_KEY    = 'mnotif_chat_stats';

	/**
	 * Initialize hooks.
	 */
	public function init() {
		// Settings save + stats are admin-side and must work even when the
		// widget is currently disabled (so it can be configured, then enabled).
		add_action( 'wp_ajax_mnotif_save_widget', array( $this, 'ajax_save_widget' ) );

		if ( ! $this->is_enabled() ) {
			return;
		}

		add_action( 'wp_footer', array( $this, 'render' ) );
		add_action( 'wp_ajax_mnotif_chat_track', array( $this, 'ajax_track' ) );
		add_action( 'wp_ajax_nopriv_mnotif_chat_track', array( $this, 'ajax_track' ) );
	}

	/**
	 * Check if chat widget is enabled.
	 *
	 * @return bool
	 */
	private function is_enabled() {
		return (int) Mersal_Notif_Settings::get( 'chat_widget_enabled', 0 ) === 1;
	}

	/**
	 * Get widget settings.
	 *
	 * @return array
	 */
	public static function get_settings() {
		$defaults = array(
			'button_color'     => '#25D366',
			'icon_color'       => '#ffffff',
			'position'         => 'right',
			'button_size'      => '60',
			'bottom_offset'    => '24',
			'corner_radius'    => '12',
			'show_desktop'     => 1,
			'show_mobile'      => 1,
			'powered_by'       => 1,
			'include_page_url' => 0,
			'header_title'     => __( 'Chat with us', 'mersal-notifications' ),
			'welcome_msg'      => __( 'Hello! How can we help you?', 'mersal-notifications' ),
			'reply_time'       => __( 'Usually replies in a few minutes', 'mersal-notifications' ),
			'excluded_pages'   => '',
			'agents'           => array(),
			'social_links'     => array(),
		);
		$saved = get_option( self::SETTINGS_KEY, array() );
		return wp_parse_args( is_array( $saved ) ? $saved : array(), $defaults );
	}

	/**
	 * Check if widget should show on current page.
	 *
	 * @param array $settings Widget settings.
	 * @return bool
	 */
	private function should_show( $settings ) {
		if ( ! $settings['show_desktop'] && ! $this->is_mobile() ) {
			return false;
		}
		if ( ! $settings['show_mobile'] && $this->is_mobile() ) {
			return false;
		}
		if ( ! empty( $settings['excluded_pages'] ) ) {
			$excluded = array_map( 'absint', explode( ',', $settings['excluded_pages'] ) );
			if ( is_page( $excluded ) ) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Render the chat widget.
	 */
	public function render() {
		$settings = self::get_settings();
		if ( ! $this->should_show( $settings ) ) {
			return;
		}

		$position = 'left' === $settings['position'] ? 'left' : 'right';
		$offset   = max( 0, (int) $settings['bottom_offset'] );
		$size     = max( 40, (int) $settings['button_size'] );
		$radius   = max( 0, (int) $settings['corner_radius'] );
		$color    = esc_attr( $settings['button_color'] );
		$icon_clr = esc_attr( $settings['icon_color'] );
		$inc_url  = ! empty( $settings['include_page_url'] ) ? 1 : 0;

		?>
		<div id="mnotif-chat-widget" style="position:fixed;bottom:<?php echo esc_attr( $offset ); ?>px;<?php echo esc_attr( $position ); ?>:20px;z-index:99998;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;">
			<!-- Chat window -->
			<div id="mnotif-chat-window" style="display:none;position:absolute;bottom:<?php echo esc_attr( $size + 16 ); ?>px;<?php echo esc_attr( $position ); ?>:0;width:340px;max-width:90vw;background:#fff;border-radius:<?php echo esc_attr( $radius ); ?>px;box-shadow:0 4px 24px rgba(0,0,0,.15);overflow:hidden;">
				<!-- Header -->
				<div style="background:<?php echo $color; ?>;color:#fff;padding:16px;">
					<div style="font-weight:600;font-size:15px;"><?php echo esc_html( $settings['header_title'] ); ?></div>
					<div style="font-size:12px;opacity:.8;margin-top:2px;"><?php echo esc_html( $settings['reply_time'] ); ?></div>
				</div>
				<!-- Welcome message -->
				<div style="padding:16px;background:#f5f5f5;">
					<div style="background:#fff;border-radius:8px;padding:12px;font-size:14px;color:#333;box-shadow:0 1px 2px rgba(0,0,0,.1);">
						<?php echo esc_html( $settings['welcome_msg'] ); ?>
					</div>
				</div>
				<!-- Agents -->
				<div style="padding:12px 16px;">
					<?php
					$agents = $settings['agents'];
					if ( empty( $agents ) ) {
						// Fallback: single agent from general settings.
						$wa_number = Mersal_Notif_Settings::get( 'wa_phone', '' );
						if ( ! empty( $wa_number ) ) {
							$agents = array(
								array(
									'name'    => get_bloginfo( 'name' ),
									'phone'   => $wa_number,
									'message' => '',
								),
							);
						}
					}
					foreach ( $agents as $agent ) :
						$phone = preg_replace( '/[^0-9]/', '', $agent['phone'] ?? '' );
						if ( empty( $phone ) ) {
							continue;
						}
						$pre_msg = $agent['message'] ?? '';
						$avatar  = $agent['avatar'] ?? '';
						$wa_url  = 'https://wa.me/' . $phone;
						if ( ! empty( $pre_msg ) ) {
							$wa_url .= '?text=' . rawurlencode( $pre_msg );
						}
						?>
						<a href="<?php echo esc_url( $wa_url ); ?>" target="_blank" rel="noopener"
						   style="display:flex;align-items:center;padding:8px;border-radius:8px;text-decoration:none;color:#333;transition:background .2s;"
						   onmouseover="this.style.background='#f0f0f0'" onmouseout="this.style.background='transparent'"
						   data-mnotif-chat-agent="<?php echo esc_attr( $phone ); ?>" data-mnotif-premsg="<?php echo esc_attr( $pre_msg ); ?>">
							<?php if ( $avatar ) : ?>
								<img src="<?php echo esc_url( $avatar ); ?>" alt="" style="width:40px;height:40px;border-radius:50%;object-fit:cover;margin-inline-end:12px;">
							<?php else : ?>
								<div style="width:40px;height:40px;border-radius:50%;background:<?php echo $color; ?>;display:flex;align-items:center;justify-content:center;margin-inline-end:12px;">
									<span style="color:#fff;font-size:16px;">&#x1F4AC;</span>
								</div>
							<?php endif; ?>
							<div>
								<div style="font-weight:500;font-size:14px;"><?php echo esc_html( $agent['name'] ?? __( 'Support', 'mersal-notifications' ) ); ?></div>
								<?php if ( ! empty( $agent['role'] ) ) : ?>
									<div style="font-size:12px;color:#999;"><?php echo esc_html( $agent['role'] ); ?></div>
								<?php endif; ?>
							</div>
						</a>
					<?php endforeach; ?>
				</div>
				<!-- Social links -->
				<?php if ( ! empty( $settings['social_links'] ) ) : ?>
					<div style="padding:8px 16px;border-top:1px solid #eee;display:flex;gap:8px;justify-content:center;flex-wrap:wrap;">
						<?php
						foreach ( $settings['social_links'] as $social ) :
							$url = $social['url'] ?? '';
							if ( empty( $url ) ) {
								continue;
							}
							$label = $social['label'] ?? '';
							?>
							<a href="<?php echo esc_url( $url ); ?>" target="_blank" rel="noopener"
							   style="color:#999;font-size:12px;text-decoration:none;"
							   data-mnotif-chat-social="<?php echo esc_attr( $label ); ?>">
								<?php echo esc_html( $label ); ?>
							</a>
						<?php endforeach; ?>
					</div>
				<?php endif; ?>
				<?php if ( ! empty( $settings['powered_by'] ) ) : ?>
					<div style="padding:6px;text-align:center;font-size:10px;color:#c2c9c5;background:#fafafa;">
						<a href="https://mersal.it" target="_blank" rel="noopener" style="color:#a8b0ab;text-decoration:none;">Powered by Mersal</a>
					</div>
				<?php endif; ?>
			</div>
			<!-- Floating button -->
			<button id="mnotif-chat-btn" type="button"
					style="width:<?php echo esc_attr( $size ); ?>px;height:<?php echo esc_attr( $size ); ?>px;border-radius:50%;background:<?php echo $color; ?>;border:none;cursor:pointer;box-shadow:0 2px 12px rgba(0,0,0,.2);display:flex;align-items:center;justify-content:center;transition:transform .2s;"
					onmouseover="this.style.transform='scale(1.05)'" onmouseout="this.style.transform='scale(1)'"
					aria-label="<?php echo esc_attr( __( 'Chat on WhatsApp', 'mersal-notifications' ) ); ?>">
				<svg width="<?php echo esc_attr( $size * 0.5 ); ?>" height="<?php echo esc_attr( $size * 0.5 ); ?>" viewBox="0 0 24 24" fill="<?php echo $icon_clr; ?>">
					<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/>
				</svg>
			</button>
		</div>
		<script>
		(function(){
			var btn=document.getElementById('mnotif-chat-btn');
			var win=document.getElementById('mnotif-chat-window');
			if(!btn||!win)return;
			var ajax=<?php echo wp_json_encode( admin_url( 'admin-ajax.php' ) ); ?>;
			var nonce=<?php echo wp_json_encode( wp_create_nonce( 'mnotif_chat' ) ); ?>;
			var incUrl=<?php echo (int) $inc_url; ?>;
			function track(type, extra){
				try{
					var fd=new FormData();
					fd.append('action','mnotif_chat_track');
					fd.append('nonce',nonce);
					fd.append('type',type);
					fd.append('page',location.pathname);
					if(extra) Object.keys(extra).forEach(function(k){ fd.append(k, extra[k]); });
					fetch(ajax,{method:'POST',body:fd,credentials:'same-origin'});
				}catch(e){}
			}
			// Impression: once per page per browser session.
			try{
				var ik='mnotif_imp_'+location.pathname;
				if(!sessionStorage.getItem(ik)){ sessionStorage.setItem(ik,'1'); track('imp'); }
			}catch(e){ track('imp'); }
			btn.addEventListener('click',function(){
				var open=win.style.display==='block';
				win.style.display=open?'none':'block';
				if(!open) track('open');
			});
			document.querySelectorAll('[data-mnotif-chat-agent]').forEach(function(el){
				if(incUrl){
					// Append the current page URL to the prefilled message so the
					// agent knows what the visitor was looking at.
					var phone=el.dataset.mnotifChatAgent;
					var msg=(el.dataset.mnotifPremsg||'');
					var text=(msg?msg+'\n':'')+location.href;
					el.href='https://wa.me/'+phone+'?text='+encodeURIComponent(text);
				}
				el.addEventListener('click',function(){ track('agent',{phone:el.dataset.mnotifChatAgent}); });
			});
			document.querySelectorAll('[data-mnotif-chat-social]').forEach(function(el){
				el.addEventListener('click',function(){ track('social',{label:el.dataset.mnotifChatSocial}); });
			});
		})();
		</script>
		<?php
	}

	/**
	 * Check if user is on mobile.
	 *
	 * @return bool
	 */
	private function is_mobile() {
		$agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '';
		return (bool) preg_match( '/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i', $agent );
	}

	/**
	 * Device / OS for analytics buckets.
	 *
	 * @return array{0:string,1:string}
	 */
	private function device_os() {
		$ua = isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '';
		$os = 'Other';
		if ( preg_match( '/android/i', $ua ) ) {
			$os = 'Android';
		} elseif ( preg_match( '/iphone|ipad|ipod/i', $ua ) ) {
			$os = 'iOS';
		} elseif ( preg_match( '/windows/i', $ua ) ) {
			$os = 'Windows';
		} elseif ( preg_match( '/macintosh/i', $ua ) ) {
			$os = 'Mac';
		} elseif ( preg_match( '/linux/i', $ua ) ) {
			$os = 'Linux';
		}
		$device = $this->is_mobile() ? ( preg_match( '/ipad/i', $ua ) ? 'Tablet' : 'Mobile' ) : 'Desktop';
		return array( $device, $os );
	}

	/**
	 * AJAX: Track chat interactions (impressions, opens, agent/social clicks).
	 * Aggregates into a bounded option: totals, last-60-days series, top
	 * agents/pages, device/OS split, hour + weekday histograms.
	 */
	public function ajax_track() {
		check_ajax_referer( 'mnotif_chat', 'nonce' );

		$type = sanitize_key( $_POST['type'] ?? '' );
		if ( ! in_array( $type, array( 'imp', 'open', 'agent', 'social' ), true ) ) {
			wp_send_json_success();
		}
		$phone = sanitize_text_field( wp_unslash( $_POST['phone'] ?? '' ) );
		$page  = sanitize_text_field( wp_unslash( $_POST['page'] ?? '' ) );
		$page  = substr( $page ? $page : '/', 0, 128 );

		// Rate limit: max ~20 events per IP per minute.
		$ip     = Mersal_Notif_Security::client_ip();
		$rl_key = 'mnotif_chat_rl_' . md5( $ip );
		$hits   = (int) get_transient( $rl_key );
		if ( $hits > 20 ) {
			wp_send_json_success();
		}
		set_transient( $rl_key, $hits + 1, MINUTE_IN_SECONDS );

		$stats = get_option( self::STATS_KEY, array() );
		if ( ! is_array( $stats ) ) {
			$stats = array();
		}
		$stats += array( 'totals' => array(), 'days' => array(), 'agents' => array(), 'pages' => array(), 'device' => array(), 'os' => array(), 'hours' => array(), 'dow' => array() );

		// Legacy counters (kept so old dashboards keep reading).
		$stats[ $type ]  = (int) ( $stats[ $type ] ?? 0 ) + 1;
		$stats['total']  = (int) ( $stats['total'] ?? 0 ) + 1;

		$stats['totals'][ $type ] = (int) ( $stats['totals'][ $type ] ?? 0 ) + 1;

		// Daily series (capped at 60 days).
		$day = current_time( 'Y-m-d' );
		if ( ! isset( $stats['days'][ $day ] ) ) {
			$stats['days'][ $day ] = array();
			if ( count( $stats['days'] ) > 60 ) {
				ksort( $stats['days'] );
				$stats['days'] = array_slice( $stats['days'], -60, null, true );
			}
		}
		$stats['days'][ $day ][ $type ] = (int) ( $stats['days'][ $day ][ $type ] ?? 0 ) + 1;

		if ( 'agent' === $type && $phone ) {
			$stats['agents'][ $phone ] = (int) ( $stats['agents'][ $phone ] ?? 0 ) + 1;
			arsort( $stats['agents'] );
			$stats['agents'] = array_slice( $stats['agents'], 0, 20, true );
		}

		// Per-page opens/clicks (impressions excluded to keep it meaningful).
		if ( 'imp' !== $type ) {
			$stats['pages'][ $page ] = (int) ( $stats['pages'][ $page ] ?? 0 ) + 1;
			arsort( $stats['pages'] );
			$stats['pages'] = array_slice( $stats['pages'], 0, 40, true );
		}

		// Device/OS/hour/weekday buckets track engagement (opens + clicks).
		if ( in_array( $type, array( 'open', 'agent' ), true ) ) {
			list( $device, $os )        = $this->device_os();
			$stats['device'][ $device ] = (int) ( $stats['device'][ $device ] ?? 0 ) + 1;
			$stats['os'][ $os ]         = (int) ( $stats['os'][ $os ] ?? 0 ) + 1;
			$hour                       = (int) current_time( 'G' );
			$dow                        = (int) current_time( 'w' );
			$stats['hours'][ $hour ]    = (int) ( $stats['hours'][ $hour ] ?? 0 ) + 1;
			$stats['dow'][ $dow ]       = (int) ( $stats['dow'][ $dow ] ?? 0 ) + 1;
		}

		update_option( self::STATS_KEY, $stats, false );
		wp_send_json_success();
	}

	/**
	 * Read analytics for the admin page.
	 *
	 * @return array
	 */
	public static function get_stats() {
		$stats = get_option( self::STATS_KEY, array() );
		return is_array( $stats ) ? $stats : array();
	}

	/**
	 * AJAX: save widget settings (admin).
	 */
	public function ajax_save_widget() {
		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.
		$in  = wp_unslash( $_POST );
		$out = array(
			'button_color'     => sanitize_hex_color( $in['button_color'] ?? '' ) ?: '#25D366',
			'icon_color'       => sanitize_hex_color( $in['icon_color'] ?? '' ) ?: '#ffffff',
			'position'         => ( 'left' === ( $in['position'] ?? '' ) ) ? 'left' : 'right',
			'button_size'      => (string) max( 40, min( 90, (int) ( $in['button_size'] ?? 60 ) ) ),
			'bottom_offset'    => (string) max( 0, min( 200, (int) ( $in['bottom_offset'] ?? 24 ) ) ),
			'corner_radius'    => (string) max( 0, min( 32, (int) ( $in['corner_radius'] ?? 12 ) ) ),
			'show_desktop'     => empty( $in['show_desktop'] ) ? 0 : 1,
			'show_mobile'      => empty( $in['show_mobile'] ) ? 0 : 1,
			'powered_by'       => empty( $in['powered_by'] ) ? 0 : 1,
			'include_page_url' => empty( $in['include_page_url'] ) ? 0 : 1,
			'header_title'     => sanitize_text_field( $in['header_title'] ?? '' ),
			'welcome_msg'      => sanitize_text_field( $in['welcome_msg'] ?? '' ),
			'reply_time'       => sanitize_text_field( $in['reply_time'] ?? '' ),
			'excluded_pages'   => implode( ',', array_filter( array_map( 'absint', preg_split( '/[\s,]+/', (string) ( $in['excluded_pages'] ?? '' ) ) ) ) ),
			'agents'           => array(),
			'social_links'     => array(),
		);

		if ( ! empty( $in['agents'] ) && is_array( $in['agents'] ) ) {
			foreach ( $in['agents'] as $agent ) {
				if ( ! is_array( $agent ) ) {
					continue;
				}
				$phone = preg_replace( '/[^0-9]/', '', (string) ( $agent['phone'] ?? '' ) );
				if ( '' === $phone ) {
					continue;
				}
				$out['agents'][] = array(
					'name'    => sanitize_text_field( $agent['name'] ?? '' ),
					'phone'   => $phone,
					'role'    => sanitize_text_field( $agent['role'] ?? '' ),
					'message' => sanitize_textarea_field( $agent['message'] ?? '' ),
					'avatar'  => esc_url_raw( $agent['avatar'] ?? '' ),
				);
			}
		}
		if ( ! empty( $in['social_links'] ) && is_array( $in['social_links'] ) ) {
			foreach ( $in['social_links'] as $social ) {
				if ( ! is_array( $social ) || empty( $social['url'] ) ) {
					continue;
				}
				$out['social_links'][] = array(
					'label' => sanitize_text_field( $social['label'] ?? '' ),
					'url'   => esc_url_raw( $social['url'] ),
				);
			}
		}

		update_option( self::SETTINGS_KEY, $out, false );
		wp_send_json_success( array( 'message' => __( 'Widget settings saved.', 'mersal-notifications' ) ) );
	}
}
