<?php

namespace WeDevs\Wpuf\Pro\Fields;

/**
 * Password Field Class
 *
 * @since 3.1.0
 **/
class Field_Password extends Pro_Field_Contract {

    public function __construct() {
        $this->name       = __( 'Password', 'wpuf-pro' );
        $this->input_type = 'password';
        $this->icon       = 'lock-closed';
    }

    /**
     * Render the Password field
     *
     * @param array   $field_settings
     * @param integer $form_id
     * @param string  $type
     * @param integer $post_id
     *
     * @return void
     */
    public function render( $field_settings, $form_id, $type = 'post', $post_id = null ) {
        // Migrate minimum_strength to new settings if needed
        $field_settings = self::migrate_minimum_strength( $field_settings );
        $value                     = $field_settings['default'];
        $repeat_pass               = ! empty( $field_settings['repeat_pass'] ) ? $field_settings['repeat_pass'] : 'no';
        $minimum_length            = ! empty( $field_settings['min_length'] ) ? $field_settings['min_length'] : 0;
        $require_uppercase         = ! empty( $field_settings['require_uppercase'] ) ? $field_settings['require_uppercase'] : 'no';
        $require_lowercase         = ! empty( $field_settings['require_lowercase'] ) ? $field_settings['require_lowercase'] : 'no';
        $require_number            = ! empty( $field_settings['require_number'] ) ? $field_settings['require_number'] : 'no';
        $require_special_char      = ! empty( $field_settings['require_special_char'] ) ? $field_settings['require_special_char'] : 'no';
        $disallow_common_passwords = ! empty( $field_settings['disallow_common_passwords'] ) ? $field_settings['disallow_common_passwords'] : 'no';
        // Get common passwords list if needed
        $common_passwords = [];
        if ( 'yes' === $disallow_common_passwords ) {
            $common_passwords = self::get_common_passwords();
        }

        // Determine if any password requirements are enabled
        $has_requirements = 'yes' === $require_uppercase || 'yes' === $require_lowercase || 'yes' === $require_number || 'yes' === $require_special_char || 'yes' === $disallow_common_passwords;

        // Password strength settings
        $pass_strength    = ! empty( $field_settings['pass_strength'] ) && 'yes' === $field_settings['pass_strength'];
        $minimum_strength = ! empty( $field_settings['minimum_strength'] ) ? $field_settings['minimum_strength'] : '';

        // Enqueue strength meter scripts when needed
        if ( $pass_strength || ! empty( $minimum_strength ) ) {
            wp_enqueue_script( 'zxcvbn' );
            wp_enqueue_script( 'password-strength-meter' );
        }

        $field_settings['required'] = ! empty( $field_settings['required'] ) ? $field_settings['required'] : 'yes';
        $eye_icon_src               = file_exists(
            WPUF_ROOT . '/assets/images/eye.svg'
        ) ? WPUF_ASSET_URI . '/images/eye.svg' : '';
        ?>

        <li <?php $this->print_list_attributes( $field_settings ); ?>>
            <?php $this->print_label( $field_settings, $form_id ); ?>

            <div class="wpuf-fields">
                <div class="wpuf-fields-inline" style="position: relative;">
                    <input
                        class="password <?php echo ' wpuf_' . $field_settings['name'] . '_' . $form_id; ?>"
                        id="<?php echo $field_settings['name'] . '_' . $form_id . '_1'; ?>"
                        type="password"
                        data-required="<?php echo $field_settings['required']; ?>"
                        data-type="password"
                        data-repeat="<?php echo $repeat_pass; ?>"
                        data-minimum-length="<?php echo $minimum_length; ?>"
                        data-require-uppercase="<?php echo esc_attr( $require_uppercase ); ?>"
                        data-require-lowercase="<?php echo esc_attr( $require_lowercase ); ?>"
                        data-require-number="<?php echo esc_attr( $require_number ); ?>"
                        data-require-special-char="<?php echo esc_attr( $require_special_char ); ?>"
                        data-disallow-common-passwords="<?php echo esc_attr( $disallow_common_passwords ); ?>"
                        placeholder="<?php echo esc_attr( $field_settings['placeholder'] ); ?>"
                        value=""
                        size="<?php echo esc_attr( $field_settings['size'] ); ?>"
                        name="pass1"
                    />
                    <?php
                    if ( $eye_icon_src ) {
                        ?>
                        <img class="wpuf-eye" src="<?php echo esc_url( $eye_icon_src ); ?>" alt="">
                        <?php
                    }
                    ?>
                </div>

                <span class="wpuf-wordlimit-message wpuf-help"></span>
                <?php
                if ( $has_requirements ) {
                    ?>
                    <div class="wpuf-password-requirements" id="wpuf-password-requirements_<?php echo $form_id; ?>">
                        <?php if ( 'yes' === $require_uppercase ) { ?>
                            <div class="wpuf-password-req-item" data-requirement="uppercase">
                                <span class="wpuf-req-icon">✗</span>
                                <span class="wpuf-req-text"><?php esc_html_e(
                                        'Uppercase letter', 'wpuf-pro'
                                    ); ?></span>
                            </div>
                        <?php } ?>
                        <?php if ( 'yes' === $require_lowercase ) { ?>
                            <div class="wpuf-password-req-item" data-requirement="lowercase">
                                <span class="wpuf-req-icon">✗</span>
                                <span class="wpuf-req-text"><?php esc_html_e(
                                        'Lowercase letter', 'wpuf-pro'
                                    ); ?></span>
                            </div>
                        <?php } ?>
                        <?php if ( 'yes' === $require_number ) { ?>
                            <div class="wpuf-password-req-item" data-requirement="number">
                                <span class="wpuf-req-icon">✗</span>
                                <span class="wpuf-req-text"><?php esc_html_e( 'Number', 'wpuf-pro' ); ?></span>
                            </div>
                        <?php } ?>
                        <?php if ( 'yes' === $require_special_char ) { ?>
                            <div class="wpuf-password-req-item" data-requirement="special">
                                <span class="wpuf-req-icon">✗</span>
                                <span class="wpuf-req-text"><?php esc_html_e(
                                        'Special character', 'wpuf-pro'
                                    ); ?></span>
                            </div>
                        <?php } ?>
                        <?php if ( 'yes' === $disallow_common_passwords ) { ?>
                            <div class="wpuf-password-req-item" data-requirement="common">
                                <span class="wpuf-req-icon">✗</span>
                                <span class="wpuf-req-text"><?php esc_html_e(
                                        'Not a common password', 'wpuf-pro'
                                    ); ?></span>
                            </div>
                        <?php } ?>
                    </div>
                    <?php
                }
                ?>
                <?php $this->help_text( $field_settings ); ?>
            </div>
        </li>

        <?php if ( 'yes' === $repeat_pass ) { ?>

            <?php
            $confirm_pass_field_settings          = $field_settings;
            $confirm_pass_field_settings['label'] = __( 'Confirm Password', 'wpuf-pro' );
            $confirm_pass_field_settings['name']  = 'confirm_password';
            $re_pass_placeholder                  = ! empty( $field_settings['re_pass_placeholder'] ) ? esc_attr(
                $field_settings['re_pass_placeholder']
            ) : '';
            $re_pass_help                         = ! empty( $field_settings['re_pass_help'] ) ? esc_attr(
                $field_settings['re_pass_help']
            ) : '';
            ?>

            <li <?php $this->print_list_attributes( $confirm_pass_field_settings ); ?>>
                <?php
                // Use the confirm password field settings but with the re_pass_label
                $confirm_pass_field_settings['label'] = $field_settings['re_pass_label'];
                $this->print_label( $confirm_pass_field_settings, $form_id );
                ?>

                <div class="wpuf-fields">
                    <input
                        id="<?php echo $field_settings['name'] . '_' . $form_id . '_2'; ?>"
                        class="password <?php echo ' wpuf_' . $field_settings['name'] . '_' . $form_id; ?>"
                        type="password"
                        placeholder="<?php echo esc_attr( $re_pass_placeholder ); ?>"
                        data-required="<?php echo $field_settings['required']; ?>"
                        data-type="confirm_password" name="pass2"
                        value=""
                        size="<?php echo esc_attr( $field_settings['size'] ); ?>"
                    />

                    <span class="wpuf-wordlimit-message wpuf-help"></span>
                    <?php if ( 'yes' === $repeat_pass ) { ?>
                        <span class="wpuf-password-match-message" id="wpuf-password-match_<?php echo $form_id; ?>"
                              style="display: none;"></span>
                    <?php } ?>
                    <span class="wpuf-help"><?php echo esc_html( $re_pass_help ); ?></span>
                </div>
            </li>

            <?php
            wp_enqueue_style( 'wpuf-password-fields' );
        }

        // Enqueue JavaScript for password requirements validation and password matching
        if ( $has_requirements || 'yes' === $repeat_pass ) {
            wp_enqueue_script( 'wpuf-password-fields' );
            wp_localize_script( 'wpuf-password-fields', 'wpufPasswordFields', [
                'matched'          => __( 'Password Matched', 'wpuf-pro' ),
                'mismatch'         => __( 'Password doesn\'t match', 'wpuf-pro' ),
                'commonPasswords'  => $common_passwords,
            ] );
        }

        if ( $pass_strength && ! $has_requirements ) {
            ?>

            <li>
                <div class="wpuf-label">&nbsp;</div>
                <div class="wpuf-fields">
                    <div class="pass-strength-result" id="pass-strength-result_<?php echo $form_id; ?>" style="display: block"><?php esc_html_e( 'Strength indicator', 'wpuf-pro' ); ?></div>
                </div>
            </li>

            <script type="text/javascript">
                jQuery(function($) {
                    function check_pass_strength() {
                        var pass1 = $("#<?php echo $field_settings['name'] . '_' . $form_id . '_1'; ?>").val(),
                            pass2 = $("#<?php echo $field_settings['name'] . '_' . $form_id . '_2'; ?>").val(),
                            strength;
                        var minimumStrength = "<?php echo $minimum_strength; ?>";
                        var strengthField = "#pass-strength-result_<?php echo $form_id; ?>";

                        if ( typeof pass2 === 'undefined' ) {
                            pass2 = pass1;
                        }

                        $( strengthField ).removeClass('short bad good strong');
                        if (!pass1) {
                            $( strengthField ).html(pwsL10n.empty);
                            return;
                        }

                        if ( ! minimumStrength ) {
                            return;
                        }

                        strength = wp.passwordStrength.meter(pass1, wp.passwordStrength.userInputDisallowedList(), pass2);

                        switch (strength) {
                            case 2:
                                $( strengthField ).addClass('bad').html(pwsL10n.bad);
                                break;
                            case 3:
                                $( strengthField ).addClass('good').html(pwsL10n.good);
                                break;
                            case 4:
                                $( strengthField ).addClass('strong').html(pwsL10n.strong);
                                break;
                            case 5:
                                $( strengthField ).addClass('short').html(pwsL10n.mismatch);
                                break;
                            default:
                                $( strengthField ).addClass('short').html(pwsL10n['short']);
                        }

                        var passwordField = "#<?php echo $field_settings['name'] . '_' . $form_id . '_1'; ?>";

                        WP_User_Frontend.removeErrors($(passwordField).closest('li'));

                        switch ( minimumStrength ) {
                            case 'weak':
                                if ( strength < 2 ) {
                                    WP_User_Frontend.markError(passwordField, 'custom', wpuf_frontend.password_warning_weak);
                                }
                                break;
                            case 'medium':
                                if ( strength < 3 ) {
                                    WP_User_Frontend.markError(passwordField, 'custom', wpuf_frontend.password_warning_medium);
                                }
                                break;
                            case 'strong':
                                if ( strength < 4 ) {
                                    WP_User_Frontend.markError(passwordField, 'custom', wpuf_frontend.password_warning_strong);
                                }
                                break;
                        }
                    }

                    $("#<?php echo $field_settings['name'] . '_' . $form_id . '_1'; ?>").val('').keyup(check_pass_strength);
                    $("#<?php echo $field_settings['name'] . '_' . $form_id . '_2'; ?>").val('').keyup(check_pass_strength);
                    $( "#pass-strength-result_<?php echo $form_id; ?>" ).show();
                });
            </script>
            <?php
        }
    }

    /**
     * It's a full width block
     *
     * @return void
     **/
    public function is_full_width() {
        return true;
    }

    /**
     * Get field options setting
     *
     * @return array
     **/
    public function get_options_settings() {
        $default_options      = $this->get_default_option_settings( false, [ 'dynamic' ] );
        $default_text_options = $this->get_default_text_option_settings();
        $settings             = [
            [
                'name'     => 'min_length',
                'title'    => __( 'Minimum password length', 'wpuf-pro' ),
                'type'     => 'text',
                'section'  => 'advanced',
                'priority' => 23,
            ],
            [
                'name'          => 'require_uppercase',
                'type'          => 'checkbox',
                'options'       => [ 'yes' => __( 'Require Uppercase Letter', 'wpuf-pro' ) ],
                'is_single_opt' => true,
                'section'       => 'advanced',
                'priority'      => 23.1,
                'help_text'     => __( 'Enforce at least one A–Z', 'wpuf-pro' ),
            ],
            [
                'name'          => 'require_lowercase',
                'type'          => 'checkbox',
                'options'       => [ 'yes' => __( 'Require Lowercase Letter', 'wpuf-pro' ) ],
                'is_single_opt' => true,
                'section'       => 'advanced',
                'priority'      => 23.2,
                'help_text'     => __( 'Enforce at least one a–z', 'wpuf-pro' ),
            ],
            [
                'name'          => 'require_number',
                'type'          => 'checkbox',
                'options'       => [ 'yes' => __( 'Require Number', 'wpuf-pro' ) ],
                'is_single_opt' => true,
                'section'       => 'advanced',
                'priority'      => 23.3,
                'help_text'     => __( 'Enforce at least one digit (0–9)', 'wpuf-pro' ),
            ],
            [
                'name'          => 'require_special_char',
                'type'          => 'checkbox',
                'options'       => [ 'yes' => __( 'Require Special Character', 'wpuf-pro' ) ],
                'is_single_opt' => true,
                'section'       => 'advanced',
                'priority'      => 23.4,
                'help_text'     => __( 'Enforce at least one symbol (e.g. @, #, $, %)', 'wpuf-pro' ),
            ],
            [
                'name'          => 'disallow_common_passwords',
                'type'          => 'checkbox',
                'options'       => [ 'yes' => __( 'Disallow Common Passwords and Patterns', 'wpuf-pro' ) ],
                'is_single_opt' => true,
                'section'       => 'advanced',
                'priority'      => 23.5,
                'help_text'     => __( 'Block weak/common passwords', 'wpuf-pro' ),
            ],
            [
                'name'          => 'repeat_pass',
                'title'         => __( 'Password Re-type', 'wpuf-pro' ),
                'type'          => 'checkbox',
                'options'       => [ 'yes' => __( 'Require Password repeat', 'wpuf-pro' ) ],
                'is_single_opt' => true,
                'section'       => 'advanced',
                'priority'      => 24,
            ],
            [
                'name'     => 're_pass_label',
                'title'    => __( 'Re-type password label', 'wpuf-pro' ),
                'type'     => 'text',
                'section'  => 'advanced',
                'priority' => 25,
            ],
            [
                'name'      => 're_pass_placeholder',
                'title'     => __( 'Re-type password placeholder', 'wpuf-pro' ),
                'type'      => 'text',
                'section'   => 'advanced',
                'priority'  => 25.1,
                'help_text' => __( 'Text for HTML5 placeholder attribute', 'wpuf-pro' ),
            ],
            [
                'name'      => 're_pass_help',
                'title'     => __( 'Re-type password help', 'wpuf-pro' ),
                'type'      => 'text',
                'section'   => 'basic',
                'priority'  => 20.1,
                'help_text' => __( 'Give the user some information about this field', 'wpuf-pro' ),
            ],
            [
                'name'          => 'pass_strength',
                'title'         => __( 'Password Strength Meter', 'wpuf-pro' ),
                'type'          => 'checkbox',
                'options'       => [ 'yes' => __( 'Show password strength meter', 'wpuf-pro' ) ],
                'is_single_opt' => true,
                'section'       => 'advanced',
                'priority'      => 26,
            ],
        ];

        return array_merge( $default_options, $default_text_options, $settings );
    }

    /**
     * Get the field props
     *
     * @return array
     **/
    public function get_field_props() {
        $defaults = $this->default_attributes();
        $props    = [
            'input_type'                => 'password',
            'name'                      => 'password',
            'required'                  => 'yes',
            'is_meta'                   => 'no',
            'size'                      => 40,
            'id'                        => 0,
            'is_new'                    => true,
            'min_length'                => 5,
            'repeat_pass'               => 'yes',
            're_pass_label'             => 'Confirm Password',
            'pass_strength'             => 'yes',
            're_pass_placeholder'       => '',
            're_pass_help'              => '',
            'restriction_to'            => 'max',
            'restriction_type'          => 'character',
            'require_uppercase'         => 'no',
            'require_lowercase'         => 'no',
            'require_number'            => 'no',
            'require_special_char'      => 'no',
            'disallow_common_passwords' => 'no',
        ];

        return array_merge( $defaults, $props );
    }

    /**
     * Migrate minimum_strength setting to new validation settings
     * Called on-the-fly when field settings are loaded
     *
     * @since 4.2.11
     *
     * @param array $field_settings Field settings array
     *
     * @return array Migrated field settings
     */
    public static function migrate_minimum_strength( $field_settings ) {
        // Only migrate if minimum_strength exists and new settings haven't been set
        if ( ! empty( $field_settings['minimum_strength'] ) &&
             ! isset( $field_settings['require_uppercase'] ) &&
             ! isset( $field_settings['require_lowercase'] ) &&
             ! isset( $field_settings['require_number'] ) ) {
            $minimum_strength = $field_settings['minimum_strength'];
            switch ( $minimum_strength ) {
                case 'medium':
                    $field_settings['require_uppercase']    = 'yes';
                    $field_settings['require_lowercase']    = 'yes';
                    $field_settings['require_number']       = 'yes';
                    $field_settings['require_special_char'] = 'no';
                    break;
                case 'strong':
                    $field_settings['require_uppercase']    = 'yes';
                    $field_settings['require_lowercase']    = 'yes';
                    $field_settings['require_number']       = 'yes';
                    $field_settings['require_special_char'] = 'yes';
                    break;
                case 'weak':
                default:
                    // No requirements for weak, keep defaults
                    $field_settings['require_uppercase']    = 'no';
                    $field_settings['require_lowercase']    = 'no';
                    $field_settings['require_number']       = 'no';
                    $field_settings['require_special_char'] = 'no';
                    break;
            }
        }

        return $field_settings;
    }

    /**
     * Prepare entry
     *
     * @param $field
     *
     * @return mixed
     */
    public function prepare_entry( $field ) {
        $field_name = isset( $_REQUEST[ $field['name'] ] ) ? strip_shortcodes(
            trim( sanitize_text_field( wp_unslash( $_REQUEST[ $field['name'] ] ) ) )
        ) : '';

        return $field_name;
    }

    /**
     * Get list of common passwords to disallow
     *
     * Returns an array of common passwords that should be blocked when
     * the "Disallow Common Passwords" option is enabled. The list includes
     * commonly used weak passwords, sequential patterns, and dictionary words.
     * Note: Repeated patterns (e.g., 111111, 121212, paspas) are handled
     * separately via regex validation.
     *
     * @since 4.2.11
     *
     * @return array Array of common password strings (case-insensitive matching)
     */
    public static function get_common_passwords() {
        $common_passwords = [
            '123456',
            '123456789',
            '12345678',
            '12345',
            '1234',
            '654321',
            '123abc',
            'password',
            'passw0rd',
            'passwd',
            'p@ssword',
            'qwerty',
            'qwerty123',
            'qwertyuiop',
            'asdfgh',
            'asdfghjkl',
            'azerty',
            'letmein',
            'letmein1',
            'welcome',
            'iloveyou',
            'iloveyou1',
            'admin',
            'administrator',
            'root',
            'login',
            'guest',
            'user',
            'user123',
            'test',
            'testing',
            'changeme',
            'default',
            'abc123',
            'abc12345',
            'abc123456',
            '1q2w3e4r',
            '1qaz2wsx',
            'qazwsx',
            'monkey',
            'dragon',
            'sunshine',
            'flower',
            'lovely',
            'shadow',
            'master',
            'superman',
            'batman',
            'freedom',
            'whatever',
            'trustno1',
            'password1',
            'rocket',
            'hello',
            'password123',
            'football',
            'baseball',
            'secret',
            'god',
            'ninja',
            'solo',
            'princess',
            'q1w2e3r4',
            'zaq12wsx',
            'loveme',
            'pokemon',
            'computer',
            'pass',
            '123qwe',
            '1q2w3e',
            'abcd1234',
            'welcome1',
            'access',
            'access123',
            'letmein123',
            'football1',
            'michael',
            'mustang',
            'starwars',
            'pass123',
            'asdf',
            'purple',
            'blink182',
            'cheese',
            'summer',
            'winter',
            'flower123',
            'asdf1234',
            '0123',
            '01234',
            '012345',
            '0123456',
            '01234567',
            '012345678',
            '0123456789',
            '0987',
            '09876',
            '098765',
            '0987654',
            '09876543',
            '098765432',
            '0987654321',
            '123321',
            '12344321',
            '1234567',
            '12345678',
            '1234567890',
            '1234567abcdefg',
            '123456abcdef',
            '12345abc',
            '2345',
            '23456',
            '234567',
            '2345678',
            '23456789',
            '234567890',
            '3210',
            '3456',
            '34567',
            '345678',
            '3456789',
            '34567890',
            '4321',
            '43210',
            '4567',
            '45678',
            '456789',
            '4567890',
            '5432',
            '54321',
            '543210',
            '5678',
            '56789',
            '567890',
            '6543',
            '65432',
            '6543210',
            '6789',
            '67890',
            '7654',
            '76543',
            '765432',
            '7654321',
            '76543210',
            '7890',
            '8765',
            '87654',
            '876543',
            '8765432',
            '87654321',
            '876543210',
            '9876',
            '98765',
            '987654',
            '9876543',
            '98765432',
            '987654321',
            '9876543210',
            'Aa123456',
            'lkjhgfd',
            'mnbvcxz',
            'plmkojn',
            'poiuyt',
            'zxcvbnm',
        ];

        /**
         * Filter the list of common passwords to disallow
         *
         * Allows developers to customize the list of common passwords that
         * should be blocked when the "Disallow Common Passwords and Patterns" option is enabled.
         *
         * @since 4.2.11
         *
         * @param array $common_passwords Array of common password strings
         */
        return apply_filters( 'wpuf_password_common_passwords', $common_passwords );
    }

    /**
     * Check if password contains repeated patterns
     *
     * Detects common weak patterns such as:
     * - Same character repeated 3+ times (e.g., "aaa", "111", "tttt")
     * - Repeated sequences of 2+ characters (e.g., "121212", "paspas", "abcabc")
     *
     * @since 4.2.11
     *
     * @param string $password Password to check
     *
     * @return bool True if password contains repeated patterns, false otherwise
     */
    public static function has_repeated_patterns( $password ) {
        if ( empty( $password ) || strlen( $password ) < 3 ) {
            return false;
        }

        // Check for same character repeated 3+ times (e.g., "aaa", "111", "tttt")
        if ( preg_match( '/(.)\1{2,}/', $password ) ) {
            return true;
        }

        // Check if entire password is a repeated sequence (e.g., "121212", "paspas", "abcabc")
        if ( preg_match( '/^(.{2,})\1+$/', $password ) ) {
            return true;
        }

        return false;
    }

}
