<?php

/**
 * This file contains the AdminApprovalEnhanced class for extending FluentForm's admin approval functionality.
 *
 * @package FormEnhancer\FluentForm\Integrations
 */

namespace FormEnhancer\FluentForm\Integrations;

use FluentForm\Framework\Helpers\ArrayHelper;
use FluentForm\App\Models\Submission;
use FluentForm\App\Services\FormBuilder\ShortCodeParser;
use FluentForm\App\Services\FormBuilder\Notifications\EmailNotification;
use FluentFormPro\classes\AdminApproval\GlobalSettings;
use FluentFormPro\classes\AdminApproval\AdminApproval;

/**
 * Class AdminApprovalEnhanced
 *
 * Extends FluentForm's admin approval functionality to send additional email notifications.
 */
class AdminApprovalEnhanced
{
	/**
	 * Constructor.
	 *
	 * Sets up action hooks.
	 */
	public function __construct()
	{
		\add_action('fluentform/before_form_actions_processing', [$this, 'processOnSubmission'], 9, 3);
	}

	/**
	 * Hook to process on form submission same as Admin Approval, but send one more email to the user with the same message as shown in the form.
	 *
	 * @param int   $insertId The submission ID.
	 * @param array $formData The submitted form data.
	 * @param array $form     The form object.
	 * @return void
	 */
	public function processOnSubmission($insertId, $formData, $form)
	{

		// phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
		if ($form->has_payment) {
			return;
		}

		$adminApproval = new AdminApproval();

		$adminApprovalFormSettings = $adminApproval->getAdminApproval($form->id, 'public');
		$isInActive = ArrayHelper::get($adminApprovalFormSettings, 'status') != 'yes';
		$skipIfLoggedIn = ArrayHelper::get($adminApprovalFormSettings, 'skip_if_logged_in') == 'yes' && \get_current_user_id();
		$submission = Submission::find($insertId);
		if (!$adminApprovalFormSettings || $isInActive || $skipIfLoggedIn || $submission->status === 'approved') {
			return;
		}

		$this->sendApprovalPendingUserEmail($form, $insertId, $formData, $adminApprovalFormSettings);
	}

	/**
	 * Send approval pending user email.
	 *
	 * Source: based on sendApprovalPendingUserEmail() function from fluentformpro/src/classes/AdminApproval/AdminApproval.php (all credits to FluentForms team).
	 *
	 * @param array $form                      The form object.
	 * @param int   $insertId                  The submission ID.
	 * @param array $formData                  The submitted form data.
	 * @param array $adminApprovalFormSettings The admin approval settings.
	 * @return void|bool
	 */
	private function sendApprovalPendingUserEmail($form, $insertId, $formData, $adminApprovalFormSettings)
	{
		$globalSettings = (new GlobalSettings())->getSettings([]);

		// Message.
		$approvalPendingMessage = ArrayHelper::get($adminApprovalFormSettings, 'approval_pending_message');
		$approvalPendingMessage = ShortCodeParser::parse($approvalPendingMessage, $insertId, $formData);

		$emailField = ArrayHelper::get($adminApprovalFormSettings, 'email_field');
		if (!$emailField) {
			return;
		}
		$emailId = \trim(ArrayHelper::get($formData, $emailField));
		if (!$emailId || !\is_email($emailId)) {
			return;
		}

		$data['email_body'] = $approvalPendingMessage;
		$data['email_subject'] = \__('Your submission is waiting for approval', 'formenhancer');

		$mailSent = $this->processEmail($form, $insertId, $data, $globalSettings, $emailId, $formData);

		\do_action('fluentform/log_data', [
			'parent_source_id' => $form->id,
			'source_type'      => 'submission_item',
			'source_id'        => $insertId,
			'component'        => 'AdminApprovalEnhanced',
			'status'           => 'info',
			'title'            => \__('User Approval Notification Email sent', 'formenhancer'),
			'description'      => \__('Email sent to user email', 'formenhancer') . ' : [' . $emailId . ']',
		]);

		return $mailSent;
	}

	/**
	 * Process email.
	 *
	 * Source: processEmail() function from fluentformpro/src/classes/AdminApproval/AdminApproval.php (all credits to FluentForms team).
	 *
	 * @param array  $form       The form object.
	 * @param int    $insertId   The submission ID.
	 * @param array  $data       The email data.
	 * @param array  $settings   The global settings.
	 * @param string $emailFields The recipient email address.
	 * @param array  $formData   The submitted form data.
	 * @return bool
	 */
	private function processEmail($form, $insertId, $data, $settings, $emailFields, $formData)
	{
		$data = ShortCodeParser::parse($data, $insertId, $formData);
		$notification = [
			'name'           => 'Admin Approval Notification Email',
			'fromName'       => ArrayHelper::get($settings, 'fromName'),
			'fromEmail'      => ArrayHelper::get($settings, 'fromEmail', ''),
			'replyTo'        => ArrayHelper::get($settings, 'replyTo'),
			'bcc'            => '',
			'subject'        => $data['email_subject'],
			'message'        => $data['email_body'],
			'enabled'        => true,
			'email_template' => '',
			'sendTo'         => [
				'type'  => 'email',
				'email' => $emailFields,
				'field' => ''
			]
		];

		$emailNotificationClass = new EmailNotification(\wpFluentForm());
		$emailHeaders = $emailNotificationClass->getHeaders($notification);

		if (ArrayHelper::get($settings, 'asPlainText') != 'yes') {
			$emailBody = $emailNotificationClass->getEmailWithTemplate($data['email_body'], $form, $notification);
		}

		return \wp_mail($emailFields, $data['email_subject'], $emailBody, $emailHeaders);
	}
}
