<?php

namespace GriffinForms\Frontend\Language;

class Field extends \GriffinForms\Frontend\Language\Format
{
        
    protected function numberErrorText()
    {
        return __('Only numbers are allowed.', 'griffinforms-form-builder');
    }
    
    protected function requiredErrorText()
    {
        return __('This field is required.', 'griffinforms-form-builder');
    }
    
    protected function minNoErrorText($data)
    {
        // translators: %d refers to the minimum value required for the input
        return sprintf(__('Minimum value is %d.', 'griffinforms-form-builder'), $data['min']);
    }
    
    protected function maxNoErrorText($data)
    {
        // translators: %d refers to the maximum value allowed for the input
        return sprintf(__('Maximum value is %d.', 'griffinforms-form-builder'), $data['max']);
    }
    
    protected function oddNoErrorText($data)
    {
        return __('Only odd numbers allowed.', 'griffinforms-form-builder');
    }
    
    protected function evenNoErrorText($data)
    {
        return __('Only even numbers allowed.', 'griffinforms-form-builder');
    }
    
    protected function wholeNoErrorText()
    {
        return __('Decimals not allowed.', 'griffinforms-form-builder');
    }
    
    protected function patternErrorText()
    {
        return __('Invalid format.', 'griffinforms-form-builder');
    }
    
    protected function multiplesOfErrorText($data)
    {
        $multiples = implode(',', $data['multiples']);
        // translators: %s refers to the allowed multiples (e.g., 2, 4, 6)
        return sprintf(__('Only multiples of %s allowed.', 'griffinforms-form-builder'), $multiples);
    }
    
    protected function uniqueErrorText()
    {
        return __('Only unique values allowed.', 'griffinforms-form-builder');
    }
    
    protected function dbValidateErrorText()
    {
        return __('Invalid Value.', 'griffinforms-form-builder');
    }

    protected function minMaxSelectErrorText($data)
    {
        $min = absint($data['min_selections'] ?? 0);
        $max = absint($data['max_selections'] ?? 0);

        if ($min > 0 && $max > 0 && $min === $max) {
            return sprintf(
                _n('Select exactly %d option.', 'Select exactly %d options.', $min, 'griffinforms-form-builder'),
                $min
            );
        }

        if ($min > 0 && $max > 0) {
            return sprintf(
                /* translators: 1: minimum selections, 2: maximum selections */
                __('Select between %1$d and %2$d options.', 'griffinforms-form-builder'),
                $min,
                $max
            );
        }

        if ($min > 0) {
            return sprintf(
                _n('Select at least %d option.', 'Select at least %d options.', $min, 'griffinforms-form-builder'),
                $min
            );
        }

        if ($max > 0) {
            return sprintf(
                _n('Select no more than %d option.', 'Select no more than %d options.', $max, 'griffinforms-form-builder'),
                $max
            );
        }

        return __('Invalid selection count.', 'griffinforms-form-builder');
    }
    
    protected function minErrorText($data)
    {
        if (isset($data['messages']['min']) && $data['messages']['min'] !== '') {
            return $this->replacePasswordTokens($data['messages']['min'], $data);
        }
        // translators: %d refers to the minimum number of characters required for the input field.
        return sprintf(__('Minimum %d characters required.', 'griffinforms-form-builder'), $data['min']);
    }

    protected function maxErrorText($data)
    {
        if (isset($data['messages']['max']) && $data['messages']['max'] !== '') {
            return $this->replacePasswordTokens($data['messages']['max'], $data);
        }
        // translators: %d refers to the maximum number of characters allowed
        return sprintf(__('Maximum %d characters allowed.', 'griffinforms-form-builder'), $data['max']);
    }
    
    protected function noNumbersErrorText($data)
    {
        return __('Numbers are not allowed.', 'griffinforms-form-builder');
    }
    
    protected function noSpacesErrorText($data)
    {
        return __('Spaces are not allowed.', 'griffinforms-form-builder');
    }
    
    protected function noSplCharsErrorText($data)
    {
        return __('Special characters are not allowed.', 'griffinforms-form-builder');
    }
    
    protected function excludeCharsErrorText($data)
    {
        // translators: %s refers to the list of characters that are not allowed
        return sprintf(__('These characters are not allowed - %s', 'griffinforms-form-builder'), $data['exclude']);
    }
    
    protected function emailErrorText($data)
    {
        return __('Please enter a valid email.', 'griffinforms-form-builder');
    }

    protected function phoneErrorText($data)
    {
        return __('Please enter a valid phone number.', 'griffinforms-form-builder');
    }

    protected function mindigitsErrorText($data)
    {
        if (empty($data['min_digits'])) {
            return __('The phone number is shorter than allowed.', 'griffinforms-form-builder');
        }
        // translators: %d refers to the minimum number of digits required for the phone number.
        return sprintf(__('Enter at least %d digits.', 'griffinforms-form-builder'), absint($data['min_digits']));
    }

    protected function maxdigitsErrorText($data)
    {
        if (empty($data['max_digits'])) {
            return __('The phone number is longer than allowed.', 'griffinforms-form-builder');
        }
        // translators: %d refers to the maximum number of digits allowed for the phone number.
        return sprintf(__('Enter no more than %d digits.', 'griffinforms-form-builder'), absint($data['max_digits']));
    }

    protected function formattypeErrorText($data)
    {
        $format_type = isset($data['format_type']) ? $data['format_type'] : '';

        switch ($format_type) {
            case 'international_format':
                return __('Use the international format (for example, +14155552671).', 'griffinforms-form-builder');
            case 'national_format':
                return __('Use the national format without an international country code.', 'griffinforms-form-builder');
            default:
                return __('The phone number format is invalid.', 'griffinforms-form-builder');
        }
    }

    protected function extensionErrorText($data)
    {
        return __('Extensions are not allowed in this phone number.', 'griffinforms-form-builder');
    }

    protected function allowedcountrycodesErrorText($data)
    {
        if (empty($data['allowed_country_codes']) || !is_array($data['allowed_country_codes'])) {
            return __('The phone number must start with an allowed country code.', 'griffinforms-form-builder');
        }

        $codes = implode(', ', array_map('trim', $data['allowed_country_codes']));
        // translators: %s refers to the allowed country codes for the phone number.
        return sprintf(__('The phone number must start with one of the following country codes: %s.', 'griffinforms-form-builder'), $codes);
    }
    
    protected function restrictedDomainsErrorText($data)
    {
        $list = implode(', ', $data['restricted_domains']);
        // translators: %s refers to the list of allowed email domains
        return sprintf(__('Only following email domains are allowed - <em> %s </em>.', 'griffinforms-form-builder'), $list);
    }
    
    protected function excludedDomainsErrorText($data)
    {
        $domain = '';
        if (isset($data['email_domain']) && is_string($data['email_domain']) && trim($data['email_domain']) !== '') {
            $domain = trim($data['email_domain']);
        } elseif (isset($data['excluded_domains']) && is_array($data['excluded_domains']) && !empty($data['excluded_domains'][0])) {
            $domain = trim((string) $data['excluded_domains'][0]);
        } else {
            $domain = __('This email domain', 'griffinforms-form-builder');
        }

        // translators: %s refers to the email domain that is not allowed
        return sprintf(__('<em>%s</em> emails are not allowed.', 'griffinforms-form-builder'), $domain);
    }
    
    protected function urlErrorText($data)
    {
        return __('Please enter a valid url.', 'griffinforms-form-builder');
    }
    
    protected function protocolsErrorText($data)
    {
        if (count($data['protocols']) > 1) {
            $list = implode(', ', $data['protocols']);
            // translators: %s refers to the list of allowed URL protocols (e.g., http, https)
            return sprintf(__('The URL must begin with one of the following <em>%s</em>.', 'griffinforms-form-builder'), $list);
        } else {
            // translators: %s refers to the allowed URL protocol (e.g., https://)
            return sprintf(__('The URL must begin with <em>%s</em>.', 'griffinforms-form-builder'), $data['protocols'][0] . '://');
        }
    }
    
    protected function restrictedTldsErrorText($data)
    {
        if (count($data['restricted_tld']) > 1) {
            $list = implode(', ', $data['restricted_tld']);
            // translators: %s refers to the list of allowed top-level domains (TLDs) (e.g., .com, .org)
            return sprintf(__('The URL must end with one of the following <em>%s</em>.', 'griffinforms-form-builder'), $list);
        } else {
            // translators: %s refers to the allowed top-level domain (TLD) (e.g., .com)
            return sprintf(__('The URL must end with <em>%s</em>.', 'griffinforms-form-builder'), $data['restricted_tld'][0]);
        }
    }
    
    protected function excludedTldsErrorText($data)
    {
        if (count($data['excluded_tld']) > 1) {
            $list = implode(', ', $data['excluded_tld']);
            // translators: %s refers to the list of excluded top-level domains (TLDs) (e.g., .com, .org)
            return sprintf(__('The URL must not end with one of the following <em>%s</em>.', 'griffinforms-form-builder'), $list);
        } else {
            // translators: %s refers to the excluded top-level domain (TLD) (e.g., .com)
            return sprintf(__('The URLs ending with <em>%s</em> are not accepted.', 'griffinforms-form-builder'), $data['excluded_tld'][0]);
        }
    }
    
    protected function dateErrorText($data)
    {
        return __('Please enter a valid date.', 'griffinforms-form-builder');
    }
    
    protected function minChecksErrorText($data)
    {
        // Translators: %1$d refers to the minimum number of checkbox options to select, %2$s refers to the number of options currently selected.
        return sprintf(__('Please select a minimum of %1$d options. You have selected <span>%2$s</span>.', 'griffinforms-form-builder'), $data['min_checks'], 0);
    }
    
    protected function maxChecksErrorText($data)
    {
        // Translators: %1$d refers to the maximum number of checkbox options to select, %2$s refers to the number of options currently selected.
        return sprintf(__('Please select a maximum of %1$d options. You have selected <span>%2$s</span>.', 'griffinforms-form-builder'), $data['max_checks'], 0);
    }
    
    protected function minCharsErrorText($data)
    {
        // translators: %d refers to the minimum number of characters required for input text field.
        return sprintf(__('A minimum of %d characters are required.', 'griffinforms-form-builder'), $data['min_chars']);
    }
    
    protected function maxCharsErrorText($data)
    {
        // translators: %d refers to the maximum number of characters allowed for input text field.
        return sprintf(__('A maximum of %d characters are allowed.', 'griffinforms-form-builder'), $data['max_chars']);
    }
    
    protected function minDateErrorText($data)
    {
        // translators: %s refers to the minimum allowed date for date field in the format specified by the site settings
        return sprintf(__('Selected date cannot be earlier than %s', 'griffinforms-form-builder'), wp_date(get_option('date_format'), $data['min']));
    }
    
    protected function maxDateErrorText($data)
    {
        // translators: %s refers to the maximum allowed date in the format specified by the site settings
        return sprintf(__('Selected date cannot be later than %s', 'griffinforms-form-builder'), wp_date(get_option('date_format'), $data['max']));
    }
    
    protected function dayTypeErrorText($data)
    {
        // translators: %s refers to the type of day (e.g., weekday, weekend, Monday) that the selected date should fall on
        return sprintf(__('Selected date should fall on %s', 'griffinforms-form-builder'), ucfirst($data['day_type']));
    }
    
    protected function relativeMinDateErrorText($data)
    {
        return __('Selected date is earlier than the allowed minimum date.', 'griffinforms-form-builder');
    }
    
    protected function relativeMaxDateErrorText($data)
    {
        return __('Selected date is later than the allowed maximum date.', 'griffinforms-form-builder');
    }

    protected function minTimeErrorText($data)
    {
        $min_time_24h = gmdate('H:i', $data['min']);
        $min_time_12h = gmdate('h:i A', $data['min']);
        // translators: %1$s refers to the minimum allowed time in 24-hour format, %2$s refers to the same time in 12-hour format
        return sprintf(__('Selected time cannot be earlier than %1$s (%2$s)', 'griffinforms-form-builder'), $min_time_24h, $min_time_12h);
    }

    protected function maxTimeErrorText($data)
    {
        $max_time_24h = gmdate('H:i', $data['max']);
        $max_time_12h = gmdate('h:i A', $data['max']);
        // translators: %1$s refers to the maximum allowed time in 24-hour format, %2$s refers to the same time in 12-hour format
        return sprintf(__('Selected time cannot be later than %1$s (%2$s)', 'griffinforms-form-builder'), $max_time_24h, $max_time_12h);
    }

    protected function invalidTimeErrorText($data)
    {
        return __('Invalid time format.', 'griffinforms-form-builder');
    }

    protected function invalidMaxTime($data)
    {
        return __('Maximum time cannot be earlier than minimum time.', 'griffinforms-form-builder');
    }

    protected function addressLine1DefaultLabelText()
    {
        return __('Address Line 1', 'griffinforms-form-builder');
    }

    protected function addressLine2DefaultLabelText()
    {
        return __('Address Line 2', 'griffinforms-form-builder');
    }

    protected function addressCityDefaultLabelText()
    {
        return __('City', 'griffinforms-form-builder');
    }

    protected function addressStateDefaultLabelText()
    {
        return __('State / Province', 'griffinforms-form-builder');
    }

    protected function addressPostalDefaultLabelText()
    {
        return __('Postal Code', 'griffinforms-form-builder');
    }

    protected function addressCountryDefaultLabelText()
    {
        return __('Country', 'griffinforms-form-builder');
    }

    protected function addressCountryPlaceholderText()
    {
        return __('Select a country', 'griffinforms-form-builder');
    }

    protected function addressStatePlaceholderText()
    {
        return __('Select an option', 'griffinforms-form-builder');
    }

    protected function minRatingErrorText($data)
    {
        $min = isset($data['validation_value']) ? rtrim(rtrim(number_format((float) $data['validation_value'], 1, '.', ''), '0'), '.') : '1';
        // translators: %s refers to the minimum rating value required
        return sprintf(__('Please select at least %s.', 'griffinforms-form-builder'), $min);
    }

    protected function countryFilterErrorText($data)
    {
        return __('The selected country is not available for this field.', 'griffinforms-form-builder');
    }

    protected function allowedSetsErrorText($data)
    {
        if (isset($data['messages']['allowed_sets']) && $data['messages']['allowed_sets'] !== '') {
            return $this->replacePasswordTokens($data['messages']['allowed_sets'], $data);
        }
        return __('Remove characters that are not permitted in this password.', 'griffinforms-form-builder');
    }

    protected function requireUppercaseErrorText($data)
    {
        if (isset($data['messages']['require_uppercase']) && $data['messages']['require_uppercase'] !== '') {
            return $this->replacePasswordTokens($data['messages']['require_uppercase'], $data);
        }
        return __('Your password must include at least one uppercase letter.', 'griffinforms-form-builder');
    }

    protected function requireLowercaseErrorText($data)
    {
        if (isset($data['messages']['require_lowercase']) && $data['messages']['require_lowercase'] !== '') {
            return $this->replacePasswordTokens($data['messages']['require_lowercase'], $data);
        }
        return __('Your password must include at least one lowercase letter.', 'griffinforms-form-builder');
    }

    protected function requireNumberErrorText($data)
    {
        if (isset($data['messages']['require_number']) && $data['messages']['require_number'] !== '') {
            return $this->replacePasswordTokens($data['messages']['require_number'], $data);
        }
        return __('Your password must include at least one number.', 'griffinforms-form-builder');
    }

    protected function requireSymbolErrorText($data)
    {
        if (isset($data['messages']['require_symbol']) && $data['messages']['require_symbol'] !== '') {
            return $this->replacePasswordTokens($data['messages']['require_symbol'], $data);
        }
        return __('Your password must include at least one symbol.', 'griffinforms-form-builder');
    }

    protected function disallowedCharsErrorText($data)
    {
        if (isset($data['messages']['disallowed_chars']) && $data['messages']['disallowed_chars'] !== '') {
            return $this->replacePasswordTokens($data['messages']['disallowed_chars'], $data);
        }
        return __('Remove the blocked characters from your password.', 'griffinforms-form-builder');
    }

    protected function strengthRequirementErrorText($data)
    {
        if (isset($data['messages']['min_strength']) && $data['messages']['min_strength'] !== '') {
            return $this->replacePasswordTokens($data['messages']['min_strength'], $data);
        }

        $strength = isset($data['min_strength']) ? $data['min_strength'] : 'weak';
        $label = $this->passwordStrengthLabel($strength);
        return sprintf(__('Your password must reach at least %s strength.', 'griffinforms-form-builder'), $label);
    }

    protected function confirmationErrorText($data)
    {
        if (isset($data['messages']['confirmation']) && $data['messages']['confirmation'] !== '') {
            return sanitize_text_field($data['messages']['confirmation']);
        }

        if (isset($data['field_settings']['confirmation_message']) && $data['field_settings']['confirmation_message'] !== '') {
            return sanitize_text_field($data['field_settings']['confirmation_message']);
        }

        return __('Your passwords do not match.', 'griffinforms-form-builder');
    }

    protected function passwordStrengthLabelWeakText()
    {
        return __('Weak', 'griffinforms-form-builder');
    }

    protected function passwordStrengthLabelMediumText()
    {
        return __('Medium', 'griffinforms-form-builder');
    }

    protected function passwordStrengthLabelStrongText()
    {
        return __('Strong', 'griffinforms-form-builder');
    }

    protected function passwordStrengthLabelVeryStrongText()
    {
        return __('Very strong', 'griffinforms-form-builder');
    }

    protected function passwordStrengthLabel($level)
    {
        switch ($level) {
            case 'very_strong':
                return $this->passwordStrengthLabelVeryStrongText();
            case 'strong':
                return $this->passwordStrengthLabelStrongText();
            case 'medium':
                return $this->passwordStrengthLabelMediumText();
            default:
                return $this->passwordStrengthLabelWeakText();
        }
    }

    protected function passwordConfirmationLabelDefaultText()
    {
        return __('Confirm Password', 'griffinforms-form-builder');
    }

    protected function passwordConfirmationMessageDefaultText()
    {
        return __('Your passwords do not match.', 'griffinforms-form-builder');
    }

    private function replacePasswordTokens($message, $data)
    {
        if (!is_string($message) || $message === '') {
            return '';
        }

        $replacements = array(
            '{{min}}' => isset($data['min']) ? absint($data['min']) : '',
            '{{max}}' => isset($data['max']) ? absint($data['max']) : '',
            '{{strength}}' => $this->passwordStrengthLabel(isset($data['min_strength']) ? $data['min_strength'] : 'weak')
        );

        return strtr($message, $replacements);
    }

}
