<?php
/**
 * Enhanced Property Single Renderer 
 *
 * @package     Havenlytics
 * @subpackage  Frontend
 * @since       2.0.0
 */

namespace HvnlyNab\Frontend;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Enhanced Property Single Renderer Class
 */
class PropertySingleRenderer {

    /**
     * Storage key for saved sections.
     *
     * @var string
     */
    private $storage_key = 'hvnly_property_builder.sections';

    /**
     * Cache for processed groups to avoid duplicates.
     *
     * @var array
     */
    private $processed_groups = [];

    /**
     * Main rendering method for single property content.
     *
     * @param int $property_id Property ID.
     * @return void
     */
    public function render_main_content( $property_id = null ) {
        $property_id = $property_id ?: get_the_ID();
        
        // Default sections configuration
        $default_sections = array(
            'gallery' => array(
                'title'    => 'Property Gallery',
                'template' => 'gallery-carousel',
                'order'    => 0,
                'enabled'  => true,
                'priority' => 10,
            ),
            'summary' => array(
                'title'    => 'Property Summary',
                'template' => 'summary-card',
                'order'    => 0,
                'enabled'  => true,
                'priority' => 20,
            ),
            'description' => array(
                'title'    => 'Property Description',
                'template' => 'description-card',
                'order'    => 0,
                'enabled'  => true,
                'priority' => 30,
            ),
        );
        
        // Get all sections from database (dynamic sections from property builder)
        $dynamic_sections = get_option( $this->storage_key, array() );

        // Start with default sections
        $all_sections = $default_sections;
        
        // Merge with dynamic sections (they will override defaults if same keys exist)
        if ( ! empty( $dynamic_sections ) && is_array( $dynamic_sections ) ) {
            foreach ( $dynamic_sections as $section_id => $section_data ) {
                if ( ! is_array( $section_data ) ) {
                    continue;
                }
                
                // Skip required sections (like sec_basic_info) from frontend display
                if ( isset( $section_data['required'] ) && $section_data['required'] ) {
                    continue;
                }
                
                // Skip if no fields
                if ( empty( $section_data['fields'] ) || ! is_array( $section_data['fields'] ) ) {
                    continue;
                }
                
                $all_sections[ $section_id ] = $section_data;
            }
        }
        
        // Sort sections by order
        $all_sections = $this->sort_sections_by_order( $all_sections );
        
        // Reset processed groups for this property
        $this->processed_groups = array();
        
        // Render each section
        foreach ( $all_sections as $section_id => $section ) {
            // Skip if section is explicitly disabled
            if ( isset( $section['enabled'] ) && ! $section['enabled'] ) {
                continue;
            }
            
            // Check if this is a default section (has template) or dynamic section (has fields)
            if ( isset( $section['template'] ) ) {
                // Default section - render directly
                $this->render_default_section( $section_id, $section, $property_id );
            } else {
                // Dynamic section - render with fields
                $this->render_section( $section_id, $section, $property_id );
            }
        }
    }

    /**
     * Render a default section using template.
     *
     * @param string $section_id  Section identifier.
     * @param array  $section     Section configuration.
     * @param int    $property_id Property ID.
     * @return void
     */
    private function render_default_section( $section_id, $section, $property_id ) {
        $template = isset( $section['template'] ) ? $section['template'] : '';
        $title    = isset( $section['title'] ) ? $section['title'] : '';
        
        if ( empty( $template ) ) {
            return;
        }
        
        $section_class = 'hvnly-property-single__section-' . sanitize_title( $section_id );
        
        // Start section container
        echo '<div class="hvnly-property-single__details-card ' . esc_attr( $section_class ) . '">';
        
        // Section title
        if ( ! empty( $title ) ) {
            echo '<h2 class="hvnly-property-single__section-title">' . esc_html( $title ) . '</h2>';
        }
        
        // Prepare template arguments
        $template_args = array(
            'property_id' => $property_id,
            'section'     => $section,
            'section_id'  => $section_id,
        );
        
        // Load the template
        hvnly_get_template( 'single-property/' . $template . '.php', $template_args );
        
        echo '</div>'; // Close section container
    }

    /**
     * Render a single section.
     *
     * @param string $section_id
     * @param array  $section
     * @param int    $property_id
     */
    private function render_section( $section_id, $section, $property_id ) {
        $section_title = isset( $section['title'] ) ? $section['title'] : '';
        $section_class = 'hvnly-property-single__section-' . sanitize_title( $section_id );
        
        // Start section container
        echo '<div class="hvnly-property-single__details-card ' . esc_attr( $section_class ) . '">';
        
        // Section title
        if ( ! empty( $section_title ) ) {
            echo '<h2 class="hvnly-property-single__section-title">' . esc_html( $section_title ) . '</h2>';
        }
        
        // Fields container
        echo '<div class="hvnly-property-single__section-fields">';
        
        // Sort fields by order
        $fields = $this->sort_fields_by_order( $section['fields'] );
        
        // First, identify all groups in this section
        $groups = $this->identify_groups( $fields );
        
        // If no groups, render all fields individually
        if ( empty( $groups ) ) {
            foreach ( $fields as $field ) {
                $this->render_field( $field, $property_id );
            }
        } else {
            // Render fields in order, skipping grouped fields
            $rendered_groups = [];
            
            foreach ( $fields as $field ) {
                // Check if this field belongs to a group
                $group_id = $field['group_id'] ?? null;
                
                if ( $group_id && ! in_array( $group_id, $rendered_groups ) ) {
                    // Get all fields for this group
                    $group_fields = $this->get_group_fields( $fields, $group_id );
                    
                    // Check if this group has any data
                    $group_type = $this->detect_group_type( $group_fields[0] );
                    
                    // Handle different group types
                    switch ( $group_type ) {
                        case 'map':
                            if ( $this->map_group_has_data( $group_fields, $property_id ) ) {
                                $this->render_group( $group_fields, $property_id );
                                $rendered_groups[] = $group_id;
                            }
                            break;
                            
                        case 'video':
                            if ( $this->video_group_has_data( $group_fields, $property_id ) ) {
                                $this->render_group( $group_fields, $property_id );
                                $rendered_groups[] = $group_id;
                            }
                            break;
                            
                        case 'gallery':
                            if ( $this->gallery_group_has_data( $group_fields, $property_id ) ) {
                                $this->render_group( $group_fields, $property_id );
                                $rendered_groups[] = $group_id;
                            }
                            break;
                            
                        case 'property_docs':
                            if ( $this->document_group_has_data( $group_fields, $property_id ) ) {
                                $this->render_group( $group_fields, $property_id );
                                $rendered_groups[] = $group_id;
                            }
                            break;
                            
                        default:
                            if ( $this->group_has_data( $group_fields, $property_id ) ) {
                                $this->render_group( $group_fields, $property_id );
                                $rendered_groups[] = $group_id;
                            }
                            break;
                    }
                } elseif ( ! $group_id ) {
                    // Render individual field
                    $this->render_field( $field, $property_id );
                }
            }
        }
        
        echo '</div>'; // Close fields container
        echo '</div>'; // Close section container
    }
    
    /**
     * Get video field data using stored reference keys
     *
     * @param int $property_id Property ID
     * @return array
     */
    private function get_video_data( $property_id ) {
        $result = array(
            'title' => '',
            'url' => '',
            'thumbnail' => '',
            'has_data' => false
        );
        
        // Check stored reference keys first
        $active_url_key = get_post_meta( $property_id, '_hvnly_active_video_url_key', true );
        $active_title_key = get_post_meta( $property_id, '_hvnly_active_video_title_key', true );
        $active_thumbnail_key = get_post_meta( $property_id, '_hvnly_active_video_thumbnail_key', true );
        
        if ( ! empty( $active_url_key ) ) {
            $result['url'] = get_post_meta( $property_id, $active_url_key, true );
            $result['title'] = get_post_meta( $property_id, $active_title_key, true );
            $result['thumbnail'] = get_post_meta( $property_id, $active_thumbnail_key, true );
            $result['has_data'] = ! empty( $result['url'] );
            
            // if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
            //     error_log( "Havenlytics: Found video data via stored references for property $property_id" );
            // }
            return $result;
        }
        
        // Fallback: search for video_*_url pattern
        $all_meta = get_post_meta( $property_id );
        foreach ( $all_meta as $meta_key => $meta_value ) {
            if ( preg_match( '/^video_.+_url$/i', $meta_key ) ) {
                $result['url'] = is_array( $meta_value ) ? ( $meta_value[0] ?? '' ) : $meta_value;
                $base_key = preg_replace( '/_url$/i', '', $meta_key );
                $result['title'] = get_post_meta( $property_id, $base_key . '_title', true );
                $result['thumbnail'] = get_post_meta( $property_id, $base_key . '_thumbnail', true );
                $result['has_data'] = ! empty( $result['url'] );
                break;
            }
        }
        
        return $result;
    }

    /**
     * Get gallery field data using stored reference keys
     *
     * @param int $property_id Property ID
     * @return array
     */
    private function get_gallery_data( $property_id ) {
        $result = array(
            'title' => '',
            'images' => '',
            'has_data' => false
        );
        
        // Check stored reference keys first
        $active_images_key = get_post_meta( $property_id, '_hvnly_active_gallery_images_key', true );
        $active_title_key = get_post_meta( $property_id, '_hvnly_active_gallery_title_key', true );
        
        if ( ! empty( $active_images_key ) ) {
            $result['images'] = get_post_meta( $property_id, $active_images_key, true );
            $result['title'] = get_post_meta( $property_id, $active_title_key, true );
            $result['has_data'] = ! empty( $result['images'] );
            
            // if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
            //     error_log( "Havenlytics: Found gallery data via stored references for property $property_id" );
            // }
            return $result;
        }
        
        // Fallback: search for gallery_*_images pattern
        $all_meta = get_post_meta( $property_id );
        foreach ( $all_meta as $meta_key => $meta_value ) {
            if ( preg_match( '/^gallery_.+_images$/i', $meta_key ) ) {
                $result['images'] = is_array( $meta_value ) ? ( $meta_value[0] ?? '' ) : $meta_value;
                $base_key = preg_replace( '/_images$/i', '', $meta_key );
                $result['title'] = get_post_meta( $property_id, $base_key . '_title', true );
                $result['has_data'] = ! empty( $result['images'] );
                break;
            }
        }
        
        return $result;
    }

    /**
     * Get documents field data using stored reference keys
     *
     * @param int $property_id Property ID
     * @return array
     */
    private function get_documents_data( $property_id ) {
        $result = array(
            'documents' => array(),
            'has_data' => false
        );
        
        // Check stored reference keys first
        $active_docs_key = get_post_meta( $property_id, '_hvnly_active_documents_key', true );
        
        if ( ! empty( $active_docs_key ) ) {
            $documents_json = get_post_meta( $property_id, $active_docs_key, true );
            if ( ! empty( $documents_json ) ) {
                $decoded = json_decode( $documents_json, true );
                if ( is_array( $decoded ) && ! empty( $decoded ) ) {
                    $result['documents'] = $decoded;
                    $result['has_data'] = true;
                    
                    // if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
                    //     error_log( "Havenlytics: Found documents data via stored references for property $property_id" );
                    // }
                    return $result;
                }
            }
            
            // Try individual arrays
            $active_icons_key = get_post_meta( $property_id, '_hvnly_active_documents_icons_key', true );
            $active_labels_key = get_post_meta( $property_id, '_hvnly_active_documents_labels_key', true );
            $active_urls_key = get_post_meta( $property_id, '_hvnly_active_documents_urls_key', true );
            
            if ( ! empty( $active_labels_key ) && ! empty( $active_urls_key ) ) {
                $icons = get_post_meta( $property_id, $active_icons_key, true );
                $labels = get_post_meta( $property_id, $active_labels_key, true );
                $urls = get_post_meta( $property_id, $active_urls_key, true );
                
                if ( ! empty( $labels ) && ! empty( $urls ) ) {
                    $labels_array = is_array( $labels ) ? $labels : array( $labels );
                    $urls_array = is_array( $urls ) ? $urls : array( $urls );
                    $icons_array = is_array( $icons ) ? $icons : array( $icons );
                    
                    $count = max( count( $labels_array ), count( $urls_array ) );
                    for ( $i = 0; $i < $count; $i++ ) {
                        $label = $labels_array[ $i ] ?? '';
                        $url = $urls_array[ $i ] ?? '';
                        if ( ! empty( $label ) && ! empty( $url ) ) {
                            $result['documents'][] = array(
                                'icon' => $icons_array[ $i ] ?? 'file-pdf',
                                'label' => $label,
                                'url' => $url
                            );
                        }
                    }
                    $result['has_data'] = ! empty( $result['documents'] );
                    return $result;
                }
            }
        }
        
        // Fallback: search for property_docs_*_documents pattern
        $all_meta = get_post_meta( $property_id );
        foreach ( $all_meta as $meta_key => $meta_value ) {
            if ( preg_match( '/^property_docs_.+_documents$/i', $meta_key ) ) {
                $documents_json = is_array( $meta_value ) ? ( $meta_value[0] ?? '' ) : $meta_value;
                if ( ! empty( $documents_json ) ) {
                    $decoded = json_decode( $documents_json, true );
                    if ( is_array( $decoded ) && ! empty( $decoded ) ) {
                        $result['documents'] = $decoded;
                        $result['has_data'] = true;
                        break;
                    }
                }
            }
        }
        
        return $result;
    }
    /**
     * Check if document group has any data
     *
     * @param array $group_fields
     * @param int   $property_id
     * @return bool
     */
    private function document_group_has_data( $group_fields, $property_id ) {
        // Try to get the main documents field first
        $field_name = '';
        $group_base_id = '';
        
        foreach ( $group_fields as $field ) {
            if ( ! empty( $field['group_base_id'] ) ) {
                $group_base_id = $field['group_base_id'];
                $field_name = $group_base_id . '_documents';
                break;
            }
        }
        
        if ( ! empty( $field_name ) ) {
            $documents = get_post_meta( $property_id, $field_name, true );
            if ( ! empty( $documents ) ) {
                $decoded = json_decode( $documents, true );
                if ( is_array( $decoded ) && ! empty( $decoded ) ) {
                    return true;
                }
            }
        }
        
        // Fallback: check individual fields
        if ( ! empty( $group_base_id ) ) {
            $icons = get_post_meta( $property_id, $group_base_id . '_icon', true );
            $labels = get_post_meta( $property_id, $group_base_id . '_label', true );
            $urls = get_post_meta( $property_id, $group_base_id . '_url', true );
            
            return ! empty( $labels ) || ! empty( $urls );
        }
        
        return false;
    }

    /**
     * Check if map group has any data (coordinates or address)
     *
     * @param array $group_fields
     * @param int   $property_id
     * @return bool
     */
    private function map_group_has_data( $group_fields, $property_id ) {
        foreach ( $group_fields as $field ) {
            $meta_key = $field['name'] ?? $field['id'] ?? '';
            if ( empty( $meta_key ) ) continue;
            
            $value = get_post_meta( $property_id, $meta_key, true );
            
            // Check for latitude, longitude, or address data
            if ( ! empty( $value ) ) {
                // Skip the preview field for data checking
                if ( strpos( $meta_key, '_preview' ) !== false || strpos( $meta_key, 'preview' ) !== false ) {
                    continue;
                }
                return true;
            }
        }
        
        // Also check legacy keys
        $lat = get_post_meta( $property_id, '_hvnly_property_latitude', true );
        $lng = get_post_meta( $property_id, '_hvnly_property_longitude', true );
        $addr = get_post_meta( $property_id, '_hvnly_property_address', true );
        
        return ! empty( $lat ) || ! empty( $lng ) || ! empty( $addr );
    }

    /**
     * Check if video group has any data
     *
     * @param array $group_fields
     * @param int   $property_id
     * @return bool
     */
    private function video_group_has_data( $group_fields, $property_id ) {
        foreach ( $group_fields as $field ) {
            $meta_key = $field['name'] ?? $field['id'] ?? '';
            if ( empty( $meta_key ) ) continue;
            
            $value = get_post_meta( $property_id, $meta_key, true );
            if ( ! empty( $value ) ) {
                return true;
            }
        }
        
        // Also check legacy keys
        $url = get_post_meta( $property_id, '_hvnly_video_url', true );
        return ! empty( $url );
    }

    /**
     * Check if gallery group has any data
     *
     * @param array $group_fields
     * @param int   $property_id
     * @return bool
     */
    private function gallery_group_has_data( $group_fields, $property_id ) {
        foreach ( $group_fields as $field ) {
            $meta_key = $field['name'] ?? $field['id'] ?? '';
            if ( empty( $meta_key ) ) continue;
            
            // Look for images field
            if ( strpos( $meta_key, '_images' ) !== false || ( $field['metaKey'] ?? '' ) === 'images' ) {
                $value = get_post_meta( $property_id, $meta_key, true );
                if ( ! empty( $value ) ) {
                    // Check if there are actual image IDs
                    $images = is_string( $value ) ? explode( ',', $value ) : (array) $value;
                    $images = array_filter( array_map( 'absint', $images ) );
                    if ( ! empty( $images ) ) {
                        return true;
                    }
                }
            }
        }
        
        return false;
    }

    /**
     * Identify all unique groups in fields.
     *
     * @param array $fields
     * @return array
     */
    private function identify_groups( $fields ) {
        $groups = [];
        
        foreach ( $fields as $field ) {
            if ( ! empty( $field['group_id'] ) ) {
                $groups[ $field['group_id'] ] = [
                    'id' => $field['group_id'],
                    'type' => $field['group_type'] ?? $this->detect_group_type( $field ),
                    'base_id' => $field['group_base_id'] ?? null,
                ];
            }
        }
        
        return $groups;
    }

    /**
     * Detect group type from field.
     *
     * @param array $field
     * @return string
     */
    private function detect_group_type( $field ) {
        $type = $field['type'] ?? '';
        $name = $field['name'] ?? $field['id'] ?? '';
        $group_type = $field['group_type'] ?? '';
        
        if ( ! empty( $group_type ) ) {
            return $group_type;
        }
        
        if ( $type === 'map' || strpos( $name, 'map_' ) === 0 ) {
            return 'map';
        }
        if ( $type === 'video' || strpos( $name, 'video_' ) === 0 ) {
            return 'video';
        }
        if ( $type === 'gallery' || strpos( $name, 'gallery_' ) === 0 ) {
            return 'gallery';
        }
        if ( $type === 'property_docs' || strpos( $name, 'property_docs_' ) === 0 ) {
            return 'property_docs';
        }
        
        return 'unknown';
    }

    /**
     * Get all fields belonging to a group.
     *
     * @param array  $fields
     * @param string $group_id
     * @return array
     */
    private function get_group_fields( $fields, $group_id ) {
        $group_fields = [];
        
        foreach ( $fields as $field ) {
            if ( ( $field['group_id'] ?? '' ) === $group_id ) {
                $group_fields[] = $field;
            }
        }
        
        // Sort by group_position
        usort( $group_fields, function( $a, $b ) {
            $a_pos = (int) ( $a['group_position'] ?? 0 );
            $b_pos = (int) ( $b['group_position'] ?? 0 );
            return $a_pos - $b_pos;
        });
        
        return $group_fields;
    }

    /**
     * Check if a group has any data.
     *
     * @param array $group_fields
     * @param int   $property_id
     * @return bool
     */
    private function group_has_data( $group_fields, $property_id ) {
        foreach ( $group_fields as $field ) {
            $value = $this->get_group_field_value( $field, $property_id );
            if ( $this->has_value( $value ) ) {
                return true;
            }
        }
        
        return false;
    }

    /**
     * Get group field value with backward compatibility.
     *
     * @param array $field
     * @param int   $property_id
     * @return mixed
     */
    private function get_group_field_value( $field, $property_id ) {
        $meta_key = $field['name'] ?? $field['id'] ?? '';
        
        if ( empty( $meta_key ) ) {
            return null;
        }
        
        // Try the specific meta key first
        $value = get_post_meta( $property_id, $meta_key, true );
        
        // For gallery fields, if we have a value, return it immediately
        if ( $this->is_gallery_field( $field ) && ! empty( $value ) ) {
            return $value;
        }
        
        // BACKWARD COMPATIBILITY: Only if no value found with specific key
        if ( empty( $value ) ) {
            // Check if this is a gallery field
            if ( $this->is_gallery_field( $field ) ) {
                $metaKey = $field['metaKey'] ?? '';
                
                if ( $metaKey === 'images' ) {
                    $value = get_post_meta( $property_id, '_hvnly_gallery_images', true );
                } elseif ( $metaKey === 'title' ) {
                    $value = get_post_meta( $property_id, '_hvnly_gallery_title', true );
                }
            }
            
            // Check if this is a video field
            elseif ( $this->is_video_field( $field ) ) {
                $metaKey = $field['metaKey'] ?? '';
                
                if ( $metaKey === 'url' ) {
                    $value = get_post_meta( $property_id, '_hvnly_video_url', true );
                } elseif ( $metaKey === 'title' ) {
                    $value = get_post_meta( $property_id, '_hvnly_video_title', true );
                } elseif ( $metaKey === 'thumbnail' ) {
                    $value = get_post_meta( $property_id, '_hvnly_video_thumbnail', true );
                }
            }
            
            // Check if this is a map field
            elseif ( $this->is_map_field( $field ) ) {
                $metaKey = $field['metaKey'] ?? '';
                
                if ( $metaKey === 'address' ) {
                    $value = get_post_meta( $property_id, '_hvnly_property_address', true );
                } elseif ( $metaKey === 'latitude' ) {
                    $value = get_post_meta( $property_id, '_hvnly_property_latitude', true );
                } elseif ( $metaKey === 'longitude' ) {
                    $value = get_post_meta( $property_id, '_hvnly_property_longitude', true );
                }
            }
            
            // Check if this is a document field
            elseif ( $this->is_document_field( $field ) ) {
                $metaKey = $field['metaKey'] ?? '';
                
                if ( $metaKey === 'icon' ) {
                    $value = get_post_meta( $property_id, $field['name'] ?? '', true );
                } elseif ( $metaKey === 'label' ) {
                    $value = get_post_meta( $property_id, $field['name'] ?? '', true );
                } elseif ( $metaKey === 'url' ) {
                    $value = get_post_meta( $property_id, $field['name'] ?? '', true );
                }
            }
        }
        
        return $value;
    }

    /**
     * Render a group using existing templates.
     *
     * @param array $group_fields
     * @param int   $property_id
     */
    private function render_group( $group_fields, $property_id ) {
        if ( empty( $group_fields ) ) {
            return;
        }
        
        // Determine group type from first field
        $first_field = $group_fields[0];
        $group_type = $first_field['group_type'] ?? $this->detect_group_type( $first_field );
        $group_name = $first_field['group_name'] ?? '';
        $group_base_id = $first_field['group_base_id'] ?? '';
        $group_id = $first_field['group_id'] ?? '';
        
        // Prepare group data with values from this group's meta keys
        $values = [];
        $title_key = '';
        $images_key = '';
        $address_key = '';
        $lat_key = '';
        $lng_key = '';
        $url_key = '';
        $thumbnail_key = '';
        $icon_key = '';
        $label_key = '';
        
        foreach ( $group_fields as $field ) {
            $meta_key = $field['name'] ?? $field['id'] ?? '';
            $metaKey = $field['metaKey'] ?? $this->extract_meta_key( $field );
            
            if ( empty( $meta_key ) ) {
                continue;
            }
            
            // Get value from SPECIFIC meta key
            $value = get_post_meta( $property_id, $meta_key, true );
            
            // Store by metaKey
            if ( ! empty( $metaKey ) ) {
                $values[ $metaKey ] = $value;
            }
            
            // Track keys by type
            if ( strpos( $meta_key, '_title' ) !== false || $metaKey === 'title' ) {
                $title_key = $meta_key;
            }
            if ( strpos( $meta_key, '_images' ) !== false || $metaKey === 'images' ) {
                $images_key = $meta_key;
            }
            if ( strpos( $meta_key, '_address' ) !== false || $metaKey === 'address' ) {
                $address_key = $meta_key;
            }
            if ( strpos( $meta_key, '_latitude' ) !== false || $metaKey === 'latitude' ) {
                $lat_key = $meta_key;
            }
            if ( strpos( $meta_key, '_longitude' ) !== false || $metaKey === 'longitude' ) {
                $lng_key = $meta_key;
            }
            if ( strpos( $meta_key, '_url' ) !== false || $metaKey === 'url' ) {
                $url_key = $meta_key;
            }
            if ( strpos( $meta_key, '_thumbnail' ) !== false || $metaKey === 'thumbnail' ) {
                $thumbnail_key = $meta_key;
            }
            if ( strpos( $meta_key, '_icon' ) !== false || $metaKey === 'icon' ) {
                $icon_key = $meta_key;
            }
            if ( strpos( $meta_key, '_label' ) !== false || $metaKey === 'label' ) {
                $label_key = $meta_key;
            }
        }
        
        // For document groups, collect ALL document data
        if ( $group_type === 'property_docs' ) {
            $documents_data = $this->get_documents_data( $property_id );
            $values['documents'] = $documents_data['documents'];
        }
        
        // For map groups, collect ALL map data
        if ( $group_type === 'map' ) {
            // FIRST: Try to get from stored reference keys
            $active_lat_key = get_post_meta($property_id, '_hvnly_active_map_latitude_key', true);
            $active_lng_key = get_post_meta($property_id, '_hvnly_active_map_longitude_key', true);
            $active_address_key = get_post_meta($property_id, '_hvnly_active_map_address_key', true);
            
            if (!empty($active_lat_key) && !empty($active_lng_key)) {
                $values['latitude'] = get_post_meta($property_id, $active_lat_key, true);
                $values['longitude'] = get_post_meta($property_id, $active_lng_key, true);
                $values['address'] = get_post_meta($property_id, $active_address_key, true);
            }
            
            // SECOND: If not found, try from current group's keys
            if (empty($values['latitude'])) {
                $values['latitude'] = $lat_key ? get_post_meta($property_id, $lat_key, true) : '';
            }
            if (empty($values['longitude'])) {
                $values['longitude'] = $lng_key ? get_post_meta($property_id, $lng_key, true) : '';
            }
            if (empty($values['address'])) {
                $values['address'] = $address_key ? get_post_meta($property_id, $address_key, true) : '';
            }
            
            // THIRD: Search all meta for map fields if still empty
            if (empty($values['latitude']) || empty($values['longitude'])) {
                $all_meta = get_post_meta($property_id);
                foreach ($all_meta as $meta_key => $meta_value) {
                    if (preg_match('/^map_.+_latitude$/i', $meta_key)) {
                        $lat_val = is_array($meta_value) ? ($meta_value[0] ?? '') : $meta_value;
                        if (!empty($lat_val) && is_numeric($lat_val)) {
                            $base_key = preg_replace('/_latitude$/i', '', $meta_key);
                            $values['latitude'] = (float) $lat_val;
                            $values['longitude'] = (float) get_post_meta($property_id, $base_key . '_longitude', true);
                            $values['address'] = get_post_meta($property_id, $base_key . '_address', true);
                            break;
                        }
                    }
                }
            }
            
            // FOURTH: Fallback to legacy keys
            if (empty($values['latitude'])) {
                $values['latitude'] = get_post_meta($property_id, '_hvnly_property_latitude', true);
            }
            if (empty($values['longitude'])) {
                $values['longitude'] = get_post_meta($property_id, '_hvnly_property_longitude', true);
            }
            if (empty($values['address'])) {
                $values['address'] = get_post_meta($property_id, '_hvnly_property_address', true);
            }
        }
        
        // For video groups, collect ALL video data
        if ( $group_type === 'video' ) {
            $video_data = $this->get_video_data( $property_id );
            $values['title'] = $video_data['title'];
            $values['url'] = $video_data['url'];
            $values['thumbnail'] = $video_data['thumbnail'];
        }
        
        // For gallery groups, collect gallery data
        if ( $group_type === 'gallery' ) {
            $gallery_data = $this->get_gallery_data( $property_id );
            $values['title'] = $gallery_data['title'];
            $values['images'] = $gallery_data['images'];
        }
        
        // Prepare group data for template
        $group_data = [
            'property_id' => $property_id,
            'fields' => $group_fields,
            'group_name' => $group_name,
            'group_type' => $group_type,
            'group_base_id' => $group_base_id,
            'group_id' => $group_id,
            'values' => $values,
            'title_key' => $title_key,
            'images_key' => $images_key,
            'address_key' => $address_key,
            'lat_key' => $lat_key,
            'lng_key' => $lng_key,
            'url_key' => $url_key,
            'thumbnail_key' => $thumbnail_key,
            'icon_key' => $icon_key,
            'label_key' => $label_key,
        ];
        
        // Use existing template based on group type
        switch ( $group_type ) {
            case 'map':
                // Only render map if we have coordinates
                if ( ! empty( $values['latitude'] ) && ! empty( $values['longitude'] ) ) {
                    hvnly_get_template( 'single-property/location-card.php', $group_data );
                } elseif ( ! empty( $values['address'] ) ) {
                    // If only address, still show but without map
                    hvnly_get_template( 'single-property/location-card.php', $group_data );
                }
                break;
                
            case 'video':
                // Only render video if we have URL
                if ( ! empty( $values['url'] ) ) {
                    hvnly_get_template( 'single-property/video-card.php', $group_data );
                }
                break;
                
            case 'gallery':
                // Only render gallery if we have images
                if ( ! empty( $values['images'] ) ) {
                    hvnly_get_template( 'single-property/gallery-card.php', $group_data );
                }
                break;
                
            case 'property_docs':
                // Only render documents if we have documents
                if ( ! empty( $values['documents'] ) ) {
                    hvnly_get_template( 'single-property/fields/group/property_docs.php', $group_data );
                }
                break;
                
            default:
                // For unknown groups, render fields individually
                foreach ( $group_fields as $field ) {
                    $this->render_field( $field, $property_id );
                }
                break;
        }
    }

    /**
     * Extract metaKey from field
     *
     * @param array $field
     * @return string
     */
    private function extract_meta_key( $field ) {
        if ( ! empty( $field['metaKey'] ) ) {
            return $field['metaKey'];
        }
        
        $id = $field['id'] ?? '';
        $parts = explode( '_', $id );
        return end( $parts );
    }

    /**
     * Get field category
     *
     * @param array $field
     * @return string
     */
    private function get_field_category( $field ) {
        // Check if it's a group field
        if ( ! empty( $field['group_id'] ) || ! empty( $field['group_type'] ) ) {
            return 'group';
        }

        // Check if it's a preset field
        if ( ! empty( $field['id'] ) && strpos( $field['id'], 'preset_' ) === 0 ) {
            return 'preset';
        }

        // Default field
        return 'default';
    }

    /**
     * Get field template name
     *
     * @param array $field
     * @return string
     */
    private function get_field_template_name( $field ) {
        $field_type = $field['type'] ?? 'text';
        $category = $this->get_field_category( $field );

        // Group fields use group_type
        if ( $category === 'group' ) {
            return $field['group_type'] ?? $field_type;
        }

        // Preset fields use a simplified name
        if ( $category === 'preset' ) {
            $id = $field['id'] ?? '';
            $name = str_replace( 'preset_hvnly_property_field_', '', $id );
            $name = str_replace( '_', '-', $name );
            
            $preset_map = [
                'fullname' => 'fullname',
                'email' => 'email',
                'phone' => 'phone',
                'company' => 'company',
                'website' => 'website',
                'number-bedrooms' => 'bedrooms',
                'number-bathrooms' => 'bathrooms',
                'number-squarefeet' => 'squarefeet',
                'number-garage' => 'garage',
                'text-address' => 'address',
                'text-city' => 'city',
                'text-zipcode' => 'zipcode',
                'checkbox-pool' => 'pool',
                'checkbox-garden' => 'garden',
                'checkbox-garage' => 'garage-checkbox'
            ];
            
            return $preset_map[ $name ] ?? $name;
        }

        // Default fields use their type
        return $field_type;
    }

    /**
     * Check if template exists
     *
     * @param string $template_path
     * @return bool
     */
    private function template_exists( $template_path ) {
        $theme_template = get_stylesheet_directory() . '/havenlytics/' . $template_path;
        $plugin_template = HVNLYNAB_PATH . 'templates/' . $template_path;
        
        return file_exists( $theme_template ) || file_exists( $plugin_template );
    }

    /**
     * Render a single field using the enhanced template system
     *
     * @param array $field
     * @param int   $property_id
     */
    private function render_field( $field, $property_id ) {
        // Skip if field is disabled
        if ( isset( $field['enabled'] ) && ! $field['enabled'] ) {
            return;
        }
        
        $meta_key = $field['name'] ?? $field['id'] ?? '';
        if ( empty( $meta_key ) ) {
            return;
        }
        
        $value = $this->get_field_value( $field, $property_id );
        
        // Skip empty values
        if ( ! $this->has_value( $value ) ) {
            return;
        }
        
        // Determine field category
        $category = $this->get_field_category( $field );
        
        // Get template name
        $template_name = $this->get_field_template_name( $field );
        
        // FIXED: Check for checkbox repeater fields
        $is_checkbox_repeater = false;
        
        // Check if it's a checkbox field with array/repeater data
        if ( $field['type'] === 'checkbox' ) {
            // Check if the value is an array or contains JSON/serialized array data
            if ( is_array( $value ) && !empty( $value ) ) {
                $is_checkbox_repeater = true;
            } elseif ( is_string( $value ) ) {
                // Check if it's a JSON array
                $decoded = json_decode( $value, true );
                if ( is_array( $decoded ) && !empty( $decoded ) ) {
                    $is_checkbox_repeater = true;
                    $value = $decoded; // Convert to array for template
                }
                // Check if it's a serialized array
                elseif ( is_serialized( $value ) ) {
                    $unserialized = maybe_unserialize( $value );
                    if ( is_array( $unserialized ) && !empty( $unserialized ) ) {
                        $is_checkbox_repeater = true;
                        $value = $unserialized; // Convert to array for template
                    }
                }
                // Check if it's a comma-separated list (simple repeater)
                elseif ( strpos( $value, ',' ) !== false ) {
                    $items = array_map( 'trim', explode( ',', $value ) );
                    $items = array_filter( $items );
                    if ( count( $items ) > 1 ) {
                        $is_checkbox_repeater = true;
                        $value = $items; // Convert to array for template
                    }
                }
            }
            
            // Additional check for fields that are specifically designed as repeaters
            // based on field ID or label
            if ( !$is_checkbox_repeater ) {
                $field_id = $field['id'] ?? '';
                $field_label = $field['label'] ?? '';
                
                $repeater_indicators = array('features', 'amenities', 'list', 'items', 'checkbox-repeater');
                foreach ( $repeater_indicators as $indicator ) {
                    if ( stripos( $field_id, $indicator ) !== false || stripos( $field_label, $indicator ) !== false ) {
                        // If it has multiple values in a simple format, treat as repeater
                        if ( is_string( $value ) && strpos( $value, ',' ) !== false ) {
                            $items = array_map( 'trim', explode( ',', $value ) );
                            $items = array_filter( $items );
                            if ( count( $items ) > 1 ) {
                                $is_checkbox_repeater = true;
                                $value = $items;
                                break;
                            }
                        }
                    }
                }
            }
        }
        
        // Use checkbox-repeater template if detected
        if ( $is_checkbox_repeater ) {
            $template_name = 'checkbox-repeater';
            $category = 'preset'; // Put in preset folder to match your template path
        }
        
        // Prepare field data
        $field_data = [
            'field'       => $field,
            'value'       => $value,
            'field_value' => $value,
            'property_id' => $property_id,
            'field_name'  => $meta_key,
            'field_label' => $field['label'] ?? '',
            'field_type'  => $field['type'] ?? 'text',
            'category'    => $category,
            'field_options' => isset( $field['options'] ) ? $field['options'] : [],
        ];
        
        // Try category-specific template first
        $template_path = 'single-property/fields/' . $category . '/' . $template_name . '.php';
        
        if ( $this->template_exists( $template_path ) ) {
            hvnly_get_template( $template_path, $field_data );
            return;
        }
        
        // Fallback to old template naming convention
        $old_template_map = [
            'text'     => 'text-field',
            'textarea' => 'textarea-field',
            'number'   => 'number-field',
            'email'    => 'email-field',
            'url'      => 'url-field',
            'checkbox' => 'checkbox-field',
            'select'   => 'select-field',
            'image'    => 'image-field',
            'file'     => 'file-field',
            'date'     => 'date-field',
        ];
        
        $old_template = $old_template_map[ $field['type'] ?? 'text' ] ?? 'fallback-field';
        hvnly_get_template( "single-property/fields/{$old_template}.php", $field_data );
    }

    /**
     * Get field value with backward compatibility
     *
     * @param array $field
     * @param int   $property_id
     * @return mixed
     */
    private function get_field_value( $field, $property_id ) {
        $meta_key = $field['name'] ?? $field['id'] ?? '';
        
        if ( empty( $meta_key ) ) {
            return null;
        }
        
        // Try the specific meta key first
        $value = get_post_meta( $property_id, $meta_key, true );
        
        // BACKWARD COMPATIBILITY: If no value found, try legacy keys
        if ( empty( $value ) ) {
            // Check if this is a gallery field
            if ( $this->is_gallery_field( $field ) ) {
                if ( strpos( $meta_key, '_images' ) !== false ) {
                    $value = get_post_meta( $property_id, '_hvnly_gallery_images', true );
                } elseif ( strpos( $meta_key, '_title' ) !== false ) {
                    $value = get_post_meta( $property_id, '_hvnly_gallery_title', true );
                }
            }
            
            // Check if this is a video field
            elseif ( $this->is_video_field( $field ) ) {
                if ( strpos( $meta_key, '_url' ) !== false ) {
                    $value = get_post_meta( $property_id, '_hvnly_video_url', true );
                } elseif ( strpos( $meta_key, '_title' ) !== false ) {
                    $value = get_post_meta( $property_id, '_hvnly_video_title', true );
                } elseif ( strpos( $meta_key, '_thumbnail' ) !== false ) {
                    $value = get_post_meta( $property_id, '_hvnly_video_thumbnail', true );
                }
            }
            
            // Check if this is a map field
            elseif ( $this->is_map_field( $field ) ) {
                if ( strpos( $meta_key, '_address' ) !== false ) {
                    $value = get_post_meta( $property_id, '_hvnly_property_address', true );
                } elseif ( strpos( $meta_key, '_latitude' ) !== false ) {
                    $value = get_post_meta( $property_id, '_hvnly_property_latitude', true );
                } elseif ( strpos( $meta_key, '_longitude' ) !== false ) {
                    $value = get_post_meta( $property_id, '_hvnly_property_longitude', true );
                }
            }
            
            // Check if this is a document field
            elseif ( $this->is_document_field( $field ) ) {
                // For document fields, we handle in the group template
                return null;
            }
            
            // Check for preset fields
            elseif ( strpos( $field['id'] ?? '', 'preset_' ) === 0 ) {
                // Preset fields use their own meta keys, so if we're here, no value found
                // Return empty to skip rendering
                return null;
            }
        }
        
        return $value;
    }

    /**
     * Check if field is a document field
     *
     * @param array $field
     * @return bool
     */
    private function is_document_field( $field ) {
        return ( $field['group_type'] ?? '' ) === 'property_docs' || 
               ( $field['type'] ?? '' ) === 'property_docs' ||
               strpos( $field['name'] ?? '', 'property_docs_' ) === 0;
    }

    /**
     * Check if field is a gallery field
     *
     * @param array $field
     * @return bool
     */
    private function is_gallery_field( $field ) {
        return ( $field['group_type'] ?? '' ) === 'gallery' || 
               ( $field['type'] ?? '' ) === 'gallery' ||
               strpos( $field['name'] ?? '', 'gallery_' ) === 0;
    }

    /**
     * Check if field is a video field
     *
     * @param array $field
     * @return bool
     */
    private function is_video_field( $field ) {
        return ( $field['group_type'] ?? '' ) === 'video' || 
               ( $field['type'] ?? '' ) === 'video' ||
               strpos( $field['name'] ?? '', 'video_' ) === 0;
    }

    /**
     * Check if field is a map field
     *
     * @param array $field
     * @return bool
     */
    private function is_map_field( $field ) {
        return ( $field['group_type'] ?? '' ) === 'map' || 
               ( $field['type'] ?? '' ) === 'map' ||
               strpos( $field['name'] ?? '', 'map_' ) === 0;
    }

    /**
     * Check if value has meaningful data.
     *
     * @param mixed $value
     * @return bool
     */
    private function has_value( $value ) {
        if ( is_null( $value ) ) {
            return false;
        }
        
        if ( is_string( $value ) ) {
            return '' !== trim( $value );
        }
        
        if ( is_array( $value ) ) {
            return ! empty( $value );
        }
        
        if ( is_numeric( $value ) ) {
            return true;
        }
        
        return ! empty( $value );
    }

    /**
     * Sort sections by their order property.
     *
     * @param array $sections
     * @return array
     */
    private function sort_sections_by_order( $sections ) {
        uasort( $sections, function( $a, $b ) {
            $a_order = (int) ( $a['order'] ?? 999 );
            $b_order = (int) ( $b['order'] ?? 999 );
            return $a_order - $b_order;
        });
        
        return $sections;
    }

    /**
     * Sort fields by their order property.
     *
     * @param array $fields
     * @return array
     */
    private function sort_fields_by_order( $fields ) {
        usort( $fields, function( $a, $b ) {
            $a_order = (int) ( $a['order'] ?? 999 );
            $b_order = (int) ( $b['order'] ?? 999 );
            return $a_order - $b_order;
        });
        
        return $fields;
    }
}