<?php
/**
 * Email Handler - Sends donation-related emails
 *
 * @package SureDonation
 */

namespace SureDonation\Inc\Emails;

use SureDonation\Inc\Helper;
use SureDonation\Inc\Payments\Payment_Helper;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Email_Handler class.
 *
 * @since 0.0.1
 */
class Email_Handler {
	/**
	 * Option key for email notifications within consolidated options.
	 *
	 * @since 0.0.1
	 */
	public const OPTION_KEY = 'email_notifications';

	/**
	 * Send donation confirmation email to donor.
	 *
	 * @param int                  $donation_id   Donation ID.
	 * @param int                  $campaign_id   Campaign ID.
	 * @param array<string, mixed> $donation_data Donation data array.
	 * @return bool True if email was sent successfully.
	 * @since 0.0.1
	 */
	public static function send_donation_confirmation( $donation_id, $campaign_id, $donation_data ) {
		$notification = self::get_notification( 'donation_receipt' );

		if ( ! $notification ) {
			return false;
		}

		// Check if donor email is available.
		$donor_email = isset( $donation_data['donor_email'] ) && is_string( $donation_data['donor_email'] ) ? $donation_data['donor_email'] : '';
		if ( empty( $donor_email ) || ! is_email( $donor_email ) ) {
			return false;
		}

		// Get campaign data.
		$campaign = get_post( $campaign_id );
		if ( ! $campaign ) {
			return false;
		}

		// Send donor receipt email.
		$sent = self::send_email(
			$donor_email,
			$notification,
			$donation_data,
			$campaign,
			$donation_id
		);

		// Also send admin notification if enabled.
		self::send_admin_new_donation( $donation_id, $campaign_id, $donation_data );

		return $sent;
	}

	/**
	 * Send new donation notification to admin.
	 *
	 * @param int                  $donation_id   Donation ID.
	 * @param int                  $campaign_id   Campaign ID.
	 * @param array<string, mixed> $donation_data Donation data array.
	 * @return bool True if email was sent successfully.
	 * @since 0.0.1
	 */
	public static function send_admin_new_donation( $donation_id, $campaign_id, $donation_data ) {
		$notification = self::get_notification( 'admin_new_donation' );

		if ( ! $notification ) {
			return false;
		}

		// Get campaign data.
		$campaign = get_post( $campaign_id );
		if ( ! $campaign ) {
			return false;
		}

		// Send to admin email.
		$admin_email = get_option( 'admin_email' );
		$admin_email = is_string( $admin_email ) ? $admin_email : '';

		return self::send_email(
			$admin_email,
			$notification,
			$donation_data,
			$campaign,
			$donation_id
		);
	}

	/**
	 * Get notification settings by type.
	 *
	 * @param string $notification_type Notification type key.
	 * @return array<string, mixed>|false Notification settings or false if not found/disabled.
	 * @since 0.0.1
	 */
	private static function get_notification( $notification_type ) {
		$notifications = Helper::get_suredonation_option( self::OPTION_KEY, [] );

		// Ensure notifications is an array before accessing offsets.
		if ( ! is_array( $notifications ) || empty( $notifications[ $notification_type ] ) ) {
			return false;
		}

		$notification = $notifications[ $notification_type ];

		// Ensure notification is an array before accessing offsets.
		if ( ! is_array( $notification ) ) {
			return false;
		}

		// Check if enabled.
		if ( empty( $notification['enabled'] ) ) {
			return false;
		}

		return $notification;
	}

	/**
	 * Send email using notification settings.
	 *
	 * @param string               $to_email      Recipient email address.
	 * @param array<string, mixed> $notification  Notification settings.
	 * @param array<string, mixed> $donation_data Donation data for smart tags.
	 * @param \WP_Post             $campaign      Campaign post object.
	 * @param int                  $donation_id   Optional donation ID.
	 * @return bool True if email was sent successfully.
	 * @since 0.0.1
	 */
	private static function send_email( $to_email, $notification, $donation_data, $campaign, $donation_id = 0 ) {
		if ( empty( $to_email ) || ! is_email( $to_email ) ) {
			return false;
		}

		// Prepare email data - ensure string types for process_smart_tags.
		$subject_raw    = isset( $notification['subject'] ) && is_string( $notification['subject'] ) ? $notification['subject'] : '';
		$email_body_raw = isset( $notification['email_body'] ) && is_string( $notification['email_body'] ) ? $notification['email_body'] : '';
		$subject        = self::process_smart_tags( $subject_raw, $donation_data, $campaign );
		$email_body     = self::process_smart_tags( $email_body_raw, $donation_data, $campaign );

		// Get from name and email - ensure string types.
		$from_name_raw = isset( $notification['from_name'] ) && is_string( $notification['from_name'] ) ? $notification['from_name'] : '';
		$from_name     = ! empty( $from_name_raw ) ? $from_name_raw : get_bloginfo( 'name' );
		$from_email    = isset( $notification['from_email'] ) && is_string( $notification['from_email'] ) && ! empty( $notification['from_email'] )
			? $notification['from_email']
			: get_option( 'admin_email' );
		$reply_to      = isset( $notification['reply_to'] ) && is_string( $notification['reply_to'] ) && ! empty( $notification['reply_to'] )
			? $notification['reply_to']
			: ( is_string( $from_email ) ? $from_email : '' );

		// Process smart tags in from fields.
		$from_name = self::process_smart_tags( is_string( $from_name ) ? $from_name : '', $donation_data, $campaign );

		// Ensure from_email and reply_to are strings.
		$from_email = is_string( $from_email ) ? $from_email : '';
		$reply_to   = is_string( $reply_to ) ? $reply_to : '';

		// Set email headers.
		$headers = [
			'Content-Type: text/html; charset=UTF-8',
			sprintf( 'From: %s <%s>', $from_name, $from_email ),
			sprintf( 'Reply-To: %s', $reply_to ),
		];

		// Convert plain text to HTML if needed.
		$email_body = self::format_email_body( $email_body );

		// Send email.
		$sent = wp_mail( $to_email, $subject, $email_body, $headers );

		// Log email send attempt.
		$notification_id = isset( $notification['id'] ) && is_string( $notification['id'] ) ? $notification['id'] : '';
		do_action( 'suredonation_email_sent', $donation_id, $to_email, $sent, $notification_id );

		return $sent;
	}

	/**
	 * Process smart tags in email content.
	 *
	 * @param string               $content       Content with smart tags.
	 * @param array<string, mixed> $donation_data Donation data.
	 * @param \WP_Post             $campaign      Campaign post object.
	 * @return string Processed content.
	 * @since 0.0.1
	 */
	private static function process_smart_tags( $content, $donation_data, $campaign ) {
		// Get currency symbol - ensure string type.
		$currency = isset( $donation_data['currency'] ) && is_string( $donation_data['currency'] ) ? $donation_data['currency'] : 'USD';

		// Calculate total amount (base + fees) - ensure numeric types.
		$amount_value       = $donation_data['amount'] ?? 0;
		$fees_covered_value = $donation_data['fees_covered'] ?? 0;
		$base_amount        = is_numeric( $amount_value ) ? (float) $amount_value : 0.0;
		$fees_covered       = is_numeric( $fees_covered_value ) ? (float) $fees_covered_value : 0.0;
		$total_amount       = $base_amount + $fees_covered;

		// Format amounts with currency symbol.
		$formatted_amount = Payment_Helper::format_amount( $total_amount, $currency );

		// Get date format - ensure string type.
		$date_format = get_option( 'date_format' );
		$date_format = is_string( $date_format ) ? $date_format : 'Y-m-d';

		// Smart tags mapping.
		$donor_name     = isset( $donation_data['donor_name'] ) && is_string( $donation_data['donor_name'] ) ? $donation_data['donor_name'] : __( 'Donor', 'suredonation' );
		$donor_email    = isset( $donation_data['donor_email'] ) && is_string( $donation_data['donor_email'] ) ? $donation_data['donor_email'] : '';
		$transaction_id = isset( $donation_data['transaction_id'] ) && is_string( $donation_data['transaction_id'] ) ? $donation_data['transaction_id'] : '';
		if ( empty( $transaction_id ) && isset( $donation_data['id'] ) ) {
			$transaction_id = is_scalar( $donation_data['id'] ) ? (string) $donation_data['id'] : '';
		}

		$tags = [
			'{donor_name}'     => $donor_name,
			'{donor_email}'    => $donor_email,
			'{amount}'         => $formatted_amount,
			'{campaign_name}'  => $campaign->post_title,
			'{donation_date}'  => current_time( $date_format ),
			'{transaction_id}' => $transaction_id,
			'{site_title}'     => get_bloginfo( 'name' ),
			'{admin_email}'    => get_option( 'admin_email' ),
			'{site_url}'       => home_url(),
			'{admin_url}'      => admin_url( 'admin.php?page=suredonation' ),
		];

		// Apply filters to allow adding custom smart tags.
		$tags = apply_filters( 'suredonation_email_smart_tags', $tags, $donation_data, $campaign );

		// Replace smart tags.
		return str_replace( array_keys( $tags ), array_values( $tags ), $content );
	}

	/**
	 * Format email body with HTML wrapper.
	 *
	 * @param string $body Email body content.
	 * @return string Formatted HTML email.
	 * @since 0.0.1
	 */
	private static function format_email_body( $body ) {
		$email_template = Email_Template::get_instance();
		return $email_template->render( $body );
	}
}
