<?php

namespace GriffinForms;

class Config
{
    public const VERSION = '3.2.3.0';
    public const DB_VER = '3.0.8.0';
    public const PHP_REQUIRED = '8.2';
    public const WP_REQUIRED = '6.6';
    public const CSS_VER = '1.2';
    public const JS_VER = '1.2';
    public const PREFIX = 'griffinforms';
    public const SITE_URL = 'https://griffinforms.com';
    public const HELPDESK_URL = 'https://griffinforms.com';
    public const DOCUMENTATION_URL = 'https://griffinforms.com/documentation';
    public const SUPPORT_EMAIL = 'support@griffinforms.com';
    public const PRO_ENABLED = true;
    private static $instance;

    public $admin_url;
    protected $tables;
    protected $field_types;
    protected $field_registry;
    protected $extension_registry;
    protected $shortcodes;
    protected $date_format;
    protected $time_format;

    protected function setAdminUrl()
    {
        $this->admin_url = get_admin_url();
    }

    protected function setFieldTypes()
    {
        $registry = $this->getFieldRegistry();
        $this->field_types = $registry ? $registry->getFieldTypes() : array();
    }

    protected function setFieldRegistry()
    {
        if ($this->hasFieldRegistryClass()) {
            $this->field_registry = \GriffinForms\Includes\Fields\FieldRegistry::getInstance();
            return;
        }

        $this->field_registry = null;
    }

    protected function setExtensionRegistry()
    {
        // Intentionally left empty — resolved lazily to allow extensions to
        // register their filters before the registry applies them.
    }

    public function getExtensionRegistry(): \GriffinForms\Includes\Extensions\ExtensionRegistry
    {
        if ($this->extension_registry === null) {
            $this->extension_registry = \GriffinForms\Includes\Extensions\ExtensionRegistry::getInstance();
        }
        return $this->extension_registry;
    }

    public function getFieldExtension(string $field_type): array
    {
        return $this->getExtensionRegistry()->getForFieldType($field_type);
    }

    protected function setShortcodes()
    {
        $this->shortcodes = array(
            'griffinforms_form',
            'griffinforms_userarea'
        );
    }

    public function getShortcodes()
    {
        return $this->shortcodes;
    }

    public function getFieldTypes()
    {
        $registry = $this->getFieldRegistry();
        return $registry ? $registry->getFieldTypes() : array();
    }

    public function getFieldDefinitions()
    {
        $registry = $this->getFieldRegistry();
        return $registry ? $registry->getDefinitions() : array();
    }

    public function getFieldDefinitionsByCategory(string $category = '')
    {
        $registry = $this->getFieldRegistry();
        return $registry ? $registry->getDefinitionsByCategory($category) : array();
    }

    public function getFrontendFieldClass(string $field_type = '')
    {
        $registry = $this->getFieldRegistry();
        return $registry ? $registry->getFrontendClass($field_type) : '';
    }

    public function getSubmissionFieldClass(string $field_type = '')
    {
        $registry = $this->getFieldRegistry();
        return $registry ? $registry->getSubmissionClass($field_type) : '';
    }

    public function getFieldValidatorClass(string $field_type = '')
    {
        $registry = $this->getFieldRegistry();
        return $registry ? $registry->getValidatorClass($field_type) : '';
    }

    public function isValidFieldType($field_type = '')
    {
        // Check if the provided field_type is empty
        if (empty($field_type)) {
            return false;  // Return false if field type is empty
        }

        $valid_field_types = $this->getFieldTypes();  // Get the list of valid field types
        return in_array($field_type, $valid_field_types);
    }

    public function isRegisteredFieldType($field_type = '')
    {
        $registry = $this->getFieldRegistry();
        return $registry ? $registry->isRegistered((string) $field_type) : false;
    }

    public function isPortableFieldType($field_type = '')
    {
        $field_type = (string) $field_type;
        if ($field_type === '') {
            return false;
        }

        return sanitize_key($field_type) === $field_type;
    }

    public function getItemTypes()
    {
        return array_keys($this->tables);
    }

    protected function setTables()
    {
        global $wpdb;
        $pre = $wpdb->prefix . 'griffinforms_';
        $this->tables = array(
            'form' => $pre . 'form',
            'forms' => $pre . 'form',
            'formpage' => $pre . 'formpage',
            'formpages' => $pre . 'formpage',
            'pagerow' => $pre . 'pagerow',
            'pagerows' => $pre . 'pagerow',
            'rowcolumn' => $pre . 'rowcolumn',
            'field' => $pre . 'field',
            'fields' => $pre . 'field',
            'options' => $pre . 'options',
            'message' => $pre . 'message',
            'messages' => $pre . 'message',
            'folder' => $pre . 'folder',
            'folders' => $pre . 'folder',
            'formstyle' => $pre . 'formstyle',
            'formtheme' => $pre . 'formtheme',
            'formthemes' => $pre . 'formtheme',
            'submission' => $pre . 'submission',
            'submissions' => $pre . 'submission',
            'submission_revision' => $pre . 'submission_revision',
            'submission_revisions' => $pre . 'submission_revision',
            'log' => $pre . 'log',
            'logs' => $pre . 'log',
            'template' => $pre . 'templates',
            'file' => $pre . 'files',
            'files' => $pre . 'files',
            'ratelimiter' => $pre . 'ratelimiter',
            'job' => $pre . 'jobs',
            'jobs' => $pre . 'jobs',
            'layout_snapshot' => $pre . 'layout_snapshots',
            'layout_snapshots' => $pre . 'layout_snapshots',
            'migration_traceability' => $pre . 'migration_traceability',
            'migration_traceabilities' => $pre . 'migration_traceability',
        );
    }

    public function getTable($item_type)
    {
        $item_type = sanitize_key($item_type);
        $item_type = strtolower($item_type);
        if (array_key_exists($item_type, $this->tables)) {
            return $this->tables[$item_type];
        } else {
            return false;
        }
    }

    public function getTables()
    {
        return array_unique(array_values($this->tables));
    }

    public function getRootUrl()
    {
        return plugin_dir_url(__FILE__);
    }

    public function getRootPath()
    {
        return plugin_dir_path(__FILE__);
    }

    protected function setDateFormat()
    {
        $this->date_format = get_option('date_format');
        $this->time_format = get_option('time_format');
    }

    public function getDateTimeFormat()
    {
        return $this->date_format . ' ' . $this->time_format;
    }

    /**
     * Returns a friendly, human-readable name for a given item or field type.
     *
     * This method maps internal type identifiers (e.g., 'inputtext', 'formpage', etc.)
     * to their corresponding friendly labels, which are translatable. If the provided key
     * is not found in the mapping, a default message is returned.
     *
     * @param string $name The internal type identifier.
     * @return string The translatable friendly name corresponding to the provided key.
     */
    public function getFriendlyName(string $name = '')
    {
        $names = array(
            'form' => __('Form', 'griffinforms-form-builder'),
            'formpage' => __('Page', 'griffinforms-form-builder'),
            'pagerow' => __('Row', 'griffinforms-form-builder'),
            'rowcolumn' => __('Column', 'griffinforms-form-builder'),
            'field' => __('Field', 'griffinforms-form-builder'),
            'folder' => __('Folder', 'griffinforms-form-builder'),
            'formtheme' => __('Theme', 'griffinforms-form-builder'),
            'message' => __('Message', 'griffinforms-form-builder'),
            'submission' => __('Submission', 'griffinforms-form-builder'),
            'inputtext' => __('Single-Line Text', 'griffinforms-form-builder'),
            'inputnumber' => __('Number', 'griffinforms-form-builder'),
            'inputemail' => __('Email', 'griffinforms-form-builder'),
            'inputpassword' => __('Password', 'griffinforms-form-builder'),
            'inputphone' => __('Phone Number', 'griffinforms-form-builder'),
            'inputaddress' => __('Address', 'griffinforms-form-builder'),
            'inputurl' => __('URL', 'griffinforms-form-builder'),
            'inputdate' => __('Date', 'griffinforms-form-builder'),
            'inputtime' => __('Time', 'griffinforms-form-builder'),
            'textarea' => __('Mult-Line Text', 'griffinforms-form-builder'),
            'selectfield' => __('Dropdown', 'griffinforms-form-builder'),
            'inputcheckbox' => __('Checkbox', 'griffinforms-form-builder'),
            'inputradio' => __('Radio', 'griffinforms-form-builder'),
            'fileupload' => __('File Upload', 'griffinforms-form-builder'),
            'termsconditions' => __('Terms and Conditions', 'griffinforms-form-builder'),
            'payment' => __('Payment', 'griffinforms-form-builder'),
            'signature' => __('Signature', 'griffinforms-form-builder'),
            'inputrating' => __('Rating', 'griffinforms-form-builder'),
            'inputrichtext' => __('Rich Text', 'griffinforms-form-builder'),
            'inputlikert' => __('Likert Scale', 'griffinforms-form-builder'),
            'imageselection' => __('Image Selection', 'griffinforms-form-builder'),
        );

        if (empty($name)) {
            return __('Unknown', 'griffinforms-form-builder');
        }

        if (array_key_exists($name, $names)) {
            return $names[$name];
        }

        $registry_label = $this->getFieldRegistry()->getLabel($name);
        if ($registry_label !== '') {
            return $registry_label;
        }

        return ucfirst($name);
    }

    public static function getInstance()
    {
        if (self::$instance == null) {
            self::$instance = new Config();
        }

        return self::$instance;
    }

    private function __construct()
    {
        $this->setAdminUrl();
        $this->setTables();
        $this->setFieldRegistry();
        $this->setFieldTypes();
        $this->setShortcodes();
        $this->setDateFormat();
    }

    protected function getFieldRegistry()
    {
        return $this->field_registry;
    }

    protected function hasFieldRegistryClass(): bool
    {
        return class_exists(\GriffinForms\Includes\Fields\FieldRegistry::class);
    }
}
