# HVAC Trainer System API Reference

This document provides detailed API reference for developers working with the HVAC Trainer system, including PHP classes, JavaScript APIs, AJAX endpoints, and database schemas.

## Table of Contents

1. [PHP Classes](#php-classes)
2. [AJAX Endpoints](#ajax-endpoints)
3. [JavaScript APIs](#javascript-apis)
4. [Database Schema](#database-schema)
5. [Hooks & Filters](#hooks--filters)
6. [Constants & Configuration](#constants--configuration)
7. [Error Codes](#error-codes)

## PHP Classes

### HVAC_Trainer_Profile_Manager

**File**: `includes/class-hvac-trainer-profile-manager.php`  
**Purpose**: Core trainer profile management functionality

#### Class Methods

##### `get_instance()`
Returns singleton instance of the profile manager.

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

**Returns**: `HVAC_Trainer_Profile_Manager` - Singleton instance

##### `create_profile($data)`
Creates a new trainer profile.

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

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

**Parameters**:
- `$data` (array) - Profile data array

**Returns**: `int|false` - Profile post ID on success, false on failure

**Data Fields**:
- `trainer_first_name` (string) - First name
- `trainer_last_name` (string) - Last name
- `trainer_display_name` (string) - Display name
- `trainer_city` (string) - City
- `trainer_state` (string) - State/Province
- `trainer_country` (string) - Country
- `profile_image_url` (string) - Profile image URL
- `certification_type` (string) - Certification level
- `user_id` (int) - WordPress user ID
- `is_public_profile` (string) - Public visibility ('1' or '0')

##### `update_profile($profile_id, $data)`
Updates an existing trainer profile.

```php
$updated_data = [
    'trainer_city' => 'New York',
    'trainer_state' => 'New York',
    'certification_type' => 'Certified measureQuick Champion'
];

$success = $manager->update_profile(5840, $updated_data);
```

**Parameters**:
- `$profile_id` (int) - Profile post ID
- `$data` (array) - Updated profile data

**Returns**: `bool` - Success status

##### `get_profile($profile_id)`
Retrieves a trainer profile.

```php
$profile = $manager->get_profile(5840);
```

**Parameters**:
- `$profile_id` (int) - Profile post ID

**Returns**: `array|false` - Profile data array or false if not found

**Return Structure**:
```php
[
    'profile_id' => 5840,
    'user_id' => 31,
    'name' => 'John Smith',
    'city' => 'Chicago',
    'state' => 'Illinois',
    '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'
]
```

##### `get_public_profiles($args = [])`
Retrieves all public trainer profiles.

```php
$profiles = $manager->get_public_profiles([
    'posts_per_page' => 20,
    'meta_query' => [
        [
            'key' => 'trainer_state',
            'value' => 'Illinois',
            'compare' => '='
        ]
    ]
]);
```

**Parameters**:
- `$args` (array) - WP_Query arguments

**Returns**: `array` - Array of profile data

##### `delete_profile($profile_id)`
Deletes a trainer profile.

```php
$success = $manager->delete_profile(5840);
```

**Parameters**:
- `$profile_id` (int) - Profile post ID

**Returns**: `bool` - Success status

##### `migrate_certification_colors()`
Migrates existing profiles to add certification color fields.

```php
$manager->migrate_certification_colors();
```

**Returns**: `void`

##### `get_certification_color($certification_type)`
Gets the color code for a certification type.

```php
$color = $manager->get_certification_color('Certified measureQuick Trainer');
// Returns: '#5077bb'
```

**Parameters**:
- `$certification_type` (string) - Certification type

**Returns**: `string` - Hex color code

**Color Mapping**:
- `'Certified measureQuick Champion'` → `'#f19a42'`
- `'Certified measureQuick Trainer'` → `'#5077bb'`
- Default → `'#f0f7e8'`

### HVAC_Find_Trainer_Page

**File**: `includes/find-trainer/class-hvac-find-trainer-page.php`  
**Purpose**: Find A Trainer page functionality

#### Class Methods

##### `get_instance()`
Returns singleton instance.

```php
$page = HVAC_Find_Trainer_Page::get_instance();
```

##### `render_page()`
Renders the complete Find A Trainer page.

```php
$page->render_page();
```

**Returns**: `void` - Outputs HTML directly

##### `get_filter_options()`
Gets available filter options for the directory.

```php
$options = $page->get_filter_options();
```

**Returns**: `array` - Filter options structure

**Return Structure**:
```php
[
    'states' => ['Illinois', 'New York', 'California'],
    'business_types' => ['Contractor', 'Distributor', 'Consultant'],
    'training_formats' => ['In-person', 'Virtual', 'Hybrid'],
    'training_resources' => ['Classroom', 'Training Lab', 'Online']
]
```

##### `build_query_args($filters, $page = 1, $per_page = 12)`
Builds WP_Query arguments from filter criteria.

```php
$filters = [
    'state' => 'Illinois',
    'business_type' => ['Contractor', 'Consultant'],
    'search' => 'John'
];

$args = $page->build_query_args($filters, 1, 20);
```

**Parameters**:
- `$filters` (array) - Filter criteria
- `$page` (int) - Page number
- `$per_page` (int) - Results per page

**Returns**: `array` - WP_Query arguments

##### `render_trainer_cards($trainers)`
Renders HTML for trainer cards.

```php
$trainers = $page->get_filtered_trainers($filters);
$page->render_trainer_cards($trainers);
```

**Parameters**:
- `$trainers` (array) - Array of trainer data

**Returns**: `void` - Outputs HTML directly

### HVAC_MapGeo_Integration

**File**: `includes/find-trainer/class-hvac-mapgeo-integration.php`  
**Purpose**: MapGeo plugin integration for interactive maps

#### Class Methods

##### `get_instance()`
Returns singleton instance.

```php
$integration = HVAC_MapGeo_Integration::get_instance();
```

##### `modify_map_layout($meta, $map_id = null)`
Modifies MapGeo map layout to add trainer profile data.

```php
add_filter('igm_add_meta', [$integration, 'modify_map_layout'], 10, 2);
```

**Parameters**:
- `$meta` (array) - MapGeo metadata
- `$map_id` (string) - Map ID

**Returns**: `array` - Modified metadata

##### `ajax_get_trainer_profile()`
AJAX handler for retrieving complete trainer profile data.

```php
add_action('wp_ajax_hvac_get_trainer_profile', [$integration, 'ajax_get_trainer_profile']);
add_action('wp_ajax_nopriv_hvac_get_trainer_profile', [$integration, 'ajax_get_trainer_profile']);
```

**Expected POST Data**:
- `profile_id` (int) - Trainer profile ID
- `nonce` (string) - Security nonce

**Response Format**:
```json
{
    "success": true,
    "data": {
        "profile_id": 5840,
        "user_id": "31",
        "name": "John Smith",
        "city": "Chicago",
        "state": "Illinois",
        "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": []
    }
}
```

##### `ajax_get_trainer_certification()`
AJAX handler for getting trainer certification information.

```php
add_action('wp_ajax_hvac_get_trainer_certification', [$integration, 'ajax_get_trainer_certification']);
```

**Expected POST Data**:
- `profile_id` (int) - Trainer profile ID
- `nonce` (string) - Security nonce

**Response Format**:
```json
{
    "success": true,
    "data": {
        "certification_type": "Certified measureQuick Trainer",
        "certification_color": "#5077bb"
    }
}
```

## AJAX Endpoints

### Trainer Profile Management

#### `hvac_save_trainer_profile`
Saves trainer profile changes.

**URL**: `wp-admin/admin-ajax.php`  
**Method**: POST  
**Auth**: Required (logged in user)

**Parameters**:
```php
[
    'action' => 'hvac_save_trainer_profile',
    'profile_id' => 5840,
    'nonce' => 'security_nonce',
    'trainer_first_name' => 'John',
    'trainer_last_name' => 'Smith',
    'trainer_city' => 'Chicago',
    // ... other profile fields
]
```

**Response**:
```json
{
    "success": true,
    "data": {
        "message": "Profile saved successfully",
        "profile_id": 5840
    }
}
```

#### `hvac_auto_save_profile`
Auto-saves profile during editing.

**Parameters**: Same as `hvac_save_trainer_profile`

**Response**: Same format with auto-save confirmation

### Find A Trainer Directory

#### `hvac_filter_trainers`
Filters trainers by multiple criteria.

**URL**: `wp-admin/admin-ajax.php`  
**Method**: POST  
**Auth**: Not required (public)

**Parameters**:
```php
[
    'action' => 'hvac_filter_trainers',
    'nonce' => 'security_nonce',
    'filters' => [
        'state' => ['Illinois', 'New York'],
        'business_type' => ['Contractor'],
        'training_format' => ['In-person', 'Virtual']
    ],
    'page' => 1,
    'per_page' => 12
]
```

**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
    }
}
```

#### `hvac_search_trainers`
Searches trainers by text query.

**Parameters**:
```php
[
    'action' => 'hvac_search_trainers',
    'nonce' => 'security_nonce',
    'search' => 'John Smith',
    'page' => 1,
    'per_page' => 12
]
```

**Response**: Same format as filter trainers

#### `hvac_get_filter_options`
Gets available filter options.

**Parameters**:
```php
[
    'action' => 'hvac_get_filter_options',
    'nonce' => 'security_nonce'
]
```

**Response**:
```json
{
    "success": true,
    "data": {
        "states": ["Illinois", "New York", "California"],
        "business_types": ["Contractor", "Distributor", "Consultant"],
        "training_formats": ["In-person", "Virtual", "Hybrid"],
        "training_resources": ["Classroom", "Training Lab", "Online"]
    }
}
```

### Contact Forms

#### `hvac_submit_contact_form`
Submits contact form to trainer.

**Parameters**:
```php
[
    'action' => 'hvac_submit_contact_form',
    'nonce' => 'security_nonce',
    'trainer_id' => 5840,
    'contact_name' => 'Jane Doe',
    'contact_email' => 'jane@example.com',
    'contact_phone' => '555-1234',
    'message' => 'I would like to inquire about training...'
]
```

**Response**:
```json
{
    "success": true,
    "data": {
        "message": "Your message has been sent successfully"
    }
}
```

## JavaScript APIs

### HVAC_FindTrainer Object

**File**: `assets/js/find-trainer.js`  
**Purpose**: Client-side Find A Trainer functionality

#### Configuration

```javascript
var HVAC_FindTrainer = {
    config: {
        ajax_url: hvac_find_trainer.ajax_url,
        nonce: hvac_find_trainer.nonce,
        filters: {},
        current_page: 1,
        per_page: 12
    }
};
```

#### Methods

##### `init(options)`
Initializes the Find A Trainer system.

```javascript
HVAC_FindTrainer.init({
    ajax_url: '/wp-admin/admin-ajax.php',
    nonce: 'security_nonce',
    filters: {
        state: [],
        business_type: [],
        training_format: []
    }
});
```

**Parameters**:
- `options` (object) - Configuration options

##### `performSearch(query)`
Performs text search for trainers.

```javascript
HVAC_FindTrainer.performSearch('John Smith');
```

**Parameters**:
- `query` (string) - Search query

##### `applyFilters()`
Applies current filter settings.

```javascript
HVAC_FindTrainer.config.filters.state = ['Illinois'];
HVAC_FindTrainer.applyFilters();
```

##### `updateResults(response)`
Updates the display with new results.

```javascript
HVAC_FindTrainer.updateResults({
    success: true,
    data: {
        html: '<div>...</div>',
        pagination: '<div>...</div>',
        count: 25
    }
});
```

**Parameters**:
- `response` (object) - AJAX response object

##### `showTrainerProfile(profileId)`
Shows trainer profile modal.

```javascript
HVAC_FindTrainer.showTrainerProfile(5840);
```

**Parameters**:
- `profileId` (int) - Trainer profile ID

### MapGeo Integration JavaScript

**File**: Embedded in `class-hvac-mapgeo-integration.php`  
**Purpose**: MapGeo map interaction handling

#### Global Functions

##### `window.hvac_show_trainer_modal(markerData)`
Custom MapGeo action handler for trainer markers.

```javascript
window.hvac_show_trainer_modal({
    hvac_profile_id: 5840,
    id: 'trainer_5840',
    title: 'John Smith'
});
```

**Parameters**:
- `markerData` (object) - Marker data from MapGeo

#### Global Variables

##### `window.hvacTrainerDataCache`
Cache object for trainer profile data.

```javascript
// Cache structure
window.hvacTrainerDataCache = {
    '5840': {
        profile_id: 5840,
        name: 'John Smith',
        certification_type: 'Certified measureQuick Trainer'
        // ... other profile data
    }
};
```

##### `window.hvacPendingRequests`
Tracking object for pending AJAX requests.

```javascript
// Pending requests structure
window.hvacPendingRequests = {
    '5840': true  // Profile ID 5840 has pending request
};
```

##### `window.lastMapGeoTrainerData`
Stores the most recent trainer data logged by MapGeo.

```javascript
window.lastMapGeoTrainerData = {
    id: 'trainer_5840',
    title: 'John Smith',
    latitude: 41.8781,
    longitude: -87.6298
};
```

## Database Schema

### Custom Post Type: trainer_profile

#### wp_posts Table Fields
```sql
-- Core post fields for trainer_profile
CREATE TABLE wp_posts (
    ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
    post_title tinytext NOT NULL,           -- Trainer display name
    post_content longtext NOT NULL,         -- Profile description
    post_status varchar(20) NOT NULL,       -- 'publish', 'draft', 'pending'
    post_type varchar(20) NOT NULL,         -- 'trainer_profile'
    post_date datetime NOT NULL,
    post_modified datetime NOT NULL,
    PRIMARY KEY (ID),
    KEY type_status_date (post_type, post_status, post_date, ID)
);
```

#### wp_postmeta Table Fields
```sql
-- Profile metadata structure
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES
-- Personal Information
(5840, 'trainer_first_name', 'John'),
(5840, 'trainer_last_name', 'Smith'),
(5840, 'trainer_display_name', 'John Smith'),
(5840, 'trainer_city', 'Chicago'),
(5840, 'trainer_state', 'Illinois'),
(5840, 'trainer_country', 'USA'),
(5840, 'profile_image_url', 'https://...'),
(5840, 'linkedin_profile_url', 'https://linkedin.com/...'),

-- Certification Information
(5840, 'certification_type', 'Certified measureQuick Trainer'),
(5840, 'certification_status', 'Active'),
(5840, 'certification_color', '#5077bb'),
(5840, 'date_certified', '2024-01-15'),
(5840, 'personal_accreditation', 'Additional certifications'),

-- System Fields
(5840, 'user_id', '31'),
(5840, 'is_public_profile', '1'),
(5840, '_last_geocode_attempt', '1691234567'),
(5840, 'geocoded_lat', '41.8781136'),
(5840, 'geocoded_lng', '-87.6297982'),

-- Business Information
(5840, 'annual_revenue_target', '100000'),
(5840, 'application_details', 'Registration details...');
```

#### Taxonomy Tables

##### Business Type Taxonomy
```sql
-- wp_terms entries for business_type taxonomy
INSERT INTO wp_terms (term_id, name, slug) VALUES
(1, 'Manufacturer', 'manufacturer'),
(2, 'Distributor', 'distributor'),
(3, 'Contractor', 'contractor'),
(4, 'Consultant', 'consultant'),
(5, 'Educator', 'educator'),
(6, 'Government', 'government'),
(7, 'Other', 'other');

-- wp_term_taxonomy entries
INSERT INTO wp_term_taxonomy (term_taxonomy_id, term_id, taxonomy, parent, count) VALUES
(1, 1, 'business_type', 0, 5),
(2, 2, 'business_type', 0, 8),
(3, 3, 'business_type', 0, 12);

-- wp_term_relationships entries (linking posts to terms)
INSERT INTO wp_term_relationships (object_id, term_taxonomy_id, term_order) VALUES
(5840, 3, 0);  -- Profile 5840 is linked to Contractor business type
```

### Database Indexes

#### Recommended Indexes for Performance
```sql
-- Optimize meta queries
CREATE INDEX idx_postmeta_profile_queries 
ON wp_postmeta (meta_key, meta_value(50), post_id);

-- Optimize trainer profile queries
CREATE INDEX idx_posts_trainer_profile 
ON wp_posts (post_type, post_status, post_date);

-- Optimize geocoded trainer queries
CREATE INDEX idx_geocoded_trainers 
ON wp_postmeta (meta_key, post_id) 
WHERE meta_key IN ('geocoded_lat', 'geocoded_lng', 'is_public_profile');
```

### Common Database Queries

#### Get All Public Trainers
```sql
SELECT p.ID, p.post_title,
       lat.meta_value as latitude,
       lng.meta_value as longitude,
       cert.meta_value as certification_type
FROM wp_posts p
LEFT JOIN wp_postmeta pub ON p.ID = pub.post_id AND pub.meta_key = 'is_public_profile'
LEFT JOIN wp_postmeta lat ON p.ID = lat.post_id AND lat.meta_key = 'geocoded_lat'  
LEFT JOIN wp_postmeta lng ON p.ID = lng.post_id AND lng.meta_key = 'geocoded_lng'
LEFT JOIN wp_postmeta cert ON p.ID = cert.post_id AND cert.meta_key = 'certification_type'
WHERE p.post_type = 'trainer_profile'
AND p.post_status = 'publish'
AND pub.meta_value = '1'
AND lat.meta_value IS NOT NULL
AND lng.meta_value IS NOT NULL;
```

#### Get Trainers by State
```sql
SELECT p.ID, p.post_title, state.meta_value as state
FROM wp_posts p
INNER JOIN wp_postmeta state ON p.ID = state.post_id AND state.meta_key = 'trainer_state'
INNER JOIN wp_postmeta pub ON p.ID = pub.post_id AND pub.meta_key = 'is_public_profile'
WHERE p.post_type = 'trainer_profile'
AND p.post_status = 'publish'
AND pub.meta_value = '1'
AND state.meta_value = 'Illinois'
ORDER BY p.post_title;
```

## Hooks & Filters

### Action Hooks

#### `hvac_trainer_profile_created`
Fired when a new trainer profile is created.

```php
add_action('hvac_trainer_profile_created', function($profile_id, $profile_data) {
    // Custom logic after profile creation
    error_log("New trainer profile created: " . $profile_id);
}, 10, 2);
```

**Parameters**:
- `$profile_id` (int) - Created profile ID
- `$profile_data` (array) - Profile data used for creation

#### `hvac_trainer_profile_updated`
Fired when a trainer profile is updated.

```php
add_action('hvac_trainer_profile_updated', function($profile_id, $old_data, $new_data) {
    // Custom logic after profile update
    if ($old_data['trainer_city'] !== $new_data['trainer_city']) {
        // Location changed - trigger geocoding
        do_action('hvac_trigger_geocoding', $profile_id);
    }
}, 10, 3);
```

**Parameters**:
- `$profile_id` (int) - Updated profile ID
- `$old_data` (array) - Previous profile data
- `$new_data` (array) - New profile data

#### `hvac_trainer_profile_geocoded`
Fired when a trainer profile is successfully geocoded.

```php
add_action('hvac_trainer_profile_geocoded', function($profile_id, $lat, $lng) {
    // Custom logic after geocoding
    error_log("Profile {$profile_id} geocoded to: {$lat}, {$lng}");
}, 10, 3);
```

**Parameters**:
- `$profile_id` (int) - Profile ID
- `$lat` (float) - Latitude
- `$lng` (float) - Longitude

### Filter Hooks

#### `hvac_trainer_profile_data`
Filters profile data before saving.

```php
add_filter('hvac_trainer_profile_data', function($data, $profile_id) {
    // Modify profile data before saving
    if (empty($data['trainer_display_name'])) {
        $data['trainer_display_name'] = $data['trainer_first_name'] . ' ' . $data['trainer_last_name'];
    }
    return $data;
}, 10, 2);
```

**Parameters**:
- `$data` (array) - Profile data
- `$profile_id` (int) - Profile ID (0 for new profiles)

**Returns**: `array` - Modified profile data

#### `hvac_trainer_query_args`
Filters WP_Query arguments for trainer queries.

```php
add_filter('hvac_trainer_query_args', function($args, $context) {
    // Modify query arguments
    if ($context === 'find_trainer_page') {
        $args['posts_per_page'] = 20; // Show more results
    }
    return $args;
}, 10, 2);
```

**Parameters**:
- `$args` (array) - WP_Query arguments
- `$context` (string) - Query context ('find_trainer_page', 'admin_list', etc.)

**Returns**: `array` - Modified query arguments

#### `hvac_trainer_card_data`
Filters trainer card display data.

```php
add_filter('hvac_trainer_card_data', function($card_data, $profile_id) {
    // Add custom fields to card display
    $card_data['custom_field'] = get_post_meta($profile_id, 'custom_field', true);
    return $card_data;
}, 10, 2);
```

**Parameters**:
- `$card_data` (array) - Card display data
- `$profile_id` (int) - Profile ID

**Returns**: `array` - Modified card data

#### `hvac_mapgeo_marker_data`
Filters MapGeo marker data for trainers.

```php
add_filter('hvac_mapgeo_marker_data', function($marker_data, $profile_id) {
    // Customize marker appearance
    $cert_type = get_post_meta($profile_id, 'certification_type', true);
    if ($cert_type === 'Certified measureQuick Champion') {
        $marker_data['icon'] = 'champion_icon';
        $marker_data['fill'] = '#f19a42';
    }
    return $marker_data;
}, 10, 2);
```

**Parameters**:
- `$marker_data` (array) - Marker data
- `$profile_id` (int) - Profile ID

**Returns**: `array` - Modified marker data

## Constants & Configuration

### Plugin Constants

```php
// Plugin version
define('HVAC_PLUGIN_VERSION', '1.0.0');

// Plugin paths
define('HVAC_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('HVAC_PLUGIN_URL', plugin_dir_url(__FILE__));

// MapGeo configuration
define('HVAC_MAPGEO_MAP_ID', '5872');

// Performance settings
define('HVAC_TRAINER_CACHE_TIMEOUT', HOUR_IN_SECONDS);
define('HVAC_TRAINER_GEOCODING_TIMEOUT', 30); // seconds

// Debug mode
define('HVAC_DEBUG', false);
```

### Configuration Options

#### WordPress Options
```php
// Google Maps API key for geocoding
update_option('hvac_google_maps_api_key', 'your_api_key_here');

// Default trainer profile settings
update_option('hvac_trainer_default_settings', [
    'auto_geocode' => true,
    'public_by_default' => false,
    'require_approval' => true
]);

// Find A Trainer page settings
update_option('hvac_find_trainer_settings', [
    'results_per_page' => 12,
    'enable_map' => true,
    'enable_contact_forms' => true,
    'cache_timeout' => 3600
]);
```

## Error Codes

### AJAX Error Codes

| Code | Constant | Description |
|------|----------|-------------|
| 1001 | `HVAC_ERROR_INVALID_NONCE` | Nonce verification failed |
| 1002 | `HVAC_ERROR_INSUFFICIENT_PERMISSIONS` | User lacks required permissions |
| 1003 | `HVAC_ERROR_PROFILE_NOT_FOUND` | Trainer profile not found |
| 1004 | `HVAC_ERROR_INVALID_DATA` | Invalid or missing data |
| 1005 | `HVAC_ERROR_SAVE_FAILED` | Profile save operation failed |
| 1006 | `HVAC_ERROR_GEOCODING_FAILED` | Geocoding service error |
| 1007 | `HVAC_ERROR_EMAIL_FAILED` | Email delivery failed |

### Error Handling Example

```php
// In AJAX handler
public function ajax_save_trainer_profile() {
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'], 'hvac_trainer_profile')) {
        wp_send_json_error([
            'code' => 1001,
            'message' => 'Security verification failed'
        ]);
        return;
    }
    
    // Check permissions
    if (!current_user_can('edit_hvac_profile')) {
        wp_send_json_error([
            'code' => 1002,
            'message' => 'Insufficient permissions'
        ]);
        return;
    }
    
    // Validate profile ID
    $profile_id = intval($_POST['profile_id']);
    if (!$profile_id || get_post_type($profile_id) !== 'trainer_profile') {
        wp_send_json_error([
            'code' => 1003,
            'message' => 'Trainer profile not found'
        ]);
        return;
    }
    
    // Process save operation
    $result = $this->save_profile($profile_id, $_POST);
    
    if (is_wp_error($result)) {
        wp_send_json_error([
            'code' => 1005,
            'message' => $result->get_error_message()
        ]);
        return;
    }
    
    wp_send_json_success([
        'message' => 'Profile saved successfully',
        'profile_id' => $profile_id
    ]);
}
```

### JavaScript Error Handling

```javascript
// Client-side error handling
function handleAjaxError(response) {
    if (!response.success && response.data.code) {
        switch (response.data.code) {
            case 1001:
                // Nonce error - refresh page
                location.reload();
                break;
            case 1002:
                // Permission error
                alert('You do not have permission to perform this action.');
                break;
            case 1003:
                // Profile not found
                alert('Trainer profile not found.');
                break;
            default:
                // Generic error
                alert('An error occurred: ' + response.data.message);
        }
    }
}

// Usage in AJAX calls
jQuery.ajax({
    url: hvac_trainer.ajax_url,
    method: 'POST',
    data: requestData,
    success: function(response) {
        if (response.success) {
            // Handle success
        } else {
            handleAjaxError(response);
        }
    },
    error: function(jqXHR, textStatus, errorThrown) {
        console.error('AJAX Error:', textStatus, errorThrown);
        alert('Network error occurred. Please try again.');
    }
});
```

This API reference provides comprehensive technical documentation for developers working with the HVAC Trainer system. For additional examples and use cases, refer to the main system documentation.