<?php
class MuktoEmailRestrictionHandler {
    private $wpdb;
    private $table_prefix;
    private $target_form_names;
    private $submissions_table;
    private $values_table;

  
    public function __construct($target_form_names) {
        global $wpdb;
        $this->wpdb = $wpdb;
        $this->table_prefix = $wpdb->prefix;
        $this->target_form_names = $target_form_names;
        $this->submissions_table = $this->table_prefix . 'e_submissions';
        $this->values_table = $this->table_prefix . 'e_submissions_values';

        // Register the validate_email method as a callback for the elementor_pro/forms/validation/email action hook.
        add_action('elementor_pro/forms/validation/email', array($this, 'validate_email'), 10, 3);
    }

    /**
     * Validate the email address being submitted.
     *
     * @param array $field The email field data.
     * @param \ElementorPro\Modules\Forms\Records\Record $record The form record object.
     * @param \ElementorPro\Modules\Forms\Submissions\Ajax_Handler $ajax_handler The AJAX handler object.
     */
    public function validate_email($field, $record, $ajax_handler) {
        $form_name = $record->get_form_settings('form_name');

        // Check if the current form is one of the target forms.
        if (!in_array($form_name, $this->target_form_names)) {
            return;
        }

        $invalid_emails = $this->get_submitted_emails($record->get_form_settings('id'), $form_name);

        // Check if the email address being submitted is already present in the list of invalid emails.
        if (in_array($field['value'], $invalid_emails)) {
            $ajax_handler->add_error($field['id'], "You have already submitted with this email!");
        }
    }

    /**
     * Retrieve the email addresses that have already been submitted for a specific form.
     *
     * @param int $form_id The form ID.
     * @param string $form_name The name of the form.
     * @return array An array of email addresses that have already been submitted for the given form.
     */
    private function get_submitted_emails($form_id, $form_name) {
        $form_submissions = $this->wpdb->get_results(
            $this->wpdb->prepare(
                "SELECT id FROM {$this->submissions_table} WHERE form_name = %s",
                $form_name
            )
        );
        $form_submission_ids = array_column($form_submissions, 'id');

        if (empty($form_submission_ids)) {
            return array();
        }

        $placeholders = rtrim(str_repeat('%d,', count($form_submission_ids)), ',');
        $results = $this->wpdb->get_results(
            $this->wpdb->prepare(
                "SELECT s.value AS email
                 FROM {$this->values_table} AS s
                 INNER JOIN (
                    SELECT submission_id, MAX(id) AS max_id
                    FROM {$this->values_table}
                    WHERE key = 'email'
                    GROUP BY submission_id
                 ) AS e ON s.submission_id = e.submission_id AND s.id = e.max_id
                 WHERE s.submission_id IN ($placeholders)",
                $form_submission_ids
            )
        );

        return array_column($results, 'email');
    }
}

// Create an instance of the MuktoEmailRestrictionHandler class and pass the array of target form names as an argument.
$email_restriction_handler = new MuktoEmailRestrictionHandler(array('update this form name'));