<?php
namespace KaliForms\Inc\Backend;

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

class Multiple_Entries_Prevention
{
    /**
     * Plugin slug
     *
     * @var string
     */
    protected $slug = 'kaliforms-pro';
    /**
     * Parent plugin slug
     *
     * @var string
     */
    protected $parent_slug = 'kaliforms';
    /**
     * Conditional_Thank_You constructor.
     */
    public function __construct()
    {
        /**
         * Meta save fields
         */
        add_filter($this->parent_slug . '_meta_save_fields', [$this, 'add_meta_fields']);
        /**
         * Populate the JSVars object
         */
        add_filter($this->parent_slug . '_jsvars_object', [$this, 'add_to_vars']);
		add_filter($this->parent_slug . '_form_options', [$this, 'alter_form_options']);

        add_filter($this->parent_slug . '_before_form_end', [$this, 'add_submitter_user_id_field']);
        /**
         * Hijack form
         */
        add_filter($this->parent_slug . '_form_shortcode_finished_rendering', [$this, 'hijack_form']);
        add_filter($this->parent_slug . '_before_form_process', [$this, 'hijack_form_submission']);
    }
    /**
     * Creates the user id field
     *
     * @param [type] $data
     * @return void
     */
    public function add_submitter_user_id_field($data)
    {
        $user = wp_get_current_user();
        if ($user->ID === 0) {
            return $data;
        }
        $data['string'] .= '<input type="hidden" name="kf_submitted_user_id" readonly value="' . $user->ID . '" />';

        return $data;
    }
    /**
     * Returns html
     *
     * @param [type] $html
     * @return void
     */
    public function hijack_form($form)
    {
        $prevention_enabled = $form->get('prevent_multiple_entries', '0');
        if ($prevention_enabled === '0') {
            return $form;
        }
        $prevent_by = $form->get('multiple_entries_invalidate', 'userid');
        if ($prevent_by === 'field') {
            return $form;
        }

        $error_message = '<div class="kaliforms-container bootstrap-wrapper">' . $form->get('multiple_entries_error', '') . '</div>';
        $user          = wp_get_current_user();
        if ($user->ID === 0) {
            $form->html = '<div class="kaliforms-container bootstrap-wrapper">' . esc_html__('You must be logged in to fill this form.', 'kaliforms') . '</div>';
            return $form;
        }

        if ($this->_count_submissions($form->post->ID, ['key' => 'kf_submitted_user_id', 'value' => $user->ID])) {
            $form->html = $error_message;
        }

        return $form;
    }
    /**
     * Hijack form submission
     *
     * @return void
     */
    public function hijack_form_submission($data)
    {
        $errorMessage      = get_post_meta($data['formId'], $this->parent_slug . '_multiple_entries_error', true);
        $invalidateBy      = get_post_meta($data['formId'], $this->parent_slug . '_multiple_entries_invalidate', true);
        $invalidateByField = get_post_meta($data['formId'], $this->parent_slug . '_multiple_entries_invalidate_field', true);
        $preventionEnabled = get_post_meta($data['formId'], $this->parent_slug . '_prevent_multiple_entries', true);

        if ($preventionEnabled === null || $preventionEnabled === '' || $preventionEnabled === '0') {
            return $data;
        }

        if ($invalidateBy === null || $invalidateBy === '' || $invalidateBy === 'userid' || $invalidateBy !== 'field') {
            return $data;
        }

        $value = $this->_get_field_value($invalidateByField, $data);
        if ($this->_count_submissions($data['formId'], ['key' => $invalidateByField, 'value' => $value])) {
            $data['admin_stop_execution'] = true;
            $data['admin_stop_reason']    = $errorMessage;
            $data['error_bag']            = isset($data['error_bag']) ? $data['error_bag'] : [];

            $data['error_bag'][] = ['field' => $invalidateByField, 'message' => esc_html__('This field should be unique.', 'kaliforms')];
        }

        return $data;
    }
    /**
     * Count submissions
     *
     * @param $form
     * @param $user
     * @return void
     */
    public function _count_submissions($formId, $data)
    {
        $args = [
            'post_type'      => 'kaliforms_submitted',
            'posts_per_page' => -1,
            'meta_key'       => 'formId',
            'meta_query'     => [
                'relation' => 'AND',
                [
                    'key'   => 'formId',
                    'value' => $formId,
                ],
                [
                    'key'   => $data['key'],
                    'value' => $data['value'],
                ],
            ],
        ];
        $query = new \WP_Query($args);
        wp_reset_postdata();
        return $query->post_count > 0;
    }
    /**
     * Adds conditional thank you message
     *
     * @param [type] $vars
     * @return void
     */
    public function add_to_vars($jsvars)
    {
        return array_merge($jsvars, $this->get_options($jsvars['formId']));
    }
    /**
     * Alter form options
     *
     * @param [type] $options
     * @return void
     */
    public function alter_form_options($options)
    {
        return array_merge($options, $this->get_options($options['formId']));
    }
    public function get_options($id)
    {
        $errorMessage      = get_post_meta($id, $this->parent_slug . '_multiple_entries_error', true);
        $invalidateBy      = get_post_meta($id, $this->parent_slug . '_multiple_entries_invalidate', true);
        $invalidateByField = get_post_meta($id, $this->parent_slug . '_multiple_entries_invalidate_field', true);
        $preventionEnabled = get_post_meta($id, $this->parent_slug . '_prevent_multiple_entries', true);

        if ($errorMessage === null || $errorMessage === '') {
            $errorMessage = '';
        }
        if ($invalidateBy === null || $invalidateBy === '') {
            $invalidateBy = 'userid';
        }
        if ($invalidateByField === null) {
            $invalidateByField = '';
        }
        if ($preventionEnabled === null || $preventionEnabled === '') {
            $preventionEnabled = '0';
        }

		$data = [];
        $data['multipleEntriesError']               = $errorMessage;
        $data['preventMultipleEntriesFromSameUser'] = $preventionEnabled;
        $data['multipleEntriesInvalidate']          = $invalidateBy;
        $data['multipleEntriesInvalidateField']     = $invalidateByField;

		return $data;
    }
    /**
     * Add new meta fields
     *
     * @param [type] $meta
     * @return void
     */
    public function add_meta_fields($meta)
    {
        $meta->add_fields(
            ['id' => 'prevent_multiple_entries', 'sanitize' => 'KaliForms\Inc\Backend\Sanitizers::sanitize_boolean'],
            ['id' => 'multiple_entries_error', 'sanitize' => 'wp_kses_post'],
            ['id' => 'multiple_entries_invalidate', 'sanitize' => 'sanitize_text_field'],
            ['id' => 'multiple_entries_invalidate_field', 'sanitize' => 'sanitize_text_field']
        );

        return $meta;
    }
    /**
     * Returns the provider object
     *
     * @return void
     */
    private function _get_field_value($key, $data)
    {
        if (isset($data[$key])) {
            if (is_array($data[$key])) {
                return implode(',', $data[$key]);
            }
            return $data[$key];
        }

        return '';
    }
}
