<?php
/**
 * Lightweight wp_mail() identity + activity logger.
 *
 * Lets the admin configure From name, From email, Reply-To and optionally
 * force these identities on every outgoing email. Also captures the last 100
 * wp_mail() attempts (excluding sends that were handed off to Brevo) so the
 * admin can diagnose deliverability issues.
 *
 * Brevo's own send activity is still recorded under its own log, so the two
 * sections in the Email tab stay distinct: wp_mail() native path vs. Brevo.
 *
 * @package TradeSchoolManager
 */

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

class TSMP_Mail {

	const OPTION     = 'tsmp_mail_settings';
	const LOG_OPTION = 'tsmp_mail_log';
	const LOG_MAX    = 100;

	private static $current = null; // request-scoped: pointer to most recent log row.

	public static function defaults() {
		return array(
			'from_name'    => get_bloginfo( 'name' ),
			'from_email'   => get_bloginfo( 'admin_email' ),
			'reply_to'     => '',
			'force_sender' => 0,
			'log_enabled'  => 1,
		);
	}

	public static function get_all() {
		return wp_parse_args( get_option( self::OPTION, array() ), self::defaults() );
	}

	public static function update( $data ) {
		$merged = array_merge( self::get_all(), $data );
		update_option( self::OPTION, $merged );
		return $merged;
	}

	public static function init() {
		// From identity  -  priority 5 sets a default; 99 forces it if requested.
		add_filter( 'wp_mail_from',      array( __CLASS__, 'apply_from_email' ), 5 );
		add_filter( 'wp_mail_from_name', array( __CLASS__, 'apply_from_name' ), 5 );
		add_filter( 'wp_mail_from',      array( __CLASS__, 'apply_from_email_force' ), 99 );
		add_filter( 'wp_mail_from_name', array( __CLASS__, 'apply_from_name_force' ), 99 );

		// Inject Reply-To header when configured (and not already present).
		add_filter( 'wp_mail', array( __CLASS__, 'inject_reply_to_and_log' ), 1 );

		add_action( 'wp_mail_succeeded', array( __CLASS__, 'mark_succeeded' ), 10, 1 );
		add_action( 'wp_mail_failed',    array( __CLASS__, 'mark_failed' ), 10, 1 );
	}

	public static function apply_from_email( $email ) {
		$s = self::get_all();
		if ( ! empty( $s['from_email'] ) && is_email( $s['from_email'] ) ) { return $s['from_email']; }
		return $email;
	}
	public static function apply_from_name( $name ) {
		$s = self::get_all();
		return ! empty( $s['from_name'] ) ? $s['from_name'] : $name;
	}
	public static function apply_from_email_force( $email ) {
		$s = self::get_all();
		if ( empty( $s['force_sender'] ) ) { return $email; }
		if ( ! empty( $s['from_email'] ) && is_email( $s['from_email'] ) ) { return $s['from_email']; }
		return $email;
	}
	public static function apply_from_name_force( $name ) {
		$s = self::get_all();
		if ( empty( $s['force_sender'] ) ) { return $name; }
		return ! empty( $s['from_name'] ) ? $s['from_name'] : $name;
	}

	public static function inject_reply_to_and_log( $atts ) {
		$s = self::get_all();

		// Reply-To injection.
		if ( ! empty( $s['reply_to'] ) && is_email( $s['reply_to'] ) ) {
			$headers = isset( $atts['headers'] ) ? $atts['headers'] : array();
			if ( ! is_array( $headers ) ) {
				$headers = preg_split( "/\r\n|\n|\r/", (string) $headers ) ?: array();
			}
			$has_reply = false;
			foreach ( $headers as $h ) {
				if ( is_string( $h ) && stripos( $h, 'reply-to:' ) === 0 ) { $has_reply = true; break; }
			}
			if ( ! $has_reply ) {
				$headers[] = 'Reply-To: ' . $s['reply_to'];
				$atts['headers'] = $headers;
			}
		}

		// Log attempt (skip if Brevo will handle it  -  Brevo logs its own activity).
		if ( ! empty( $s['log_enabled'] ) && ! self::is_brevo_taking_over() ) {
			self::record_pending( $atts );
		}
		return $atts;
	}

	private static function is_brevo_taking_over() {
		if ( ! class_exists( 'TSMP_Brevo' ) ) { return false; }
		if ( ! TSMP_Brevo::is_configured() ) { return false; }
		if ( method_exists( 'TSMP_Brevo', 'cap_reached' ) && TSMP_Brevo::cap_reached() ) { return false; }
		return true;
	}

	private static function record_pending( $atts ) {
		$log = get_option( self::LOG_OPTION, array() );
		if ( ! is_array( $log ) ) { $log = array(); }
		$row = array(
			'time'    => current_time( 'mysql' ),
			'to'      => is_string( $atts['to'] ?? '' ) ? $atts['to'] : wp_json_encode( $atts['to'] ?? '' ),
			'subject' => (string) ( $atts['subject'] ?? '' ),
			'status'  => 'pending',
			'detail'  => '',
		);
		array_unshift( $log, $row );
		if ( count( $log ) > self::LOG_MAX ) { $log = array_slice( $log, 0, self::LOG_MAX ); }
		update_option( self::LOG_OPTION, $log, false );
		self::$current = 0; // index of the row we just inserted.
	}

	public static function mark_succeeded( $mail_data ) { self::finalize( true, '' ); }
	public static function mark_failed( $error ) {
		$msg = ( $error instanceof WP_Error ) ? $error->get_error_message() : (string) $error;
		self::finalize( false, $msg );
	}

	private static function finalize( $ok, $detail ) {
		if ( null === self::$current ) { return; }
		$log = get_option( self::LOG_OPTION, array() );
		if ( ! is_array( $log ) || ! isset( $log[ self::$current ] ) ) { self::$current = null; return; }
		$log[ self::$current ]['status'] = $ok ? 'sent' : 'failed';
		$log[ self::$current ]['detail'] = mb_substr( (string) $detail, 0, 400 );
		update_option( self::LOG_OPTION, $log, false );
		self::$current = null;
	}

	public static function get_log() {
		$log = get_option( self::LOG_OPTION, array() );
		return is_array( $log ) ? $log : array();
	}

	public static function clear_log() { delete_option( self::LOG_OPTION ); }

	public static function send_test( $to ) {
		if ( ! is_email( $to ) ) { return new WP_Error( 'bad_email', __( 'Invalid recipient email.', 'tradeschool-manager' ) ); }
		/* translators: %s = site name */
		$subject = sprintf( __( '[Test] %s  -  wp_mail() delivery test', 'tradeschool-manager' ), get_bloginfo( 'name' ) );
		$body    = "This is a test email from TradeSchool Manager sent via wp_mail().\n\n"
		         . "If it arrives, your server (or your SMTP plugin) is delivering mail correctly.\n\n -  "
		         . get_bloginfo( 'name' );
		$ok = wp_mail( $to, $subject, $body );
		return $ok ? true : new WP_Error( 'send_fail', __( 'wp_mail() returned false. Check the log below for the error message.', 'tradeschool-manager' ) );
	}
}
