<?php
/**
 * Email notifications.
 *
 * @package TrustLens
 * @since   1.0.0
 */

defined( 'ABSPATH' ) || exit;

/**
 * Notifications class.
 *
 * Sends email alerts for trust events (blocked checkout, welcome summary, weekly summary).
 * Pro notifications (high-risk, velocity, chargeback, etc.) live in class-notifications-pro.php
 * and are excluded from the WordPress.org free build via @fs_premium_only.
 *
 * @since 1.0.0
 */
class TrustLens_Notifications {

	/**
	 * Last mail error captured by the shared send wrapper.
	 *
	 * @var string
	 */
	protected string $last_send_error = '';

	/**
	 * Single instance.
	 *
	 * @var TrustLens_Notifications|null
	 */
	private static ?TrustLens_Notifications $instance = null;

	/**
	 * Get instance.
	 *
	 * @since 1.0.0
	 * @return TrustLens_Notifications
	 */
	public static function instance(): TrustLens_Notifications {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 */
	private function __construct() {
		$this->init_hooks();
	}

	/**
	 * Initialize hooks.
	 *
	 * @since 1.0.0
	 */
	private function init_hooks(): void {
		// === Free notifications (always available) ===

		// Blocked checkout alert.
		add_action( 'trustlens/checkout_blocked', array( $this, 'notify_blocked_checkout' ), 10, 2 );

		// Welcome summary (one-time, scheduled on activation).
		add_action( 'trustlens/welcome_summary', array( $this, 'send_welcome_summary' ) );

		// Weekly free summary (scheduled weekly).
		add_action( 'trustlens/weekly_summary', array( $this, 'send_weekly_summary' ) );
	}

	// =========================================================================
	// Free Notifications
	// =========================================================================

	/**
	 * Notify admin of blocked checkout attempt.
	 *
	 * @since 1.0.0
	 * @param string $email_hash Customer email hash.
	 * @param string $email      Customer email.
	 */
	public function notify_blocked_checkout( string $email_hash, string $email ): void {
		if ( ! get_option( 'trustlens_enable_notifications', false ) || ! get_option( 'trustlens_notify_blocked_checkout', true ) ) {
			return;
		}

		$customer = wstl_get_customer( $email_hash );
		$this->send_blocked_checkout_alert( $email, $customer );
	}

	/**
	 * Send welcome summary email.
	 *
	 * One-time email sent 24 hours after plugin activation with scan results.
	 *
	 * @since 1.1.0
	 */
	public function send_welcome_summary(): void {
		// One-time onboarding — gated only by its own opt-out, not by the
		// master notifications switch (which defaults to off and would
		// otherwise silently drop the welcome email on every fresh install).
		if ( ! get_option( 'trustlens_notify_welcome_summary', true ) ) {
			return;
		}

		// Only send once.
		if ( get_option( 'trustlens_welcome_summary_sent', false ) ) {
			return;
		}

		$repo   = new TrustLens_Customer_Repository();
		$counts = $repo->get_segment_counts();
		$total  = array_sum( $counts );

		if ( 0 === $total ) {
			return;
		}

		$risk_count = ( $counts['risk'] ?? 0 ) + ( $counts['critical'] ?? 0 );

		$to      = $this->get_notification_email();
		$subject = sprintf(
			/* translators: %1$d: total customers, %2$s: site name */
			__( '[TrustLens] Welcome: %1$d Customers Scanned on %2$s', 'trustlens' ),
			$total,
			get_bloginfo( 'name' )
		);

		$message = $this->get_email_header( __( 'Welcome to TrustLens', 'trustlens' ) );

		$message .= '<p>' . sprintf(
			/* translators: %d: total customers */
			__( 'TrustLens has finished scanning your customer base. Here\'s what we found across %d customers:', 'trustlens' ),
			$total
		) . '</p>';

		$message .= '<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">';
		$message .= $this->get_table_row( __( 'VIP', 'trustlens' ), number_format( $counts['vip'] ?? 0 ), '#28a745' );
		$message .= $this->get_table_row( __( 'Trusted', 'trustlens' ), number_format( $counts['trusted'] ?? 0 ), '#17a2b8' );
		$message .= $this->get_table_row( __( 'Normal', 'trustlens' ), number_format( $counts['normal'] ?? 0 ), '#6c757d' );
		$message .= $this->get_table_row( __( 'Caution', 'trustlens' ), number_format( $counts['caution'] ?? 0 ), '#ffc107' );
		$message .= $this->get_table_row( __( 'Risk', 'trustlens' ), number_format( $counts['risk'] ?? 0 ), '#fd7e14' );
		$message .= $this->get_table_row( __( 'Critical', 'trustlens' ), number_format( $counts['critical'] ?? 0 ), '#dc3545' );
		$message .= '</table>';

		if ( $risk_count > 0 ) {
			$message .= '<p style="background: #fff3cd; padding: 12px 15px; border-radius: 4px; border-left: 4px solid #ffc107;">';
			$message .= sprintf(
				/* translators: %d: number of high-risk customers */
				__( '%d customers require your attention. Visit the TrustLens dashboard to review them.', 'trustlens' ),
				$risk_count
			);
			$message .= '</p>';
		}

		$message .= '<p style="margin-top: 20px;">';
		$message .= '<a href="' . esc_url( admin_url( 'admin.php?page=trustlens' ) ) . '" style="background: #2271b1; color: #fff; padding: 10px 20px; text-decoration: none; border-radius: 3px;">' . __( 'View Dashboard', 'trustlens' ) . '</a>';
		$message .= '</p>';

		$message .= $this->get_email_footer();

		if ( $this->send( $to, $subject, $message, 'welcome_summary' ) ) {
			update_option( 'trustlens_welcome_summary_sent', true );
		}
	}

	/**
	 * Send weekly free summary email.
	 *
	 * Aggregates weekly stats: orders held, checkouts blocked, money protected.
	 *
	 * @since 1.1.0
	 */
	public function send_weekly_summary(): void {
		if ( ! get_option( 'trustlens_enable_notifications', false ) || ! get_option( 'trustlens_notify_weekly_summary', true ) ) {
			return;
		}

		global $wpdb;

		$events_table = $wpdb->prefix . 'trustlens_events';
		$automation_logs = $wpdb->prefix . 'trustlens_automation_logs';
		// Anchor the 7-day window to WP-local time: both tables store created_at with
		// current_time( 'mysql' ), so a UTC strtotime() base skewed it by the site offset.
		$week_ago = gmdate( 'Y-m-d H:i:s', current_time( 'timestamp' ) - 7 * DAY_IN_SECONDS );

		// Count events from the past week.
		// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Aggregation query on internal table.
		$blocked_count = (int) $wpdb->get_var( $wpdb->prepare(
			"SELECT COUNT(*) FROM {$events_table} WHERE event_type = 'checkout_blocked' AND created_at >= %s",
			$week_ago
		) );

		$held_count = (int) $wpdb->get_var( $wpdb->prepare(
			"SELECT COUNT(*) FROM {$automation_logs} WHERE action_type = 'hold_order' AND status = 'ok' AND created_at >= %s",
			$week_ago
		) );
		// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter

		$repo   = new TrustLens_Customer_Repository();
		$counts = $repo->get_segment_counts();

		$risk_count = ( $counts['risk'] ?? 0 ) + ( $counts['critical'] ?? 0 );

		// Skip if nothing happened.
		if ( 0 === $blocked_count && 0 === $held_count && 0 === $risk_count ) {
			return;
		}

		$to      = $this->get_notification_email();
		$subject = sprintf(
			/* translators: %s: site name */
			__( '[TrustLens] Weekly Summary for %s', 'trustlens' ),
			get_bloginfo( 'name' )
		);

		$message = $this->get_email_header( __( 'Weekly Trust Summary', 'trustlens' ) );

		$message .= '<p>' . __( 'Here\'s your weekly TrustLens activity summary:', 'trustlens' ) . '</p>';

		$message .= '<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">';
		$message .= $this->get_table_row( __( 'Orders Held for Review', 'trustlens' ), number_format( $held_count ) );
		$message .= $this->get_table_row( __( 'Checkouts Blocked', 'trustlens' ), number_format( $blocked_count ) );
		$message .= $this->get_table_row( __( 'High-Risk Customers', 'trustlens' ), number_format( $risk_count ), '#dc3545' );
		$message .= $this->get_table_row( __( 'Total Tracked Customers', 'trustlens' ), number_format( array_sum( $counts ) ) );
		$message .= '</table>';

		$message .= '<p style="margin-top: 20px;">';
		$message .= '<a href="' . esc_url( admin_url( 'admin.php?page=trustlens' ) ) . '" style="background: #2271b1; color: #fff; padding: 10px 20px; text-decoration: none; border-radius: 3px;">' . __( 'View Dashboard', 'trustlens' ) . '</a>';
		$message .= '</p>';

		if ( wstl_show_pro_upsells() ) {
			$upgrade_url = wstl_get_upgrade_or_fallback_url();
			if ( $upgrade_url ) {
				$message .= '<div style="background: #f5f0f9; padding: 15px; border-radius: 4px; border-left: 4px solid #8e44ad; margin-top: 20px;">';
				$message .= '<p style="margin: 0; font-size: 13px; color: #555;">';
				$message .= '<strong>' . __( 'Upgrade to Pro', 'trustlens' ) . '</strong> &mdash; ';
				$message .= __( 'Get real-time alerts for high-risk orders, velocity detection, chargeback notifications, and more.', 'trustlens' );
				$message .= ' <a href="' . esc_url( $upgrade_url ) . '" style="color: #8e44ad;">' . __( 'See Pro features & pricing', 'trustlens' ) . ' &rarr;</a>';
				$message .= '</p></div>';
			}
		}

		$message .= $this->get_email_footer();

		$this->send( $to, $subject, $message );
	}

	// =========================================================================
	// Email Builders (Private)
	// =========================================================================

	/**
	 * Send blocked checkout alert.
	 *
	 * @since 1.0.0
	 * @param string      $email    Customer email.
	 * @param object|null $customer Customer object or null.
	 */
	private function send_blocked_checkout_alert( string $email, ?object $customer ): void {
		$to      = $this->get_notification_email();
		$subject = sprintf(
			/* translators: %s: site name */
			__( '[TrustLens] Blocked Checkout Attempt on %s', 'trustlens' ),
			get_bloginfo( 'name' )
		);

		$message = $this->get_email_header( __( 'Blocked Checkout Attempt', 'trustlens' ) );

		$message .= '<p>' . sprintf(
			/* translators: %s: customer email */
			__( 'A blocked customer (%s) attempted to checkout but was prevented.', 'trustlens' ),
			'<strong>' . esc_html( $email ) . '</strong>'
		) . '</p>';

		if ( $customer ) {
			$message .= '<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">';
			$message .= $this->get_table_row( __( 'Trust Score', 'trustlens' ), $customer->trust_score . '/100' );
			$message .= $this->get_table_row( __( 'Segment', 'trustlens' ), wstl_get_segment_label( $customer->segment ) );
			$message .= $this->get_table_row( __( 'Return Rate', 'trustlens' ), number_format( $customer->return_rate, 1 ) . '%' );
			$message .= $this->get_table_row( __( 'Total Refunded', 'trustlens' ), wp_strip_all_tags( wc_price( $customer->total_refund_value ) ) );
			$message .= '</table>';

			$message .= '<p style="margin-top: 20px;">';
			$message .= '<a href="' . esc_url( admin_url( 'admin.php?page=trustlens-customers&customer=' . $customer->email_hash ) ) . '" style="background: #2271b1; color: #fff; padding: 10px 20px; text-decoration: none; border-radius: 3px;">' . __( 'View Customer', 'trustlens' ) . '</a>';
			$message .= '</p>';
		}

		$message .= $this->get_email_footer();

		$this->send( $to, $subject, $message );
	}

	// =========================================================================
	// Utilities
	// =========================================================================

	/**
	 * Get notification email address.
	 *
	 * @since 1.0.0
	 * @return string Email address.
	 */
	public function get_notification_email(): string {
		$email = get_option( 'trustlens_notification_email', '' );

		$email = is_email( $email ) ? $email : '';

		if ( empty( $email ) ) {
			$admin_email = get_option( 'admin_email' );
			$email       = is_email( $admin_email ) ? $admin_email : '';
		}

		return $email;
	}

	/**
	 * Get email header HTML.
	 *
	 * @since 1.0.0
	 * @param string $title Email title.
	 * @return string HTML.
	 */
	protected function get_email_header( string $title ): string {
		$html  = '<!DOCTYPE html><html><head><meta charset="UTF-8"></head><body style="font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif; font-size: 14px; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px;">';
		$html .= '<div style="background: linear-gradient(135deg, #2271b1, #135e96); padding: 20px; border-radius: 5px 5px 0 0;">';
		$html .= '<h1 style="margin: 0; color: #fff; font-size: 24px;">' . esc_html( $title ) . '</h1>';
		$html .= '</div>';
		$html .= '<div style="background: #fff; padding: 20px; border: 1px solid #ddd; border-top: none; border-radius: 0 0 5px 5px;">';
		return $html;
	}

	/**
	 * Get email footer HTML.
	 *
	 * @since 1.0.0
	 * @return string HTML.
	 */
	protected function get_email_footer(): string {
		$html  = '</div>';
		$html .= '<p style="margin-top: 20px; font-size: 12px; color: #666; text-align: center;">';
		$html .= sprintf(
			/* translators: %s: site name */
			__( 'This email was sent by TrustLens on %s', 'trustlens' ),
			get_bloginfo( 'name' )
		);
		$html .= '</p>';
		$html .= '</body></html>';
		return $html;
	}

	/**
	 * Get table row HTML.
	 *
	 * @since 1.0.0
	 * @param string $label Label.
	 * @param string $value Value.
	 * @param string $color Optional color.
	 * @return string HTML.
	 */
	protected function get_table_row( string $label, string $value, string $color = '' ): string {
		$style = 'padding: 10px; border-bottom: 1px solid #eee;';
		if ( $color ) {
			$style .= ' color: ' . $color . '; font-weight: bold;';
		}

		return '<tr><td style="padding: 10px; border-bottom: 1px solid #eee; color: #666;">' . esc_html( $label ) . '</td><td style="' . $style . '">' . $value . '</td></tr>';
	}

	/**
	 * Send email.
	 *
	 * @since 1.0.0
	 * @param string $to      Recipient email.
	 * @param string $subject Email subject.
	 * @param string $message Email body (HTML).
	 * @return bool Whether email was sent.
	 */
	protected function send( string $to, string $subject, string $message, string $context = 'notification' ): bool {
		$result                = wstl_send_mail(
			$to,
			$subject,
			$message,
			array(),
			array( 'context' => $context )
		);
		$this->last_send_error = $result['error'] ?? '';

		return ! empty( $result['success'] );
	}

	/**
	 * Get the last send error from the shared mailer.
	 *
	 * @since 1.1.5
	 * @return string
	 */
	public function get_last_send_error(): string {
		return $this->last_send_error;
	}
}
