<?php
// Exit if accessed directly.
if (!defined('ABSPATH')) {
    exit; // Prevent direct access to the file.
}

// Check if the class already exists to avoid redeclaration.
if (!class_exists('IAFWZC_Form_Group_Id')) {
    class IAFWZC_Form_Group_Id
    {
        // Constructor for loading required dependencies, if any
        public function __construct()
        {
            // Add any necessary initialization here
        }

        /**
         * Gets all form group IDs and names for different form types like Contact Form 7 and WPForms.
         *
         * @return array Associative array where each form type identifier has a name and list of form IDs and names.
         */
        public function getAllFormGroupID()
        {
            $formGroups = [];

            // Contact Form 7
            $contactForms = $this->getContactForm7Forms();
            if (!empty($contactForms)) {
                $formGroups[1] = [
                    'form_group_name' => 'Contact Form 7',
                    'forms' => $contactForms
                ];
            }

            // WPForms
            $wpForms = $this->getWPForms();
            if (!empty($wpForms)) {
                $formGroups[2] = [
                    'form_group_name' => 'WPForms',
                    'forms' => $wpForms
                ];
            }

            // Gravity Forms
            $gravityForms = $this->getGravityForms();
            if (!empty($gravityForms)) {
                $formGroups[3] = [
                    'form_group_name' => 'Gravity Forms',
                    'forms' => $gravityForms
                ];
            }

            // Ninja Forms
            // $ninjaForms = $this->getNinjaForms();
            // if (!empty($ninjaForms)) {
            //     $formGroups[4] = [
            //         'form_group_name' => 'Ninja Forms',
            //         'forms' => $ninjaForms
            //     ];
            // }

            // Formidable Forms
            $formidableForms = $this->getFormidableForms();
            if (!empty($formidableForms)) {
                $formGroups[5] = [
                    'form_group_name' => 'Formidable Forms',
                    'forms' => $formidableForms
                ];
            }

            // Everest Forms
            // $everestForms = $this->getEverestForms();
            // if (!empty($everestForms)) {
            //     $formGroups[6] = [
            //         'form_group_name' => 'Everest Forms',
            //         'forms' => $everestForms
            //     ];
            // }

            // Elementor Forms
            $elementorForms = $this->getElementorForms();
            if (!empty($elementorForms)) {
                $formGroups[7] = [
                    'form_group_name' => 'Elementor Forms',
                    'forms' => $elementorForms
                ];
            }

            return $formGroups;
        }



        /**
         * Retrieves all Contact Form 7 forms with their IDs and names.
         *
         * @return array Array of arrays, each containing the ID and name of a Contact Form 7 form.
         */
        private function getContactForm7Forms()
        {
            $contactForms = [];
            try {
                // Query for all Contact Form 7 forms
                $args = [
                    'post_type' => 'wpcf7_contact_form',
                    'posts_per_page' => -1,
                ];
                $cf7Forms = get_posts($args);

                foreach ($cf7Forms as $form) {
                    $contactForms[] = [
                        'id' => $form->ID,
                        'name' => $form->post_title,
                    ];
                }

                return $contactForms;
            } catch (Throwable $e) {
                return $contactForms;
            }
        }

        /**
         * Retrieves all WPForms with their IDs and names.
         *
         * @return array Array of arrays, each containing the ID and name of a WPForms form.
         */
        private function getWPForms()
        {
            $wpForms = [];
            try {
                // Fetch all WPForms using WPForms API
                $forms = wpforms()->form->get();

                if (!is_array($forms)) {
                    return $wpForms;
                }

                foreach ($forms as $form) {
                    $wpForms[] = [
                        'id' => $form->ID,
                        'name' => $form->post_title,
                    ];
                }

                return $wpForms;
            } catch (Throwable $e) {
                return $wpForms;
            }
        }
        /**
         * Retrieves all Gravity Forms with their IDs and names.
         *
         * @return array Array of arrays, each containing the ID and name of a Gravity Form.
         */
        private function getGravityForms()
        {
            $gravityForms = [];
            try {
                // Check if Gravity Forms is active and accessible
                if (class_exists('GFAPI')) {
                    // Fetch all Gravity Forms using Gravity Forms API
                    $forms = GFAPI::get_forms();

                    foreach ($forms as $form) {
                        $gravityForms[] = [
                            'id' => $form['id'],
                            'name' => $form['title'],
                        ];
                    }
                }

                return $gravityForms;
            } catch (Throwable $e) {
                return $gravityForms;
            }
        }
        /**
         * Retrieves all Ninja Forms with their IDs and names.
         *
         * @return array Array of arrays, each containing the ID and name of a Ninja Form.
         */
        private function getNinjaForms()
        {
            $ninjaForms = [];
            try {
                // Check if Ninja Forms is active and accessible
                if (class_exists('Ninja_Forms')) {
                    // Fetch all Ninja Forms using Ninja Forms API
                    $forms = Ninja_Forms()->form()->get_forms();

                    foreach ($forms as $form) {
                        $ninjaForms[] = [
                            'id' => $form->get_id(),
                            'name' => $form->get_setting('title'),
                        ];
                    }
                }

                return $ninjaForms;
            } catch (Throwable $e) {
                return $ninjaForms;
            }
        }

        /**
         * Retrieves all Formidable Forms with their IDs and names.
         *
         * @return array Array of arrays, each containing the ID and name of a Formidable Form.
         */
        private function getFormidableForms()
        {
            $formidableForms = [];
            try {
                // Check if Formidable Forms is active and accessible
                if (class_exists('FrmForm')) {
                    // Fetch all Formidable Forms using Formidable Forms API
                    $forms = FrmForm::getAll(); // Retrieve all forms

                    foreach ($forms as $form) {
                        $formidableForms[] = [
                            'id' => $form->id,
                            'name' => $form->name,
                        ];
                    }
                }

                return $formidableForms;
            } catch (Throwable $e) {
                return $formidableForms;
            }
        }
        /**
         * Retrieves all Everest Forms with their IDs and names.
         *
         * @return array Array of arrays, each containing the ID and name of an Everest Form.
         */
        private function getEverestForms()
        {
            $everestForms = [];
            try {
                // Define the query arguments
                $args = [
                    'post_type'      => 'everest_form',
                    'posts_per_page' => -1, // Retrieve all forms
                    'post_status'    => 'publish', // Only include published forms
                ];

                // Execute the query
                $forms_query = new WP_Query($args);

                // Check if any forms were found
                if ($forms_query->have_posts()) {
                    // Loop through each form
                    while ($forms_query->have_posts()) {
                        $forms_query->the_post();
                        $everestForms[] = [
                            'id'   => get_the_ID(),
                            'name' => get_the_title(),
                        ];
                    }
                    // Restore original Post Data
                    wp_reset_postdata();
                }

                return $everestForms;
            } catch (Throwable $e) {
                return $everestForms;
            }
        }
        /** =========================
         *  ELEMENTOR FORMS LISTING (clean)
         *  ========================= */
        public function getElementorForms()
        {
            $form_list = [];

            // Require Elementor Core + Pro
            if (! did_action('elementor/loaded') || ! defined('ELEMENTOR_PRO_VERSION')) {
                return $form_list;
            }

            try {
                $args = [
                    'post_type'      => ['page', 'post', 'elementor_library'],
                    'posts_per_page' => -1,
                    'post_status'    => 'any',
                    'fields'         => 'ids',
                    // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
                    'meta_query'     => [
                        [
                            'key'     => '_elementor_data',
                            'compare' => 'EXISTS',
                        ],
                    ],
                ];

                $posts = get_posts($args);
                if (empty($posts) || is_wp_error($posts)) {
                    return $form_list;
                }

                foreach ($posts as $post_id) {
                    $raw = get_post_meta($post_id, '_elementor_data', true);
                    if ($raw === '' || $raw === null) {
                        continue;
                    }

                    // Tolerant decode (no pre-unslash)
                    $data = $this->decode_elementor_json($raw);
                    if (! is_array($data)) {
                        continue;
                    }

                    // Find Elementor Form widgets
                    $iterator = new RecursiveIteratorIterator(
                        new RecursiveArrayIterator($data),
                        RecursiveIteratorIterator::SELF_FIRST
                    );

                    foreach ($iterator as $node) {
                        if (
                            is_array($node)
                            && ($node['elType'] ?? null) === 'widget'
                            && ($node['widgetType'] ?? null) === 'form'
                            && ! empty($node['id'])
                        ) {
                            $form_name = ! empty($node['settings']['form_name'])
                                ? (string) $node['settings']['form_name']
                                : 'Untitled Form';

                            $form_id   = (string) $node['id']; // Elementor widget id
                            $title     = get_the_title($post_id);

                            $form_list[] = [
                                'id'   => $post_id . '_' . $form_id,  // combined id for lookup
                                'name' => sprintf('%s (Page: %s)', $form_name, $title),
                            ];
                        }
                    }
                }

                return $form_list;
            } catch (Throwable $e) {
                return $form_list;
            }
        }

        /** =========================
         *  Tolerant JSON decoder (no side-effects)
         *  ========================= */
        private function decode_elementor_json($raw)
        {
            // 1) Try as-is
            $data = json_decode($raw, true);
            if (is_array($data)) return $data;

            // 2) Try unslash
            if (function_exists('wp_unslash')) {
                $data = json_decode(wp_unslash($raw), true);
                if (is_array($data)) return $data;
            }

            // 3) Normalize encoding (rare)
            if (function_exists('mb_convert_encoding')) {
                $fixed = mb_convert_encoding($raw, 'UTF-8', 'UTF-8');
                $data  = json_decode($fixed, true);
                if (is_array($data)) return $data;
            }

            return null;
        }
    }
}
