<?php

namespace WeDevs\Wpuf\Pro\Fields;

/**
 * Date of Birth Field Class
 *
 * Predefined date of birth field with fixed meta key for user profiles/registration
 *
 * @since 4.2.5
 */
class Field_Date_Of_Birth extends Profile_Field {

    /**
     * Default year range for datepicker
     * Format: '-100:+100' means 100 years in the past, 100 years in the future
     *
     * @var string
     */
    const DEFAULT_YEAR_RANGE = '-100:+100';

    /**
     * Days per week for week-to-day conversion
     *
     * @var int
     */
    const DAYS_PER_WEEK = 7;

    /**
     * Constructor
     *
     * @since 4.2.5
     */
    public function __construct() {
        $this->name       = __( 'Date of Birth', 'wpuf-pro' );
        $this->input_type = 'date_of_birth_field';
        $this->icon       = 'dob';

        $this->enqueue_scripts();
    }

    /**
     * Enqueue scripts
     *
     * @since 4.2.5
     */
    public function enqueue_scripts() {
        wp_enqueue_script( 'jquery-ui-timepicker', WPUF_PRO_ASSET_URI . '/js/jquery-ui-timepicker-addon.js', [ 'jquery-ui-datepicker' ], '1.2' );
    }

    /**
     * Render the Date of Birth field
     *
     * @since 4.2.5
     *
     * @param array  $field_settings
     * @param int    $form_id
     * @param string $type
     * @param int    $post_id
     *
     * @return void
     */
    public function render( $field_settings, $form_id, $type = 'post', $post_id = null ) {
        // Get stored value
        if ( isset( $post_id ) && 0 !== (int) $post_id ) {
            $value = $this->get_meta( $post_id, $field_settings['name'], $type );
        } else {
            $value = isset( $field_settings['default'] ) ? $field_settings['default'] : '';
        }

        // Convert stored YYYY-MM-DD format to display format if needed
        if ( ! empty( $value ) ) {
            $date_obj = \DateTime::createFromFormat( 'Y-m-d', $value );
            if ( $date_obj ) {
                $format = isset( $field_settings['format'] ) ? $field_settings['format'] : 'dd/mm/yy';
                $php_format = str_replace( [ 'dd', 'mm', 'yy' ], [ 'd', 'm', 'Y' ], $format );
                $value = $date_obj->format( $php_format );
            }
        }

        $name            = $field_settings['name'];
        $is_required     = isset( $field_settings['required'] ) ? $field_settings['required'] : 'no';
        $is_readonly     = isset( $field_settings['readonly'] ) ? $field_settings['readonly'] : 'no';
        $show_age        = isset( $field_settings['show_age'] ) ? $field_settings['show_age'] : 'no';
        $show_age_months = isset( $field_settings['show_age_months'] ) ? $field_settings['show_age_months'] : 'no';
        $format          = isset( $field_settings['format'] ) ? $field_settings['format'] : 'dd/mm/yy';

        $this->field_print_label( $field_settings, $form_id ); ?>

        <div class="wpuf-fields">
            <input
                id="wpuf-dob-<?php echo $name; ?>"
                type="text"
                autocomplete="off"
                class="datepicker wpuf-date-field wpuf-dob-field <?php echo 'wpuf_' . $name . '_' . $form_id; ?>"
                data-required="<?php echo $is_required; ?>"
                data-type="text"
                name="<?php echo esc_attr( $name ); ?>"
                placeholder="<?php echo esc_attr( $format ); ?>"
                value="<?php echo esc_attr( $value ); ?>"
                size="30"
                data-format="<?php echo esc_attr( $format ); ?>"
                data-time="no"
                data-mintime="<?php echo ! empty( $field_settings['mintime'] ) ? esc_attr( $field_settings['mintime'] ) : ''; ?>"
                data-maxtime="<?php echo ! empty( $field_settings['maxtime'] ) ? esc_attr( $field_settings['maxtime'] ) : ''; ?>"
            />

            <?php if ( $show_age === 'yes' ) : ?>
                <div class="wpuf-dob-age wpuf-dob-age-<?php echo $name; ?>" style="margin-top: 8px; font-size: 14px; color: #666;"></div>
            <?php endif; ?>

            <?php $this->help_text( $field_settings ); ?>
        </div>

        <script type="text/javascript">
            jQuery(document).ready(function($) {
                // Use setTimeout to ensure this runs after global field initialization
                setTimeout(function() {
                    var $dateField = $("#wpuf-dob-<?php echo $name; ?>");
                    var $ageDisplay = $('.wpuf-dob-age-<?php echo $name; ?>');
                    var showAge = <?php echo $show_age === 'yes' ? 'true' : 'false'; ?>;
                    var showAgeMonths = <?php echo $show_age_months === 'yes' ? 'true' : 'false'; ?>;
                    var isReadonly = <?php echo $is_readonly === 'yes' ? 'true' : 'false'; ?>;

                    if ( $dateField.length === 0 ) {
                        return;
                    }

                    // Function to parse date string to Date object
                    function parseDateFromString(dateStr) {
                        if (!dateStr) return null;

                        var format = '<?php echo esc_js( $format ); ?>';
                        var parts = dateStr.split(/[\/\-]/);

                        if ( parts.length !== 3 ) return null;

                        var day, month, year;

                        if ( 'dd/mm/yy' === format || 'dd-mm-yy' === format ) {
                            day = parseInt(parts[0], 10);
                            month = parseInt(parts[1], 10) - 1;
                            year = parseInt(parts[2], 10);
                        } else if ( 'mm/dd/yy' === format || 'mm-dd-yy' === format ) {
                            day = parseInt(parts[1], 10);
                            month = parseInt(parts[0], 10) - 1;
                            year = parseInt(parts[2], 10);
                        } else if ( 'yy/mm/dd' === format || 'yy-mm-dd' === format ) {
                            day = parseInt(parts[2], 10);
                            month = parseInt(parts[1], 10) - 1;
                            year = parseInt(parts[0], 10);
                        } else {
                            return null;
                        }

                        return new Date(year, month, day);
                    }

                    // Function to calculate age text
                    function calculateAgeText(birthDate) {
                        if ( !birthDate ) {
                            return null;
                        }

                        var today = new Date();
                        var years = today.getFullYear() - birthDate.getFullYear();
                        var months = today.getMonth() - birthDate.getMonth();

                        if (months < 0) {
                            years--;
                            months += 12;
                        } else if (months === 0) {
                            if (today.getDate() < birthDate.getDate()) {
                                years--;
                                months = 11;
                            }
                        } else if (today.getDate() < birthDate.getDate()) {
                            months--;
                        }

                        if ( years < 0 ) {
                            return null;
                        }

                        var ageText = '<?php esc_html_e( 'Age: ', 'wpuf-pro' ); ?>' + years + ' <?php esc_html_e( 'years', 'wpuf-pro' ); ?>';

                        if ( showAgeMonths ) {
                            if ( months > 0 ) {
                                ageText += ', ' + months + ' <?php esc_html_e( 'months', 'wpuf-pro' ); ?>';
                            }
                        }

                        return ageText;
                    }

                    // Handle readonly field
                    if ( isReadonly ) {
                        $dateField.prop('readonly', true);

                        <?php if ( 'yes' === $show_age ) : ?>
                        // Update age display for readonly fields
                        var initialValue = $dateField.val();
                        if ( initialValue ) {
                            var date = parseDateFromString(initialValue);
                            if ( date ) {
                                var ageText = calculateAgeText(date);
                                if ( ageText ) {
                                    if ( $ageDisplay.length ) {
                                        $ageDisplay.text( ageText );
                                    }
                                }
                            }
                        }
                        <?php endif; ?>
                        return;
                    }

                    var date_default = {
                        dateFormat: '<?php echo esc_js( $format ); ?>',
                        changeMonth: true,
                        changeYear: true,
                        yearRange: '<?php echo esc_js( self::DEFAULT_YEAR_RANGE ); ?>',
                        maxDate: 0
                    };

                    function parseDateValue(dateStr) {
                        if ( !dateStr ) {
                            return null;
                        }

                        dateStr = dateStr.trim();

                        if ( !dateStr ) {
                            return null;
                        }

                        // Parse absolute date only (dd-mm-yyyy or dd/mm/yyyy)
                        var dateParts = dateStr.split(/[-/]/);

                        if ( dateParts.length === 3 ) {
                            var year = parseInt(dateParts[2], 10);
                            var month = parseInt(dateParts[1], 10) - 1;
                            var day = parseInt(dateParts[0], 10);
                            return new Date(year, month, day);
                        }

                        return null;
                    }

                    <?php
                    $maxtime = '';
                    $mintime = '';

                    $has_mintime = isset( $field_settings['mintime'] ) && strlen( trim( $field_settings['mintime'] ) ) > 0;
                    $has_maxtime = isset( $field_settings['maxtime'] ) && strlen( trim( $field_settings['maxtime'] ) ) > 0;

                    if ( $has_mintime || $has_maxtime ) {
                        if ( $has_mintime ) {
                            $mintime = str_replace( '/', '-', trim( $field_settings['mintime'] ) );
                        }
                        if ( $has_maxtime ) {
                            $maxtime = str_replace( '/', '-', trim( $field_settings['maxtime'] ) );
                        }
                    ?>
                    var dateObj = jQuery.extend({}, date_default);

                    <?php if ( $has_mintime ) { ?>
                    var parsedMinDate = parseDateValue("<?php echo esc_js( $mintime ); ?>");

                    if ( parsedMinDate !== null ) {
                        dateObj.minDate = parsedMinDate;
                    }
                    <?php } ?>

                    <?php if ( $has_maxtime ) { ?>
                    var parsedMaxDate = parseDateValue("<?php echo esc_js( $maxtime ); ?>");

                    if ( parsedMaxDate !== null ) {
                        dateObj.maxDate = parsedMaxDate;
                    }
                    <?php } ?>

                    if ( $dateField.hasClass('hasDatepicker') ) {
                        $dateField.datepicker('destroy');
                    }

                    $dateField.datepicker(dateObj);
                    <?php } else { ?>
                    if ( $dateField.hasClass('hasDatepicker') ) {
                        $dateField.datepicker('destroy');
                    }

                    $dateField.datepicker(date_default);
                    <?php } ?>

                        $dateField.addClass('wpuf-initialized');

                    // Age update function
                    function updateAge() {
                        if ( !showAge ) {
                            return;
                        }

                        var dateValue = $dateField.val();
                        if ( dateValue ) {
                            var birthDate = parseDateFromString(dateValue);
                            if ( birthDate ) {
                                var ageText = calculateAgeText(birthDate);
                                if ( ageText ) {
                                    if ( $ageDisplay.length > 0 ) {
                                        $ageDisplay.text( ageText ).show();
                                    }
                                }
                            }
                        } else {
                            if ( $ageDisplay.length > 0 ) {
                                $ageDisplay.text( '' );
                            }
                        }
                    }

                    if ( showAge ) {
                        $dateField.on('change', updateAge);
                        updateAge();
                    }
                }, 100); // End setTimeout
            });
        </script>

        <?php $this->after_field_print_label();
    }

    /**
     * Get field options setting
     *
     * @since 4.2.5
     *
     * @return array
     */
    public function get_options_settings() {
        // Get default options but exclude the name field since we'll provide our own meta_key field
        $filtered_options = $this->get_default_option_settings( true, [ 'name' ] );

        $dob_options = [
            [
                'name'      => 'name',
                'title'     => __( 'Meta Key', 'wpuf-pro' ),
                'type'      => 'text',
                'section'   => 'basic',
                'priority'  => 11,
                'readonly'  => true,
                'help_text' => __( 'The meta key used to store this field data in the database. This is fixed to "wpuf_dob" and cannot be changed.', 'wpuf-pro' ),
            ],

            [
                'name'      => 'format',
                'title'     => __( 'Date Format', 'wpuf-pro' ),
                'type'      => 'select',
                'section'   => 'advanced',
                'priority'  => 23,
                'options'   => [
                    'dd/mm/yy' => __( 'dd/mm/yyyy (e.g., 25/12/2024)', 'wpuf-pro' ),
                    'mm/dd/yy' => __( 'mm/dd/yyyy (e.g., 12/25/2024)', 'wpuf-pro' ),
                    'yy/mm/dd' => __( 'yyyy/mm/dd (e.g., 2024/12/25)', 'wpuf-pro' ),
                    'dd-mm-yy' => __( 'dd-mm-yyyy (e.g., 25-12-2024)', 'wpuf-pro' ),
                    'mm-dd-yy' => __( 'mm-dd-yyyy (e.g., 12-25-2024)', 'wpuf-pro' ),
                    'yy-mm-dd' => __( 'yyyy-mm-dd (e.g., 2024-12-25)', 'wpuf-pro' ),
                ],
                'default'   => 'dd/mm/yy',
                'help_text' => __( 'Select the date format for display', 'wpuf-pro' ),
            ],

            [
                'name'          => 'show_age',
                'title'         => '',
                'type'          => 'checkbox',
                'is_single_opt' => true,
                'options'       => [
                    'yes' => __( 'Show age as number', 'wpuf-pro' ),
                ],
                'section'       => 'basic',
                'priority'      => 13,
                'help_text'     => __( 'Display calculated age alongside the date of birth', 'wpuf-pro' ),
            ],

            [
                'name'          => 'show_age_months',
                'title'         => '',
                'type'          => 'checkbox',
                'is_single_opt' => true,
                'options'       => [
                    'yes' => __( 'Show months in age calculation', 'wpuf-pro' ),
                ],
                'section'       => 'basic',
                'priority'      => 13.5,
                'help_text'     => __( 'Display age with months (e.g., "25 years, 3 months")', 'wpuf-pro' ),
            ],

            [
                'name'      => 'mintime',
                'title'     => __( 'Minimum Date', 'wpuf-pro' ),
                'type'      => 'text',
                'section'   => 'advanced',
                'priority'  => 26,
                'help_text' => __( 'Enter earliest selectable date (e.g., 01-01-1900)', 'wpuf-pro' ),
            ],

            [
                'name'      => 'maxtime',
                'title'     => __( 'Maximum Date', 'wpuf-pro' ),
                'type'      => 'text',
                'section'   => 'advanced',
                'priority'  => 27,
                'help_text' => __( 'Enter latest selectable date (e.g., 31-12-2024)', 'wpuf-pro' ),
            ],
        ];

        return array_merge( $filtered_options, $dob_options );
    }

    /**
     * Get the field props
     *
     * @since 4.2.5
     *
     * @return array
     */
    public function get_field_props() {
        $defaults = $this->default_attributes();
        $props    = [
            'input_type'       => 'date_of_birth',
            'label'            => __( 'Date of Birth', 'wpuf-pro' ),
            'name'             => 'wpuf_dob', // Fixed meta key for form builder
            'is_meta'          => 'yes',
            'format'           => 'dd/mm/yy',
            'show_age'         => 'no',
            'show_age_months'  => 'no',
            'readonly'         => 'no',
            'id'               => 0,
            'is_new'           => true,
            'show_in_post'     => 'yes',
            'hide_field_label' => 'no',
        ];

        return array_merge( $defaults, $props );
    }

    /**
     * Prepare entry
     *
     * @since 4.2.5
     *
     * @param $field
     *
     * @return mixed
     */
    public function prepare_entry( $field ) {
        check_ajax_referer( 'wpuf_form_add' );

        $val = isset( $_POST[ $field['name'] ] ) ? sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) : '';

        if ( empty( $val ) ) {
            return '';
        }

        // Convert datepicker format to YYYY-MM-DD for storage
        $format = isset( $field['format'] ) ? $field['format'] : 'dd/mm/yy';
        $php_format = str_replace( [ 'dd', 'mm', 'yy' ], [ 'd', 'm', 'Y' ], $format );

        $date = \DateTime::createFromFormat( $php_format, $val );
        if ( $date ) {
            return $date->format( 'Y-m-d' );
        }

        return '';
    }

    /**
     * Render field data for display
     *
     * @since 4.2.5
     *
     * @param mixed $data
     * @param array $field
     *
     * @return string
     */
    public function render_field_data( $data, $field ) {
        $data       = is_array( $data ) ? array_pop( $data ) : $data;
        $hide_label = isset( $field['hide_field_label'] )
            ? wpuf_validate_boolean( $field['hide_field_label'] )
            : false;

        $container_classnames = [ 'wpuf-field-data', 'wpuf-field-data-' . $this->input_type ];

        if ( empty( $data ) ) {
            return '';
        }

        // Format the date for display (data is stored in YYYY-MM-DD format)
        $format          = isset( $field['format'] ) ? $field['format'] : 'dd/mm/yy';
        $show_age        = isset( $field['show_age'] ) ? $field['show_age'] : 'no';
        $show_age_months = isset( $field['show_age_months'] ) ? $field['show_age_months'] : 'no';

        $formatted_date = self::format_date_for_display( $data, $format );
        $age_text       = '';

        if ( 'yes' === $show_age ) {
            $age_data = self::calculate_age( $data, 'yes' === $show_age_months );
            if ( $age_data !== false ) {
                if ( is_array( $age_data ) ) {
                    // Array with years and months
                    if ( $age_data['months'] > 0 ) {
                        $age_text = sprintf(
                            /* translators: 1: years, 2: months */
                            __( ' (Age: %1$d years, %2$d months)', 'wpuf-pro' ),
                            $age_data['years'],
                            $age_data['months']
                        );
                    } else {
                        $age_text = sprintf(
                            /* translators: %d: age in years */
                            __( ' (Age: %d years)', 'wpuf-pro' ),
                            $age_data['years']
                        );
                    }
                } else {
                    // Just years
                    $age_text = sprintf(
                        /* translators: %d: age in years */
                        __( ' (Age: %d years)', 'wpuf-pro' ),
                        $age_data
                    );
                }
            }
        }

        ob_start();
        ?>
            <li class="<?php echo esc_attr( implode( ' ', $container_classnames ) ); ?>">
                <?php if ( ! $hide_label ) : ?>
                    <label><?php echo esc_html( $field['label'] ); ?>:</label>
                <?php endif; ?>
                <?php echo esc_html( $formatted_date . $age_text ); ?>
            </li>
        <?php
        return ob_get_clean();
    }

    /**
     * Validate date of birth during form submission
     *
     * Ensures the date is valid and in the past (not future)
     *
     * @since 4.2.5
     *
     * @param string $error Existing error message from previous validation hooks
     *
     * @return string Error message if validation fails, or empty string if valid
     */
    public static function validate_date_of_birth( $error ) {
        // If there's already an error from a previous hook, preserve it
        if ( ! empty( $error ) ) {
            return $error;
        }

        $form_id = isset( $_POST['form_id'] ) ? intval( wp_unslash( $_POST['form_id'] ) ) : 0;
        if ( ! $form_id ) {
            return $error;
        }

        $form        = new \WeDevs\Wpuf\Admin\Forms\Form( $form_id );
        $form_fields = $form->get_fields();

        foreach ( $form_fields as $field ) {
            if ( 'date_of_birth_field' !== $field['template'] && 'date_of_birth_field' !== $field['input_type'] ) {
                continue;
            }

            $field_name = isset( $field['name'] ) ? $field['name'] : '';

            // Validate field name to prevent arbitrary POST data access
            if ( empty( $field_name ) || ! preg_match( '/^[a-zA-Z0-9_-]+$/', $field_name ) ) {
                continue;
            }

            $submitted_value = isset( $_POST[ $field_name ] ) ? sanitize_text_field( wp_unslash( $_POST[ $field_name ] ) ) : '';

            // Skip if field is not required and empty
            $is_required = isset( $field['required'] ) && $field['required'] === 'yes';
            if ( empty( $submitted_value ) && ! $is_required ) {
                continue;
            }

            if ( empty( $submitted_value ) && $is_required ) {
                $field_label = isset( $field['label'] ) ? $field['label'] : __( 'Date of Birth', 'wpuf-pro' );
                return sprintf(
                    /* translators: %s: Field label */
                    __( '%s is required', 'wpuf-pro' ),
                    $field_label
                );
            }

            $validation_error = self::validate_date_value( $submitted_value, $field );

            if ( ! empty( $validation_error ) ) {
                return $validation_error;
            }
        }

        return $error;
    }

    /**
     * Validate a single date of birth value
     *
     * @since 4.2.5
     *
     * @param string $date_value Submitted date value in datepicker format
     * @param array  $field_settings Field configuration
     *
     * @return string Error message if validation fails, or empty string if valid
     */
    private static function validate_date_value( $date_value, $field_settings ) {
        $format = isset( $field_settings['format'] ) ? $field_settings['format'] : 'dd/mm/yy';
        $field_label = isset( $field_settings['label'] ) ? $field_settings['label'] : __( 'Date of Birth', 'wpuf-pro' );

        // Convert jQuery date format to PHP format
        $php_format = str_replace( [ 'dd', 'mm', 'yy' ], [ 'd', 'm', 'Y' ], $format );

        // Parse submitted date
        $date = \DateTime::createFromFormat( $php_format, $date_value );

        if ( false === $date ) {
            return sprintf(
                /* translators: 1: Field label, 2: Expected date format */
                __( 'Invalid date format for %1$s. Expected format: %2$s', 'wpuf-pro' ),
                $field_label,
                $format
            );
        }

        // Set time to midnight for date-only comparison
        $date->setTime( 0, 0, 0 );

        // Validate minDate
        $has_mintime = isset( $field_settings['mintime'] ) && strlen( trim( $field_settings['mintime'] ) ) > 0;

        if ( $has_mintime ) {
            $min_date = self::parse_min_max_date( $field_settings['mintime'] );

            if ( false !== $min_date ) {
                $min_date->setTime( 0, 0, 0 );

                if ( $date < $min_date ) {
                    return sprintf(
                        /* translators: 1: Field label, 2: Minimum date */
                        __( 'The date for %1$s must be on or after %2$s', 'wpuf-pro' ),
                        $field_label,
                        $min_date->format( $php_format )
                    );
                }
            }
        }

        // Validate maxDate
        $has_maxtime = isset( $field_settings['maxtime'] ) && strlen( trim( $field_settings['maxtime'] ) ) > 0;

        if ( $has_maxtime ) {
            $max_date = self::parse_min_max_date( $field_settings['maxtime'] );

            if ( false !== $max_date ) {
                $max_date->setTime( 0, 0, 0 );

                if ( $date > $max_date ) {
                    return sprintf(
                        /* translators: 1: Field label, 2: Maximum date */
                        __( 'The date for %1$s must be on or before %2$s', 'wpuf-pro' ),
                        $field_label,
                        $max_date->format( $php_format )
                    );
                }
            }
        }

        return '';
    }

    /**
     * Parse min/max date string (absolute dates only)
     *
     * Supports absolute dates: "01-01-2024", "01/01/2024"
     *
     * @param string $date_string Date string
     * @return \DateTime|false DateTime object or false on failure
     * @since 4.2.5
     */
    private static function parse_min_max_date( $date_string ) {
        $date_string = trim( $date_string );

        // Parse as absolute date only
        $normalized_string = str_replace( '/', '-', $date_string );
        $parts = explode( '-', $normalized_string );

        if ( count( $parts ) === 3 ) {
            $parsed = \DateTime::createFromFormat( 'j-n-Y', $normalized_string );
            if ( false === $parsed ) {
                $parsed = \DateTime::createFromFormat( 'd-m-Y', $normalized_string );
            }

            if ( false !== $parsed ) {
                $formatted_date = $parsed->format( 'j-n-Y' );
                $formatted_date_padded = $parsed->format( 'd-m-Y' );
                $normalized_input = preg_replace( '/\b0+(\d)/', '$1', $normalized_string );

                if ( $formatted_date === $normalized_input || $formatted_date_padded === $normalized_string ) {
                    $parsed->setTime( 0, 0, 0 );
                    return $parsed;
                }
            }
        }

        return false;
    }

    /**
     * Calculate age from date of birth
     *
     * @since 4.2.5
     *
     * @param string $date_of_birth Date in YYYY-MM-DD format
     * @param bool   $with_months   Whether to include months in calculation
     *
     * @return int|array|false Age in years, or array with years and months, or false on error
     */
    public static function calculate_age( $date_of_birth, $with_months = false ) {
        if ( empty( $date_of_birth ) ) {
            return false;
        }

        $dob = \DateTime::createFromFormat( 'Y-m-d', $date_of_birth );
        if ( false === $dob ) {
            return false;
        }

        $now = new \DateTime();
        $age = $now->diff( $dob );

        if ( $with_months ) {
            return [
                'years'  => $age->y,
                'months' => $age->m,
            ];
        }

        return $age->y;
    }

    /**
     * Format date for display based on selected format
     *
     * @since 4.2.5
     *
     * @param string $date_value Date in YYYY-MM-DD format (stored format)
     * @param string $format Datepicker format (e.g., 'dd/mm/yy')
     *
     * @return string Formatted date string
     */
    public static function format_date_for_display( $date_value, $format = 'dd/mm/yy' ) {
        if ( empty( $date_value ) ) {
            return '';
        }

        $date = \DateTime::createFromFormat( 'Y-m-d', $date_value );
        if ( false === $date ) {
            return $date_value; // Return original if parsing fails
        }

        // Convert jQuery datepicker format to PHP format
        // Handle both slash and dash separators
        $separator = strpos( $format, '/' ) !== false ? '/' : '-';
        $php_format = str_replace( [ 'dd', 'mm', 'yy' ], [ 'd', 'm', 'Y' ], $format );

        return $date->format( $php_format );
    }
}
