<?php
/**
 * ReportSender
 *
 * Schedules and sends the periodic email report via wp_mail.
 *
 * @package Relatedly\Admin\Email
 * @since   2.0.0
 */

namespace Relatedly\Admin\Email;

use Relatedly\Core\Options;
use Relatedly\Core\Cache;
use Relatedly\Premium\FeatureGate;

defined( 'ABSPATH' ) || exit;

/**
 * Schedules and sends Relatedly email reports.
 *
 * @since 2.0.0
 */
class ReportSender {

	/**
	 * Plugin settings repository.
	 *
	 * @since 2.0.0
	 * @var Options
	 */
	private Options $options;

	/**
	 * Cache service.
	 *
	 * @since 2.0.0
	 * @var Cache
	 */
	private Cache $cache;

	/**
	 * Create the report sender.
	 *
	 * @since 2.0.0
	 * @param Options $options Plugin settings repository.
	 * @param Cache   $cache   Cache service.
	 */
	public function __construct( Options $options, Cache $cache ) {
		$this->options = $options;
		$this->cache   = $cache;
	}

	/**
	 * Register report scheduling hooks.
	 *
	 * @since 2.0.0
	 */
	public function init_hooks(): void {
		add_action( 'relatedly_scheduled_email_report', [ $this, 'send' ] );
		add_action( 'relatedly_settings_saved', [ $this, 'reschedule' ] );
		add_action( 'init', [ $this, 'maybe_schedule' ] );
	}

	/**
	 * Ensure a cron event exists when reports are enabled.
	 *
	 * @since 2.0.0
	 */
	public function maybe_schedule(): void {
		if ( ! FeatureGate::can_use_email_reports() ) {
			return;
		}

		if ( ! $this->options->get( 'email_reports_enabled', false ) ) {
			return;
		}

		if ( wp_next_scheduled( 'relatedly_scheduled_email_report' ) ) {
			return;
		}

		$this->reschedule();
	}

	/**
	 * Send the report to all configured recipients.
	 *
	 * @since 2.0.0
	 */
	public function send(): void {
		if ( ! FeatureGate::can_use_email_reports() ) {
			return;
		}

		if ( ! $this->options->get( 'email_reports_enabled', false ) ) {
			return;
		}

		$recipients = (array) $this->options->get( 'email_reports_recipients', [] );
		$recipients = array_filter( array_map( 'sanitize_email', $recipients ) );

		if ( empty( $recipients ) ) {
			return;
		}

		$generator = new ReportGenerator( $this->options, $this->cache );
		$body      = $generator->build();

		if ( '' === trim( $body ) ) {
			return;
		}

		$subject = sprintf(
			/* translators: %s: site name */
			__( 'Relatedly Report — %s', 'relatedly' ),
			get_bloginfo( 'name' )
		);

		add_filter( 'wp_mail_content_type', [ $this, 'set_html_content_type' ] );

		foreach ( $recipients as $email ) {
			wp_mail( $email, $subject, $body );
		}

		remove_filter( 'wp_mail_content_type', [ $this, 'set_html_content_type' ] );
	}

	/**
	 * Return the HTML content type for report emails.
	 *
	 * @since 2.0.0
	 */
	public function set_html_content_type(): string {
		return 'text/html';
	}

	/**
	 * Reschedule the cron event when settings are saved.
	 *
	 * @since 2.0.0
	 */
	public function reschedule(): void {
		$timestamp = wp_next_scheduled( 'relatedly_scheduled_email_report' );
		if ( $timestamp ) {
			wp_unschedule_event( $timestamp, 'relatedly_scheduled_email_report' );
		}

		if ( ! FeatureGate::can_use_email_reports() ) {
			return;
		}

		if ( ! $this->options->get( 'email_reports_enabled', false ) ) {
			return;
		}

		$frequency  = (string) $this->options->get( 'email_reports_frequency', 'weekly' );
		$recurrence = ( 'monthly' === $frequency ) ? 'monthly' : 'weekly';

		wp_schedule_event( time(), $recurrence, 'relatedly_scheduled_email_report' );
	}
}
