<?php

namespace GriffinForms\Admin\Choices;

class ConditionalLogic extends \GriffinForms\Admin\Choices\Format
{
    public function ifItems()
    {
        return [
            'field' => __('the field', 'griffinforms-form-builder'),
            'user'  => __('the user', 'griffinforms-form-builder')
        ];
    }

    public function actionItemTypes()
    {
        return [
            'field' => __('the field', 'griffinforms-form-builder'),
            'form'  => __('the form', 'griffinforms-form-builder'),
            'row'   => __('the row', 'griffinforms-form-builder'),
        ];
    }

    // Returns the list of editable attributes for conditional-logic actions.
    public function actionFieldAttributes($field_type = '')
    {
        $field_type = strtolower((string) $field_type);

        // Payment fields use a restricted action set (no raw value changes).
        if ('payment' === $field_type) {
            return [
                'visibility' => __('visibility', 'griffinforms-form-builder'),
                'state'      => __('state', 'griffinforms-form-builder'),
                'label'      => __('label', 'griffinforms-form-builder'),
                'gateway'    => __('payment gateway', 'griffinforms-form-builder'),
            ];
        }

        $attributes = [
            'visibility' => __('visibility', 'griffinforms-form-builder'),
            'state' => __('state', 'griffinforms-form-builder'),
            'value' => __('value', 'griffinforms-form-builder'),
            'label' => __('label', 'griffinforms-form-builder'),
        ];
        if ('fileupload' === $field_type || 'signature' === $field_type || 'inputrichtext' === $field_type || 'inputlikert' === $field_type || 'imageselection' === $field_type) {
            unset($attributes['value']);
        }

        if ('selectfield' === $field_type) {
            $attributes['option_groups'] = __('options group', 'griffinforms-form-builder');
        }

        if ('inputlikert' === $field_type) {
            $attributes['rows'] = __('rows', 'griffinforms-form-builder');
        }

        if ('payment' === $field_type) {
            $attributes['gateway'] = __('payment gateway', 'griffinforms-form-builder');
        }

        return $attributes;
    }

    public function actionFormAttributes()
    {
        return [
            'visibility' => __('visibility', 'griffinforms-form-builder'),
            'success_message' => __('success message', 'griffinforms-form-builder'),
            'redirection' => __('redirection', 'griffinforms-form-builder'),
            'submit_button_label' => __('submit button label', 'griffinforms-form-builder'),
            'submit_button_state' => __('submit button state', 'griffinforms-form-builder'),
        ];
    }

    // Returns attributes available for actions targeting a row.
    public function actionRowAttributes()
    {
        return [
            'visibility' => __('visibility', 'griffinforms-form-builder'),
            'heading'    => __('heading', 'griffinforms-form-builder'),
        ];
    }

    // Returns the operation labels available for visibility changes.
    public function actionVisibilityOperations($item_type = null)
    {
        return $this->extractOperationLabels(
            $this->filterVisibilityOperationsByItemType(
                $item_type,
                $this->actionVisibilityOperationConfig()
            )
        );
    }

    // Provides the configuration for visibility operations.
    protected function actionVisibilityOperationConfig()
    {
        return [
            'show' => [
                'label'       => __('be shown', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'hide' => [
                'label'       => __('be hidden', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'show_error' => [
                'label'       => __('show error message', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'show_warning' => [
                'label'       => __('show warning message', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'show_info' => [
                'label'       => __('show info message', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'show_popup' => [
                'label'       => __('show popup message', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'add_class' => [
                'label'       => __('add class', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'remove_class' => [
                'label'       => __('remove class', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
        ];
    }

    protected function filterVisibilityOperationsByItemType($item_type, array $operations)
    {
        $item_type = is_string($item_type) ? strtolower($item_type) : null;

        if ('form' === $item_type) {
            $allowed = ['show_error', 'show_warning', 'show_info', 'show_popup'];
            return array_intersect_key($operations, array_flip($allowed));
        }

        if ('field' === $item_type) {
            return array_diff_key($operations, array_flip(['show_popup']));
        }

        if ('row' === $item_type) {
            // Rows support only show/hide and class toggles.
            $allowed = ['show', 'hide', 'add_class', 'remove_class'];
            return array_intersect_key($operations, array_flip($allowed));
        }

        if (null === $item_type || '' === $item_type) {
            return $operations;
        }

        return $operations;
    }

    // Returns the operation labels available for value changes.
    public function actionValueOperations()
    {
        return $this->extractOperationLabels($this->actionValueOperationConfig());
    }

    // Provides the configuration for value operations on supported field types.
    protected function actionValueOperationConfig($field_type = '')
    {
        $field_type = strtolower((string) $field_type);

        $input_type = 'textarea';
        switch ($field_type) {
            case 'inputnumber':
                $input_type = 'number';
                break;
            case 'inputemail':
                $input_type = 'email';
                break;
            case 'inputphone':
                $input_type = 'tel';
                break;
            case 'inputurl':
                $input_type = 'url';
                break;
            case 'inputdate':
                $input_type = 'date';
                break;
            case 'inputtime':
                $input_type = 'time';
                break;
        }

        $operations = [
            'change_to' => [
                'label'       => __('change to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => $input_type,
            ],
        ];

        if ('inputaddress' === $field_type) {
            unset($operations['change_to']);

            $operations['change_country_to'] = [
                'label'       => __('change country to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ];

            $operations['change_city_to'] = [
                'label'       => __('change city to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ];

            $operations['change_state_to'] = [
                'label'       => __('change state / province to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ];
        }

        return $operations;
    }

    // Returns the operation labels available for label changes.
    public function actionLabelOperations($field_type = '')
    {
        return $this->extractOperationLabels($this->actionLabelOperationConfig($field_type));
    }

    // Provides the configuration for label operations on fields.
    protected function actionLabelOperationConfig($field_type = '')
    {
        $field_type = strtolower((string) $field_type);

        $operations = [
            'change_to' => [
                'label'       => __('change to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'add_class' => [
                'label'       => __('add class', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'remove_class' => [
                'label'       => __('remove class', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
        ];

        if ('inputaddress' === $field_type) {
            $operations['change_line_1_label_to'] = [
                'label'       => __('change Address Line 1 label to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ];

            $operations['change_line_2_label_to'] = [
                'label'       => __('change Address Line 2 label to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ];

            $operations['change_city_label_to'] = [
                'label'       => __('change City label to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ];

            $operations['change_state_label_to'] = [
                'label'       => __('change State / Province label to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ];

            $operations['change_country_label_to'] = [
                'label'       => __('change Country label to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ];
        }

        return $operations;
    }

    public function actionStateOperations()
    {
        return $this->extractOperationLabels($this->actionStateOperationConfig());
    }

    protected function actionStateOperationConfig()
    {
        return [
            'disabled' => [
                'label'       => __('be disabled', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'enabled' => [
                'label'       => __('be enabled', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
        ];
    }

    protected function actionOptionGroupsOperationConfig()
    {
        return [
            'show' => [
                'label'       => __('show selected groups', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'option_groups',
            ],
            'hide' => [
                'label'       => __('hide selected groups', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'option_groups',
            ],
        ];
    }

    protected function actionLikertRowsOperationConfig()
    {
        return [
            'show_rows' => [
                'label'       => __('show selected rows', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'likert_rows',
            ],
            'hide_rows' => [
                'label'       => __('hide selected rows', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'likert_rows',
            ],
        ];
    }

    protected function actionGatewayOperationConfig()
    {
        return [
            'set_to' => [
                'label'       => __('set to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'select_gateway',
            ],
        ];
    }

    protected function actionSuccessMessageOperationConfig()
    {
        return [
            'change_to' => [
                'label'       => __('change to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'append' => [
                'label'       => __('append', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
        ];
    }

    protected function actionRedirectionOperationConfig()
    {
        return [
            'change_to' => [
                'label'       => __('change to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'append' => [
                'label'       => __('append', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
        ];
    }

    // Extracts human-readable labels from an operation configuration array.
    protected function extractOperationLabels(array $operations)
    {
        $labels = [];

        foreach ($operations as $value => $config) {
            if (is_array($config) && array_key_exists('label', $config)) {
                $labels[$value] = $config['label'];
            } else {
                $labels[$value] = $config;
            }
        }

        return $labels;
    }

    // Retrieves the configuration for the selected action attribute.
    public function getActionOperationConfig($attribute, $field_type = '', $item_type = null)
    {
        $attribute = strtolower((string) $attribute);
        $item_type = is_string($item_type) ? strtolower($item_type) : null;

        switch ($attribute) {
            case 'visibility':
                return $this->filterVisibilityOperationsByItemType(
                    $item_type,
                    $this->actionVisibilityOperationConfig()
                );
            case 'value':
                return $this->actionValueOperationConfig($field_type);
            case 'label':
                return $this->actionLabelOperationConfig($field_type);
            case 'heading':
                return $this->actionHeadingOperationConfig();
            case 'state':
                return $this->actionStateOperationConfig();
            case 'option_groups':
                return $this->actionOptionGroupsOperationConfig();
            case 'rows':
                return $this->actionLikertRowsOperationConfig();
            case 'success_message':
                return $this->actionSuccessMessageOperationConfig();
            case 'redirection':
                return $this->actionRedirectionOperationConfig();
            case 'gateway':
                return $this->actionGatewayOperationConfig();
            case 'submit_button_label':
                return [
                    'change_to' => [
                        'label'       => __('change to', 'griffinforms-form-builder'),
                        'needs_input' => true,
                        'input_type'  => 'textarea',
                    ],
                ];
            case 'submit_button_state':
                return $this->actionStateOperationConfig();
            default:
                return [];
        }
    }

    // Provides the configuration for row heading operations.
    protected function actionHeadingOperationConfig()
    {
        return [
            'change_to' => [
                'label'       => __('change to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'add_class' => [
                'label'       => __('add class', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'remove_class' => [
                'label'       => __('remove class', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
        ];
    }

    // Returns metadata for a specific action operation selection.
    public function getActionOperationMeta($attribute, $operation, $field_type = '', $item_type = null)
    {
        $config = $this->getActionOperationConfig($attribute, $field_type, $item_type);
        return isset($config[$operation]) ? $config[$operation] : null;
    }

    // Provides operation labels for UI controls based on the attribute and field type.
    public function getActionOperations($attribute, $field_type = '', $item_type = null)
    {
        return $this->extractOperationLabels(
            $this->getActionOperationConfig($attribute, $field_type, $item_type)
        );
    }

    public function fieldAttrs($field_type = '')
    {
        $field_type = strtolower((string) $field_type);

        // Payment field specific attributes.
        if ('payment' === $field_type) {
            return [
                'selected_product'  => __('selected product', 'griffinforms-form-builder'),
                'product_quantity'  => __('product quantity', 'griffinforms-form-builder'),
                'total_amount'      => __('total amount', 'griffinforms-form-builder'),
                'selection_count'   => __('number of selected products', 'griffinforms-form-builder'),
                'selected_gateway'  => __('selected gateway', 'griffinforms-form-builder'),
            ];
        }

        $attributes = [
            'value' => __('value', 'griffinforms-form-builder'),
            'attribute_count' => __('number of answers', 'griffinforms-form-builder'),
        ];

        if ('inputpassword' === $field_type) {
            $attributes['strength'] = __('strength', 'griffinforms-form-builder');
        }

        return $attributes;
    }

    // Condition attributes for user
    public function userAttrs($unused = '')
    {
        return [
            'browser_time' => __('browser time', 'griffinforms-form-builder'),
        ];
    }

    // Evaluator labels for user->browser_time
    public function userbrowser_timeEvaluators($unused = '')
    {
        return $this->extractEvaluatorLabels($this->userbrowser_timeEvaluatorConfig($unused));
    }

    // Evaluator config for user->browser_time
    public function userbrowser_timeEvaluatorConfig($unused = '')
    {
        return [
            'before' => [
                'label'       => __('is before', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'time_select',
            ],
            'after' => [
                'label'       => __('is after', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'time_select',
            ],
        ];
    }

    public function fieldValueEvaluators($field_type)
    {
        return $this->extractEvaluatorLabels($this->fieldValueEvaluatorConfig($field_type));
    }

    public function fieldValueEvaluatorConfig($field_type)
    {
        $method = $field_type . 'valueEvaluators';
        if (method_exists($this, $method)) {
            return $this->$method();
        }

        return $this->defaultFieldValueEvaluators();
    }

    public function fieldattribute_countEvaluators($field_type = '')
    {
        return $this->extractEvaluatorLabels($this->fieldattribute_countEvaluatorConfig($field_type));
    }

    public function fieldattribute_countEvaluatorConfig($field_type = '')
    {
        return [
            'less_than' => [
                'label'       => __('is less than', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'more_than' => [
                'label'       => __('is greater than', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'equal_to' => [
                'label'       => __('is equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
        ];
    }

    public function fieldstrengthEvaluators($field_type = '')
    {
        return $this->extractEvaluatorLabels($this->fieldstrengthEvaluatorConfig($field_type));
    }

    public function fieldstrengthEvaluatorConfig($field_type = '')
    {
        $field_type = strtolower((string) $field_type);
        if ('' !== $field_type && 'inputpassword' !== $field_type) {
            return [];
        }

        $labels = [
            'weak' => __('is weak', 'griffinforms-form-builder'),
            'medium' => __('is medium', 'griffinforms-form-builder'),
            'strong' => __('is strong', 'griffinforms-form-builder'),
            'very_strong' => __('is very strong', 'griffinforms-form-builder'),
        ];

        $config = [];
        foreach ($labels as $key => $label) {
            $config[$key] = [
                'label' => $label,
                'needs_input' => false,
                'input_type' => null,
            ];
        }

        return $config;
    }

    public function defaultFieldValueEvaluators()
    {
        return [
            'equal_to'     => [
                'label'       => __('is equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'not_equal_to' => [
                'label'       => __('is not equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'contains'     => [
                'label'       => __('contains', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'not_contains' => [
                'label'       => __('does not contain', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'starts_with'  => [
                'label'       => __('starts with', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'ends_with'    => [
                'label'       => __('ends with', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'match_pattern' => [
                'label'       => __('matches pattern (regex)', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ],
            'not_match_pattern' => [
                'label'       => __('does not match pattern (regex)', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ],
            'is_empty'     => [
                'label'       => __('is empty', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'is_not_empty' => [
                'label'       => __('is not empty', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
        ];
    }

    public function getDefaultFieldValueEvaluatorLabels()
    {
        return $this->extractEvaluatorLabels($this->defaultFieldValueEvaluators());
    }

    // Evaluators metadata for single-line text fields.
    public function inputtextvalueEvaluators()
    {
        return $this->assignEvaluatorInputType(
            $this->defaultFieldValueEvaluators(),
            'text'
        );
    }

    // Evaluators metadata for multi-line text areas.
    public function textareavalueEvaluators()
    {
        return $this->assignEvaluatorInputType(
            $this->defaultFieldValueEvaluators(),
            'textarea'
        );
    }

    // Evaluators tailored for email fields.
    public function inputemailvalueEvaluators()
    {
        $evaluators = $this->filterEvaluators(
            $this->defaultFieldValueEvaluators(),
            ['equal_to', 'not_equal_to', 'contains', 'not_contains', 'match_pattern', 'not_match_pattern', 'is_empty', 'is_not_empty']
        );

        $evaluators = $this->assignEvaluatorInputType($evaluators, 'email');

        if (isset($evaluators['match_pattern'])) {
            $evaluators['match_pattern']['input_type'] = 'text';
        }
        if (isset($evaluators['not_match_pattern'])) {
            $evaluators['not_match_pattern']['input_type'] = 'text';
        }

        return $evaluators;
    }

    public function inputphonevalueEvaluators()
    {
        $evaluators = $this->filterEvaluators(
            $this->defaultFieldValueEvaluators(),
            ['equal_to', 'not_equal_to', 'contains', 'not_contains', 'match_pattern', 'not_match_pattern', 'is_empty', 'is_not_empty']
        );

        $evaluators = $this->assignEvaluatorInputType($evaluators, 'tel');

        if (isset($evaluators['match_pattern'])) {
            $evaluators['match_pattern']['input_type'] = 'text';
        }
        if (isset($evaluators['not_match_pattern'])) {
            $evaluators['not_match_pattern']['input_type'] = 'text';
        }

        return $evaluators;
    }

    public function inputaddressvalueEvaluators()
    {
        $evaluators = [
            'line1_equals' => [
                'label'       => __('Address Line 1 is equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ],
            'line1_contains' => [
                'label'       => __('Address Line 1 contains', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ],
            'line2_contains' => [
                'label'       => __('Address Line 2 contains', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ],
            'city_equals' => [
                'label'       => __('City is equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ],
            'city_contains' => [
                'label'       => __('City contains', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ],
            'state_equals' => [
                'label'       => __('State / Province is equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ],
            'state_in_list' => [
                'label'       => __('State / Province is in list', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'postal_equals' => [
                'label'       => __('Postal / ZIP Code is equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ],
            'postal_starts_with' => [
                'label'       => __('Postal / ZIP Code starts with', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ],
            'country_equals' => [
                'label'       => __('Country is equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ],
            'country_in_list' => [
                'label'       => __('Country is in list', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'country_not_in_list' => [
                'label'       => __('Country is not in list', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'textarea',
            ],
            'address_is_complete' => [
                'label'       => __('Address is complete', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'address_is_not_complete' => [
                'label'       => __('Address is not complete', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
        ];

        return $evaluators;
    }

    // Evaluators tailored for URL fields.
    public function inputurlvalueEvaluators()
    {
        $evaluators = $this->filterEvaluators(
            $this->defaultFieldValueEvaluators(),
            ['equal_to', 'not_equal_to', 'contains', 'not_contains', 'starts_with', 'ends_with', 'match_pattern', 'not_match_pattern', 'is_empty', 'is_not_empty']
        );

        $evaluators = $this->assignEvaluatorInputType($evaluators, 'url');

        if (isset($evaluators['match_pattern'])) {
            $evaluators['match_pattern']['input_type'] = 'text';
        }
        if (isset($evaluators['not_match_pattern'])) {
            $evaluators['not_match_pattern']['input_type'] = 'text';
        }

        return $evaluators;
    }

    // Evaluators suitable for number-based fields.
    public function inputnumbervalueEvaluators()
    {
        $evaluators = $this->filterEvaluators(
            $this->defaultFieldValueEvaluators(),
            ['equal_to', 'not_equal_to', 'match_pattern', 'not_match_pattern', 'is_empty', 'is_not_empty']
        );

        $evaluators = $this->assignEvaluatorInputType($evaluators, 'number');

        if (isset($evaluators['match_pattern'])) {
            $evaluators['match_pattern']['input_type'] = 'text';
        }
        if (isset($evaluators['not_match_pattern'])) {
            $evaluators['not_match_pattern']['input_type'] = 'text';
        }

        return $evaluators;
    }

    // Evaluators suitable for date fields.
    public function inputdatevalueEvaluators()
    {
        $evaluators = $this->assignEvaluatorInputType(
            $this->filterEvaluators(
                $this->defaultFieldValueEvaluators(),
                ['equal_to', 'not_equal_to', 'is_empty', 'is_not_empty']
            ),
            'date'
        );

        $evaluators = array_merge(
            [
                'before' => [
                    'label'       => __('is before', 'griffinforms-form-builder'),
                    'needs_input' => true,
                    'input_type'  => 'date',
                ],
                'after' => [
                    'label'       => __('is after', 'griffinforms-form-builder'),
                    'needs_input' => true,
                    'input_type'  => 'date',
                ],
            ],
            $evaluators
        );

        return $evaluators;
    }

    // Evaluators suitable for time fields.
    public function inputtimevalueEvaluators()
    {
        return [
            'earlier_than' => [
                'label'       => __('is earlier than', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'time',
            ],
            'later_than' => [
                'label'       => __('is later than', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'time',
            ],
            'is_empty' => [
                'label'       => __('is empty', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'is_not_empty' => [
                'label'       => __('is not empty', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
        ];
    }

    // Evaluators applied to radio choice fields.
    public function inputradiovalueEvaluators()
    {
        return $this->assignEvaluatorInputType(
            $this->filterEvaluators(
                $this->defaultFieldValueEvaluators(),
                ['equal_to', 'not_equal_to', 'is_empty', 'is_not_empty']
            ),
            'choice'
        );
    }

    // Evaluators applied to dropdown choice fields.
    public function selectfieldvalueEvaluators()
    {
        return $this->assignEvaluatorInputType(
            $this->filterEvaluators(
                $this->defaultFieldValueEvaluators(),
                ['equal_to', 'not_equal_to', 'is_empty', 'is_not_empty']
            ),
            'choice'
        );
    }

    // Evaluators specific to checkbox fields.
    public function inputcheckboxvalueEvaluators()
    {
        return [
            'is_checked'     => [
                'label'       => __('Is checked', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'is_not_checked' => [
                'label'       => __('Is not checked', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
        ];
    }

    // Evaluators tailored for Terms and Conditions fields.
    public function termsconditionsvalueEvaluators()
    {
        return [
            'is_accepted' => [
                'label'       => __('Is accepted', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'is_not_accepted' => [
                'label'       => __('Is not accepted', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
        ];
    }

    // Evaluators for signature fields.
    public function signaturevalueEvaluators()
    {
        return [
            'is_signed' => [
                'label'       => __('is signed', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'is_not_signed' => [
                'label'       => __('is not signed', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
        ];
    }

    // Evaluators for rich text fields.
    public function inputrichtextvalueEvaluators()
    {
        return [
            'is_not_empty' => [
                'label'       => __('is not empty', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'is_empty' => [
                'label'       => __('is empty', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'contains' => [
                'label'       => __('contains', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ],
            'does_not_contain' => [
                'label'       => __('does not contain', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'text',
            ],
        ];
    }

    // Evaluators for image selection fields.
    public function imageselectionvalueEvaluators()
    {
        return [
            'contains' => [
                'label'       => __('contains', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'choice',
            ],
            'does_not_contain' => [
                'label'       => __('does not contain', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'choice',
            ],
            'is_empty' => [
                'label'       => __('is empty', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'is_not_empty' => [
                'label'       => __('is not empty', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
        ];
    }

    // Evaluators for Likert scale fields.
    public function inputlikertvalueEvaluators()
    {
        return [
            'is_complete' => [
                'label'       => __('is complete', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'is_not_complete' => [
                'label'       => __('is not complete', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'row_answer_is' => [
                'label'       => __('row answer is', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'likert_row_answer',
            ],
            'row_answer_is_not' => [
                'label'       => __('row answer is not', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'likert_row_answer',
            ],
        ];
    }

    // Evaluators applicable to rating fields.
    public function inputratingvalueEvaluators()
    {
        $numeric_evaluators = [
            'equal_to' => [
                'label'       => __('is equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'not_equal_to' => [
                'label'       => __('is not equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'greater_than' => [
                'label'       => __('is greater than', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'less_than' => [
                'label'       => __('is less than', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'greater_than_or_equal' => [
                'label'       => __('is greater than or equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'less_than_or_equal' => [
                'label'       => __('is less than or equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'is_empty' => [
                'label'       => __('is empty', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
            'is_not_empty' => [
                'label'       => __('is not empty', 'griffinforms-form-builder'),
                'needs_input' => false,
                'input_type'  => null,
            ],
        ];

        return $numeric_evaluators;
    }

    // Evaluators applicable to file upload fields.
    public function fileuploadvalueEvaluators()
    {
        return $this->filterEvaluators(
            $this->defaultFieldValueEvaluators(),
            ['is_empty', 'is_not_empty']
        );
    }

    // Rebuilds a value => label list from rich evaluator metadata.
    protected function extractEvaluatorLabels($evaluators)
    {
        $labels = [];
        if (!is_array($evaluators)) {
            return $labels;
        }

        foreach ($evaluators as $value => $config) {
            if (is_array($config) && array_key_exists('label', $config)) {
                $labels[$value] = $config['label'];
            } else {
                $labels[$value] = $config;
            }
        }

        return $labels;
    }

    // Applies a common input_type to evaluators requiring user input.
    protected function assignEvaluatorInputType(array $evaluators, $input_type)
    {
        foreach ($evaluators as $key => $config) {
            if (!is_array($config)) {
                continue;
            }

            if (!empty($config['needs_input'])) {
                $evaluators[$key]['input_type'] = $input_type;
            }
        }

        return $evaluators;
    }

    // Limits evaluator options to an allowed subset of keys.
    protected function filterEvaluators(array $evaluators, array $allowed_keys)
    {
        if (empty($allowed_keys)) {
            return $evaluators;
        }

        return array_intersect_key($evaluators, array_flip($allowed_keys));
    }

    /* -------- Payment field evaluators -------- */

    public function fieldselected_productEvaluators($field_type = '')
    {
        return $this->extractEvaluatorLabels($this->fieldselected_productEvaluatorConfig($field_type));
    }

    public function fieldselected_productEvaluatorConfig($field_type = '')
    {
        if ('payment' !== strtolower((string) $field_type)) {
            return [];
        }

        return [
            'equal_to' => [
                'label'       => __('is', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'select',
            ],
            'not_equal_to' => [
                'label'       => __('is not', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'select',
            ],
            'contains' => [
                'label'       => __('contains', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'select',
            ],
            'not_contains' => [
                'label'       => __('does not contain', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'select',
            ],
        ];
    }

    public function fieldproduct_quantityEvaluators($field_type = '')
    {
        return $this->extractEvaluatorLabels($this->fieldproduct_quantityEvaluatorConfig($field_type));
    }

    public function fieldproduct_quantityEvaluatorConfig($field_type = '')
    {
        if ('payment' !== strtolower((string) $field_type)) {
            return [];
        }

        return [
            'less_than' => [
                'label'       => __('is less than', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'more_than' => [
                'label'       => __('is greater than', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'equal_to' => [
                'label'       => __('is equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
        ];
    }

    public function fieldtotal_amountEvaluators($field_type = '')
    {
        return $this->extractEvaluatorLabels($this->fieldtotal_amountEvaluatorConfig($field_type));
    }

    public function fieldtotal_amountEvaluatorConfig($field_type = '')
    {
        if ('payment' !== strtolower((string) $field_type)) {
            return [];
        }

        return [
            'less_than' => [
                'label'       => __('is less than', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'more_than' => [
                'label'       => __('is greater than', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'equal_to' => [
                'label'       => __('is equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
        ];
    }

    public function fieldselection_countEvaluators($field_type = '')
    {
        return $this->extractEvaluatorLabels($this->fieldselection_countEvaluatorConfig($field_type));
    }

    public function fieldselection_countEvaluatorConfig($field_type = '')
    {
        if ('payment' !== strtolower((string) $field_type)) {
            return [];
        }

        return [
            'less_than' => [
                'label'       => __('is less than', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'more_than' => [
                'label'       => __('is greater than', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
            'equal_to' => [
                'label'       => __('is equal to', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'number',
            ],
        ];
    }

    public function fieldselected_gatewayEvaluators($field_type = '')
    {
        return $this->extractEvaluatorLabels($this->fieldselected_gatewayEvaluatorConfig($field_type));
    }

    public function fieldselected_gatewayEvaluatorConfig($field_type = '')
    {
        if ('payment' !== strtolower((string) $field_type)) {
            return [];
        }

        return [
            'equal_to' => [
                'label'       => __('is', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'select',
            ],
            'not_equal_to' => [
                'label'       => __('is not', 'griffinforms-form-builder'),
                'needs_input' => true,
                'input_type'  => 'select',
            ],
        ];
    }

    public function getConditionInput($item_type, $attr, $condition, $context = [])
    {
        $context = is_array($context) ? $context : [];
        $field_type = isset($context['field_type']) ? (string) $context['field_type'] : '';

        $evaluators = [];
        $method = $item_type . $attr . 'EvaluatorConfig';

        if (method_exists($this, $method)) {
            $evaluators = $this->$method($field_type);
        } elseif ('field' === $item_type && 'value' === $attr) {
            $evaluators = $this->fieldValueEvaluatorConfig($field_type);
        }

        if (!is_array($evaluators) || empty($evaluators)) {
            $evaluators = $this->defaultFieldValueEvaluators();
        }

        $config = isset($evaluators[$condition]) ? $evaluators[$condition] : null;

        $needs_input = false;
        $input_type = null;

        if (is_array($config)) {
            $needs_input = !empty($config['needs_input']);
            if ($needs_input && isset($config['input_type']) && '' !== (string) $config['input_type']) {
                $input_type = (string) $config['input_type'];
            }
        }

        return [
            'needs_input' => $needs_input,
            'input_type'  => $needs_input ? $input_type : null,
        ];
    }
}
