# HVAC Trainer System Documentation

This document provides comprehensive documentation for all functionality related to the HVAC Trainer custom post type and Find A Trainer page in the HVAC Community Events plugin.

## Table of Contents

1. [System Overview](#system-overview)
2. [Trainer Profile Custom Post Type](#trainer-profile-custom-post-type)
3. [Find A Trainer Page](#find-a-trainer-page)
4. [MapGeo Integration](#mapgeo-integration)
5. [User Roles & Permissions](#user-roles--permissions)
6. [API Reference](#api-reference)
7. [Frontend Components](#frontend-components)
8. [Database Schema](#database-schema)
9. [Performance Optimizations](#performance-optimizations)
10. [Troubleshooting](#troubleshooting)

## System Overview

The HVAC Trainer System is a comprehensive solution for managing trainer profiles and providing a public directory with interactive map functionality. The system consists of:

- **Custom Post Type**: `trainer_profile` for storing trainer information
- **Find A Trainer Page**: Public-facing directory with search and filtering
- **MapGeo Integration**: Interactive map with trainer markers and modals
- **Profile Management**: Complete CRUD operations for trainer profiles
- **Taxonomy System**: Categorization for business types, training formats, etc.

### Architecture Diagram

```
WordPress Users (hvac_trainer/hvac_master_trainer)
    ↓
Trainer Profile Custom Post Type (trainer_profile)
    ↓
Find A Trainer Page ← MapGeo Integration → Interactive Map
    ↓
Search/Filter System → AJAX Handlers → Database Queries
```

## Trainer Profile Custom Post Type

### Overview

The `trainer_profile` custom post type stores comprehensive information about HVAC trainers, including personal details, certifications, business information, and location data.

### Core Files

- **Main Handler**: `includes/class-hvac-trainer-profile-manager.php`
- **Settings**: `includes/class-hvac-trainer-profile-settings.php` 
- **Status Management**: `includes/class-hvac-trainer-status.php`

### Custom Fields Reference

#### Personal Information

| Field Name | Type | Description | Example |
|------------|------|-------------|---------|
| `trainer_first_name` | string | First name | "John" |
| `trainer_last_name` | string | Last name | "Smith" |
| `trainer_display_name` | string | Public display name | "John Smith" |
| `trainer_city` | string | City location | "Chicago" |
| `trainer_state` | string | State/Province | "Illinois" |
| `trainer_country` | string | Country | "USA" |
| `profile_image_url` | string | Profile photo URL | "https://..." |
| `linkedin_profile_url` | string | LinkedIn profile | "https://linkedin..." |

#### Certification Details

| Field Name | Type | Description | Values |
|------------|------|-------------|--------|
| `certification_type` | string | Certification level | "Certified measureQuick Trainer", "Certified measureQuick Champion" |
| `certification_status` | string | Current status | "Active", "Expired", "Pending", "Disabled" |
| `certification_color` | string | Hex color for MapGeo | "#5077bb", "#f19a42", "#f0f7e8" |
| `date_certified` | string | Certification date | "2024-01-15" |
| `personal_accreditation` | string | Additional certifications | Free text |

#### Business Information

| Field Name | Type | Description |
|------------|------|-------------|
| `annual_revenue_target` | string | Revenue goals |
| `application_details` | string | Registration application details |

#### System Fields

| Field Name | Type | Description |
|------------|------|-------------|
| `user_id` | integer | WordPress user ID |
| `is_public_profile` | string | Visibility flag ("1" or "0") |
| `_last_geocode_attempt` | string | Last geocoding timestamp |
| `geocoded_lat` | string | Latitude coordinate |
| `geocoded_lng` | string | Longitude coordinate |

### Taxonomies

#### Business Type (`business_type`)
- Manufacturer
- Distributor
- Contractor
- Consultant
- Educator
- Government
- Other

#### Training Audience (`training_audience`)
- Anyone (open to the public)
- Industry professionals
- Internal staff in my company
- Registered students/members of my org/institution

#### Training Formats (`training_formats`)
- In-person
- Virtual
- Hybrid
- On-demand

#### Training Locations (`training_locations`)
- Online
- Local
- Regional Travel
- National Travel
- International Travel

#### Training Resources (`training_resources`)
- Classroom
- Training Lab
- Ducted Furnace(s)
- Ducted Air Handler(s)
- Ducted Air Conditioner(s)
- Ducted Heat Pump(s)
- Ductless Heat Pump(s)
- Training Manuals
- Presentation Slides
- LMS Platform / SCORM Files
- Custom Curriculum
- Other

### Profile Creation Workflow

1. **User Registration**: User completes registration form
2. **Role Assignment**: User assigned `hvac_trainer` or `hvac_master_trainer` role
3. **Profile Creation**: System automatically creates `trainer_profile` post
4. **Data Population**: Registration data mapped to profile fields
5. **Geocoding**: System attempts to geocode trainer location
6. **Approval Process**: Admin reviews and approves profile for public display

### Profile Management

#### Creating Profiles Programmatically

```php
$profile_manager = HVAC_Trainer_Profile_Manager::get_instance();

$profile_data = [
    'trainer_first_name' => 'John',
    'trainer_last_name' => 'Smith',
    'trainer_city' => 'Chicago',
    'trainer_state' => 'Illinois',
    'certification_type' => 'Certified measureQuick Trainer',
    'user_id' => 123,
    'is_public_profile' => '1'
];

$profile_id = $profile_manager->create_profile($profile_data);
```

#### Updating Profiles

```php
$profile_manager->update_profile($profile_id, $updated_data);
```

#### Retrieving Profiles

```php
// Get single profile
$profile = $profile_manager->get_profile($profile_id);

// Get all public profiles
$public_profiles = $profile_manager->get_public_profiles();

// Get profiles by criteria
$filtered_profiles = $profile_manager->get_profiles_by_criteria([
    'state' => 'Illinois',
    'certification_type' => 'Certified measureQuick Trainer'
]);
```

## Find A Trainer Page

### Overview

The Find A Trainer page (`/find-a-trainer/`) provides a public directory of approved trainer profiles with interactive search, filtering, and map functionality.

### Core Files

- **Page Handler**: `includes/find-trainer/class-hvac-find-trainer-page.php`
- **Directory Query**: `includes/find-trainer/class-hvac-trainer-directory-query.php`
- **Contact Handler**: `includes/find-trainer/class-hvac-contact-form-handler.php`
- **Template**: `templates/page-find-trainer.php`

### Features

#### Search Functionality
- **Text Search**: Search by trainer name, city, or state
- **Real-time Results**: AJAX-powered instant search results
- **Autocomplete**: Suggestions as user types

#### Filtering System
- **State/Province Filter**: Location-based filtering
- **Business Type Filter**: Filter by trainer business type
- **Training Format Filter**: Filter by available training formats
- **Training Resources Filter**: Filter by available resources
- **Multiple Filters**: Combine multiple filter criteria

#### Directory Display
- **Card Layout**: Clean trainer cards with essential information
- **Pagination**: Performance-optimized pagination system
- **Sorting**: Certified Trainers first, then Champions, then alphabetical
- **Champion Distinction**: Special styling for measureQuick Champions

#### Contact Integration
- **Contact Forms**: Direct contact forms for each trainer
- **Email Integration**: Automated email delivery to trainers
- **Lead Tracking**: Track contact form submissions

### AJAX Endpoints

| Endpoint | Purpose | Parameters |
|----------|---------|------------|
| `hvac_filter_trainers` | Filter trainers | `filters`, `page`, `per_page` |
| `hvac_search_trainers` | Search trainers | `search`, `page`, `per_page` |
| `hvac_get_filter_options` | Get filter options | None |
| `hvac_submit_contact_form` | Submit contact form | `trainer_id`, `name`, `email`, `message` |

### Frontend Implementation

#### JavaScript Integration

```javascript
// Initialize Find A Trainer functionality
jQuery(document).ready(function($) {
    HVAC_FindTrainer.init({
        ajax_url: hvac_find_trainer.ajax_url,
        nonce: hvac_find_trainer.nonce,
        filters: {
            state: [],
            business_type: [],
            training_format: []
        }
    });
});
```

#### CSS Classes

| Class | Purpose |
|-------|---------|
| `.hvac-trainer-card` | Individual trainer card container |
| `.hvac-trainer-card-certified` | Certified trainer styling |
| `.hvac-champion-card` | Champion trainer styling |
| `.hvac-trainer-filters` | Filter panel container |
| `.hvac-search-box` | Search input container |
| `.hvac-trainer-modal` | Trainer profile modal |

## MapGeo Integration

### Overview

The MapGeo integration provides an interactive map showing trainer locations with clickable markers that open detailed trainer modals.

### Core Files

- **Integration Handler**: `includes/find-trainer/class-hvac-mapgeo-integration.php`
- **Map Configuration**: Integrated in Find A Trainer page template

### Features

#### Interactive Map
- **Map ID**: 5872 (configured in MapGeo plugin)
- **Marker Display**: Trainers with geocoded coordinates appear as markers
- **Color Coding**: Different colors based on certification type
- **Click Handlers**: Custom click actions for trainer markers

#### Performance Optimizations
- **Request Deduplication**: Prevents duplicate AJAX calls
- **Caching System**: Caches trainer data for instant subsequent access
- **Click Throttling**: Prevents rapid-fire clicking issues
- **Fallback Handling**: Graceful degradation when data unavailable

#### Modal System
- **Trainer Profiles**: Complete trainer information in popup modals
- **Champion Filtering**: Champions don't show modals (directory-only display)
- **Contact Integration**: Direct contact forms within modals
- **Responsive Design**: Mobile-optimized modal display

### Technical Implementation

#### MapGeo Marker Configuration

```php
public function modify_map_layout($meta, $map_id = null) {
    // Only process for our specific map (5872)
    if ($map_id && $map_id != $this->map_id) {
        return $meta;
    }
    
    // Configure markers with trainer profile data
    foreach ($meta['markers'] as &$marker) {
        $trainer_profile_id = $this->find_trainer_profile_by_name($marker['title']);
        if ($trainer_profile_id) {
            $marker['action'] = 'hvac_show_trainer_modal';
            $marker['hvac_profile_id'] = $trainer_profile_id;
            $marker['id'] = 'trainer_' . $trainer_profile_id;
        }
    }
    
    return $meta;
}
```

#### JavaScript Modal Handler

```javascript
window.hvac_show_trainer_modal = function(markerData) {
    var profileId = markerData.hvac_profile_id;
    
    // Check cache first for immediate response
    if (window.hvacTrainerDataCache[profileId]) {
        var cachedData = window.hvacTrainerDataCache[profileId];
        if (typeof window.showTrainerModal === 'function') {
            window.showTrainerModal(cachedData);
        }
        return;
    }
    
    // Fetch profile data via AJAX if not cached
    // Implementation handles caching, error handling, and modal display
};
```

### Certification Color Coding

| Certification Type | Color | Usage |
|--------------------|-------|-------|
| Certified measureQuick Trainer | `#5077bb` | Primary trainer markers |
| Certified measureQuick Champion | `#f19a42` | Champion markers (no modals) |
| Default/Other | `#f0f7e8` | Fallback color |

## User Roles & Permissions

### HVAC Trainer (`hvac_trainer`)

#### Core Capabilities
- `read` - Basic WordPress read access
- `upload_files` - File upload capability
- `edit_hvac_profile` - Edit own trainer profile
- `view_hvac_dashboard` - Access trainer dashboard
- `manage_hvac_events` - Manage own events
- `manage_attendees` - Manage event attendees
- `email_attendees` - Send emails to attendees

#### Events Calendar Integration
- `publish_tribe_events` - Create and publish events
- `edit_tribe_events` - Edit events
- `delete_tribe_events` - Delete events
- `edit_published_tribe_events` - Edit published events
- `delete_published_tribe_events` - Delete published events
- `read_private_tribe_events` - View private events

### HVAC Master Trainer (`hvac_master_trainer`)

#### Extended Capabilities
- All trainer capabilities
- Access to master dashboard with analytics
- View aggregate trainer statistics
- Enhanced reporting capabilities

### Permission Checks

```php
// Check if user can edit trainer profiles
if (current_user_can('edit_hvac_profile')) {
    // Allow profile editing
}

// Check for master trainer capabilities
if (current_user_can('hvac_master_trainer')) {
    // Show master trainer features
}
```

## API Reference

### AJAX Handlers

#### Get Trainer Profile
**Endpoint**: `hvac_get_trainer_profile`
**Method**: POST
**Parameters**:
- `profile_id` (integer) - Trainer profile ID
- `nonce` (string) - Security nonce

**Response**:
```json
{
    "success": true,
    "data": {
        "profile_id": 5840,
        "user_id": "31",
        "name": "Jeremy Begley",
        "city": "Knoxville",
        "state": "Tennessee",
        "certification_type": "Certified measureQuick Trainer",
        "profile_image": "https://...",
        "business_type": "Independent Contractor",
        "event_count": 5,
        "training_formats": "In-Person, Virtual",
        "training_locations": "On-site, Remote",
        "upcoming_events": []
    }
}
```

#### Filter Trainers
**Endpoint**: `hvac_filter_trainers`
**Method**: POST
**Parameters**:
- `filters` (array) - Filter criteria
- `page` (integer) - Page number
- `per_page` (integer) - Results per page
- `nonce` (string) - Security nonce

**Response**:
```json
{
    "success": true,
    "data": {
        "html": "<div class='hvac-trainer-card'>...</div>",
        "pagination": "<div class='hvac-pagination'>...</div>",
        "count": 25,
        "page": 1,
        "max_pages": 3
    }
}
```

#### Search Trainers
**Endpoint**: `hvac_search_trainers`
**Method**: POST
**Parameters**:
- `search` (string) - Search query
- `page` (integer) - Page number
- `per_page` (integer) - Results per page
- `nonce` (string) - Security nonce

**Response**: Same format as filter trainers

### PHP API Methods

#### HVAC_Trainer_Profile_Manager Methods

```php
// Get instance
$manager = HVAC_Trainer_Profile_Manager::get_instance();

// Create profile
$profile_id = $manager->create_profile($data);

// Update profile
$manager->update_profile($profile_id, $data);

// Get profile
$profile = $manager->get_profile($profile_id);

// Get public profiles
$profiles = $manager->get_public_profiles();

// Delete profile
$manager->delete_profile($profile_id);
```

#### HVAC_Find_Trainer_Page Methods

```php
// Get instance
$page = HVAC_Find_Trainer_Page::get_instance();

// Render trainer cards
$page->render_trainer_cards($trainers);

// Get filter options
$options = $page->get_filter_options();

// Build query args
$args = $page->build_query_args($filters);
```

## Frontend Components

### CSS Architecture

#### Find A Trainer Styles (`assets/css/find-trainer.css`)

```css
/* Main container */
.hvac-find-trainer-container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
}

/* Search and filters */
.hvac-search-filters {
    display: flex;
    gap: 20px;
    margin-bottom: 30px;
    flex-wrap: wrap;
}

/* Trainer cards */
.hvac-trainer-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 20px;
    margin-bottom: 30px;
}

.hvac-trainer-card {
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 20px;
    background: white;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    transition: transform 0.2s, box-shadow 0.2s;
}

.hvac-trainer-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}

/* Certified trainer styling */
.hvac-trainer-card-certified {
    border-color: #5077bb;
}

.hvac-trainer-card-certified::before {
    content: "✓ Certified Trainer";
    background: #5077bb;
    color: white;
    padding: 4px 8px;
    border-radius: 4px;
    font-size: 12px;
    position: absolute;
    top: -8px;
    right: 10px;
}

/* Champion styling */
.hvac-champion-card {
    border-color: #f19a42;
    background: linear-gradient(135deg, #fff 0%, #fef9f5 100%);
}

.hvac-champion-card .hvac-trainer-name {
    color: #f19a42;
    font-weight: bold;
}
```

#### MapGeo Integration Styles

```css
/* MapGeo modal styling */
.hvac-trainer-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: white;
    border-radius: 8px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.3);
    max-width: 500px;
    width: 90%;
    max-height: 80vh;
    overflow-y: auto;
    z-index: 10000;
}

.hvac-modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0,0,0,0.5);
    z-index: 9999;
}

/* Map markers */
.hvac-trainer-marker {
    cursor: pointer;
    transition: all 0.2s;
}

.hvac-trainer-marker:hover {
    transform: scale(1.1);
}
```

### JavaScript Components

#### Find A Trainer JavaScript (`assets/js/find-trainer.js`)

```javascript
var HVAC_FindTrainer = {
    // Configuration
    config: {
        ajax_url: '',
        nonce: '',
        filters: {},
        current_page: 1,
        per_page: 12
    },
    
    // Initialize
    init: function(options) {
        this.config = Object.assign(this.config, options);
        this.bindEvents();
        this.loadInitialResults();
    },
    
    // Event bindings
    bindEvents: function() {
        // Search functionality
        jQuery('#hvac-trainer-search').on('input', this.handleSearch.bind(this));
        
        // Filter changes
        jQuery('.hvac-filter-select').on('change', this.handleFilterChange.bind(this));
        
        // Pagination
        jQuery(document).on('click', '.hvac-page-link', this.handlePagination.bind(this));
        
        // Trainer card clicks
        jQuery(document).on('click', '.hvac-open-profile', this.openTrainerModal.bind(this));
    },
    
    // Handle search input
    handleSearch: function(e) {
        var query = jQuery(e.target).val();
        this.performSearch(query);
    },
    
    // Handle filter changes
    handleFilterChange: function(e) {
        var $filter = jQuery(e.target);
        var filterType = $filter.data('filter');
        var value = $filter.val();
        
        this.config.filters[filterType] = value;
        this.applyFilters();
    },
    
    // Perform AJAX search
    performSearch: function(query) {
        jQuery.ajax({
            url: this.config.ajax_url,
            method: 'POST',
            data: {
                action: 'hvac_search_trainers',
                search: query,
                page: 1,
                per_page: this.config.per_page,
                nonce: this.config.nonce
            },
            success: this.updateResults.bind(this)
        });
    },
    
    // Apply filters
    applyFilters: function() {
        jQuery.ajax({
            url: this.config.ajax_url,
            method: 'POST',
            data: {
                action: 'hvac_filter_trainers',
                filters: this.config.filters,
                page: 1,
                per_page: this.config.per_page,
                nonce: this.config.nonce
            },
            success: this.updateResults.bind(this)
        });
    },
    
    // Update results display
    updateResults: function(response) {
        if (response.success) {
            jQuery('.hvac-trainer-cards').html(response.data.html);
            jQuery('.hvac-pagination').html(response.data.pagination);
            this.updateResultsCount(response.data.count);
        }
    },
    
    // Open trainer modal
    openTrainerModal: function(e) {
        e.preventDefault();
        var profileId = jQuery(e.target).data('profile-id');
        this.showTrainerProfile(profileId);
    }
};
```

## Database Schema

### Trainer Profile Posts Table
```sql
-- wp_posts table entries for trainer_profile post type
SELECT 
    ID,
    post_title,
    post_status,
    post_type,
    post_date
FROM wp_posts 
WHERE post_type = 'trainer_profile';
```

### Trainer Profile Meta Data
```sql
-- wp_postmeta table entries for trainer profiles
SELECT 
    post_id,
    meta_key,
    meta_value
FROM wp_postmeta 
WHERE post_id IN (
    SELECT ID FROM wp_posts WHERE post_type = 'trainer_profile'
)
ORDER BY post_id, meta_key;
```

### Taxonomy Relationships
```sql
-- Get trainer profiles with business type taxonomy
SELECT 
    p.ID,
    p.post_title,
    t.name as business_type
FROM wp_posts p
LEFT JOIN wp_term_relationships tr ON p.ID = tr.object_id
LEFT JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
LEFT JOIN wp_terms t ON tt.term_id = t.term_id
WHERE p.post_type = 'trainer_profile'
AND tt.taxonomy = 'business_type';
```

### Key Database Queries

#### Get Public Trainer Profiles
```php
$args = [
    'post_type' => 'trainer_profile',
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'meta_query' => [
        'relation' => 'AND',
        [
            'key' => 'is_public_profile',
            'value' => '1',
            'compare' => '='
        ],
        [
            'key' => 'user_id',
            'value' => $approved_user_ids,
            'compare' => 'IN'
        ]
    ]
];
$query = new WP_Query($args);
```

#### Get Geocoded Trainers for Map
```php
$args = [
    'post_type' => 'trainer_profile',
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'meta_query' => [
        'relation' => 'AND',
        [
            'key' => 'is_public_profile',
            'value' => '1',
            'compare' => '='
        ],
        [
            'key' => 'geocoded_lat',
            'compare' => 'EXISTS'
        ],
        [
            'key' => 'geocoded_lng',
            'compare' => 'EXISTS'
        ]
    ]
];
```

## Performance Optimizations

### MapGeo Integration Optimizations

#### Request Deduplication
```javascript
// Prevent duplicate AJAX requests
window.hvacTrainerDataCache = {};
window.hvacPendingRequests = {};

function getTrainerProfile(profileId) {
    // Check cache first
    if (window.hvacTrainerDataCache[profileId]) {
        return Promise.resolve(window.hvacTrainerDataCache[profileId]);
    }
    
    // Check if request already pending
    if (window.hvacPendingRequests[profileId]) {
        return window.hvacPendingRequests[profileId];
    }
    
    // Make new request and cache promise
    window.hvacPendingRequests[profileId] = makeAjaxRequest(profileId)
        .then(function(data) {
            window.hvacTrainerDataCache[profileId] = data;
            delete window.hvacPendingRequests[profileId];
            return data;
        });
    
    return window.hvacPendingRequests[profileId];
}
```

#### Click Throttling
```javascript
// Prevent rapid-fire clicking
var lastClickTime = 0;
function handleMarkerClick(e) {
    var now = Date.now();
    if (now - lastClickTime < 500) {
        return; // Throttle clicks to 500ms intervals
    }
    lastClickTime = now;
    
    // Process click
    processMarkerClick(e);
}
```

### Database Query Optimization

#### Efficient Trainer Queries
```php
// Use meta_query for better performance with indexes
$args = [
    'post_type' => 'trainer_profile',
    'posts_per_page' => 12,
    'paged' => $page,
    'meta_query' => [
        'relation' => 'AND',
        [
            'key' => 'is_public_profile',
            'value' => '1',
            'compare' => '='
        ]
    ],
    'fields' => 'ids' // Only get IDs when possible
];

// Add user status filter efficiently
$user_query = new WP_User_Query([
    'meta_query' => [
        [
            'key' => 'account_status',
            'value' => ['approved', 'active', 'inactive'],
            'compare' => 'IN'
        ]
    ],
    'fields' => 'ID'
]);

$approved_user_ids = $user_query->get_results();
if (!empty($approved_user_ids)) {
    $args['meta_query'][] = [
        'key' => 'user_id',
        'value' => $approved_user_ids,
        'compare' => 'IN'
    ];
}
```

#### Caching Strategies
```php
// Cache expensive queries
$cache_key = 'hvac_public_trainers_' . md5(serialize($args));
$trainers = wp_cache_get($cache_key, 'hvac_trainers');

if (false === $trainers) {
    $query = new WP_Query($args);
    $trainers = $query->posts;
    wp_cache_set($cache_key, $trainers, 'hvac_trainers', HOUR_IN_SECONDS);
}
```

## Troubleshooting

### Common Issues

#### Trainers Not Appearing on Map
**Symptoms**: Trainers visible in directory but not on MapGeo map
**Causes**:
1. Missing geocoding data (latitude/longitude)
2. MapGeo configuration issues
3. Profile not public

**Solutions**:
```php
// Check geocoding status
$lat = get_post_meta($profile_id, 'geocoded_lat', true);
$lng = get_post_meta($profile_id, 'geocoded_lng', true);

if (empty($lat) || empty($lng)) {
    // Trigger geocoding
    $geocoding_service = HVAC_Geocoding_Service::get_instance();
    $geocoding_service->geocode_trainer($profile_id);
}

// Check public status
$is_public = get_post_meta($profile_id, 'is_public_profile', true);
if ($is_public !== '1') {
    update_post_meta($profile_id, 'is_public_profile', '1');
}
```

#### Modal Not Opening
**Symptoms**: Clicking map markers doesn't open trainer modal
**Causes**:
1. JavaScript errors preventing modal system
2. Missing trainer data
3. Champion profiles (intentionally no modal)

**Solutions**:
```javascript
// Debug modal system
console.log('MapGeo integration loaded:', typeof window.hvac_show_trainer_modal);
console.log('Modal function available:', typeof window.showTrainerModal);

// Check if trainer is Champion (no modal should show)
if (trainerData.certification_type === 'Certified measureQuick Champion') {
    console.log('Champion detected - no modal shown');
    return;
}
```

#### Search/Filter Not Working
**Symptoms**: Search and filters not returning results
**Causes**:
1. AJAX endpoint errors
2. Nonce verification failures
3. Database query issues

**Solutions**:
```php
// Debug AJAX handlers
add_action('wp_ajax_hvac_filter_trainers', function() {
    error_log('Filter trainers AJAX called');
    error_log('POST data: ' . print_r($_POST, true));
    
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'], 'hvac_find_trainer')) {
        error_log('Nonce verification failed');
        wp_send_json_error('Invalid nonce');
        return;
    }
    
    // Continue with handler...
});
```

#### Performance Issues
**Symptoms**: Slow loading times, multiple AJAX requests
**Causes**:
1. Duplicate requests not prevented
2. Missing caching
3. Inefficient database queries

**Solutions**:
1. Implement request deduplication
2. Add caching layers
3. Optimize database queries with proper indexes
4. Use pagination for large datasets

### Debug Mode

Enable debug logging for troubleshooting:

```php
// Add to wp-config.php
define('HVAC_DEBUG', true);

// In plugin code
if (defined('HVAC_DEBUG') && HVAC_DEBUG) {
    error_log('HVAC Debug: ' . $message);
}
```

### Performance Monitoring

Monitor system performance:

```javascript
// Track AJAX request timing
var startTime = performance.now();
jQuery.ajax({
    // ... ajax config
    success: function(response) {
        var endTime = performance.now();
        console.log('AJAX request took:', (endTime - startTime), 'milliseconds');
    }
});
```

## Conclusion

The HVAC Trainer System provides a comprehensive solution for managing trainer profiles and presenting them through an interactive Find A Trainer directory. The system is designed for performance, scalability, and user experience, with extensive customization options and robust error handling.

For additional support or feature requests, refer to the main plugin documentation or contact the development team.