<?php
namespace core;

// Prevent direct access to the file
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

// =================================================================================================
//
//  GravityAbstract
//
// =================================================================================================
abstract class GravityAbstract {
    protected $session;
    protected $config_section;
    protected $form_id;
    private   $url_fingerprint;
    private $config = null;

    public function __construct($session, $config_section) {
        $this->session = $session;
        $this->config_section = $config_section;
        $this->config = $this->session->config[$config_section];
        $this->form_id = $this->config['form_id'];
        $this->url_fingerprint = $this->config['finger_print'];

        // Register hooks
        if ($this->is_gravity_request()) {
            $this->register_hooks();
        }
    }

    # https://docs.gravityforms.com/gform_validation/
    protected function register_hooks() {
        // Admin-specific hooks  (is_admin())
        add_filter("gform_admin_pre_render_{$this->form_id}",      [$this, 'handle_admin_pre_rendering']);
        // add_action("admin_enqueue_scripts", [$this, 'custom_admin_styles']);

        add_filter("gform_entry_pre_update",                       [$this, 'handle_pre_update'], 10, 2);
        add_action("gform_after_update_entry_{$this->form_id}",    [$this, 'handle_post_update'], 10, 2);

        // Frontend-specific hooks
        add_action('wp_enqueue_scripts',                      [$this, 'enqueue_scripts'], 10, 0);
        add_filter("gform_pre_render_{$this->form_id}",       [$this, 'handle_pre_rendering']);
        add_filter("gform_pre_validation_{$this->form_id}",   [$this, 'handle_pre_validation']);
        add_filter("gform_validation_{$this->form_id}",       [$this, 'handle_validation']);
        add_action("gform_pre_submission_{$this->form_id}",   [$this, 'handle_pre_submission']);
        add_action("gform_after_submission_{$this->form_id}", [$this, 'handle_post_submission'], 10, 2);

        // Edit entry hook
        // add_filter('gravityview/edit_entry/field_value', [$this, 'handle_entry_pre_edit'], 10, 3);

        // Delete entry hook
        add_action("gform_delete_entry", [$this, '_handle_entry_deletion']);
    }


    protected function is_gravity_request() {

        // determine if the request URL contains a certain string
        if ($this->url_fingerprint && isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], $this->url_fingerprint) !== false) {
            error_log('is_gravity_request: true, REQUEST_URI=' . $_SERVER['REQUEST_URI']);
            return true;
        }

        // determine if the request is a GravityView Ajax request
        if (isset($_GET['gfid']) && $_GET['gfid'] == $this->form_id) {
            error_log('is_gravityview_request: true, gfid=' . $_GET['gfid']);
            return true;
        }

        // error_log('is_gravityview_request: false');
        return false;
    }

    protected function get_entry_id() {
        // return isset($_GET['edit']) ? $_GET['edit'] : (isset($_GET['entry']) ? $_GET['entry'] : 0);

        $entry = gravityview()->request->is_edit_entry();
        return $entry ? $entry->ID : 0;
    }

    public function _handle_entry_deletion($entry_id) {
        // check if the entry belongs to the form
        $entry = GFAPI::get_entry($entry_id);
        if ($entry['form_id'] == $this->form_id)
            $this->handle_entry_deletion($entry_id);
    }

    public function enqueue_scripts() { error_log('enqueue_scripts'); }
    public function handle_pre_rendering($form) { error_log('handle_pre_rendering'); return $form;}
    public function handle_admin_pre_rendering($form) { error_log('handle_admin_pre_rendering'); return $form; }
    public function handle_pre_validation($form) { error_log('handle_pre_validation');  return $form;}
    public function handle_validation($validation_result) { error_log('handle_validation');  return $validation_result;}
    public function handle_pre_submission($form) { error_log('handle_pre_submission');  }
    public function handle_post_submission($entry, $form) { error_log('handle_post_submission'); }
    public function handle_entry_deletion($entry_id) { error_log('handle_entry_deletion'); }
    public function handle_pre_update($entry, $original_entry) { error_log('handle_pre_update'); return $entry; }
    public function handle_post_update($entry, $original_entry) { error_log('handle_post_update'); }

    /**
     * Get the configuration for the current section.
     *
     * @return array
     */
    protected function get_config(): array {
        return $this->config;
    }

    /**
     * Create a field map (fid => field) for the form.
     *
     * @param array $form The Gravity Forms form object.
     * @return array An associative array mapping field IDs to field objects.
     */
    private $cached_fields;
    private $cached_form;
    protected function get_field_map($form): array {
        // Check if the form is the same as the cached form
        if( $this->cached_form === $form ) {
            $fields = $this->cached_fields;
        }
        // Otherwise, create a new field map
        else {
            $fields = [];
            foreach ($form['fields'] as &$field) {
                $fields[$field->id] = &$field;
            }
            // cache the field map
            $this->cached_fields = $fields;
            $this->cached_form = $form;
        }
        return $fields;
    }


    /**
     * Get the field ID map (field_name => field ID)
     *
     * @return array An associative array mapping field names to field IDs.
     */
    private $cached_fids = null;  // field_name => field_id
    protected function get_fid_map(): array {
        if($this->cached_fids == null) {
            $this->cached_fids = $this->get_config()['fid_map'];
        }
        return $this->cached_fids;
    }
}

?>