# HVAC Plugin Development Guide

## Table of Contents
- [Development Setup](#development-setup)
- [Coding Standards](#coding-standards)
- [Architecture Principles](#architecture-principles)
- [Development Workflow](#development-workflow)
- [Testing Guidelines](#testing-guidelines)
- [Deployment Process](#deployment-process)
- [Security Best Practices](#security-best-practices)
- [Performance Optimization](#performance-optimization)

## Development Setup

### Prerequisites
- PHP 7.4+ (8.0+ recommended)
- Node.js 16+ and npm
- Composer
- WP-CLI
- Git

### Local Environment Setup

1. **Clone Repository**
```bash
git clone <repository-url>
cd upskill-event-manager
```

2. **Install Dependencies**
```bash
# PHP dependencies
composer install

# Node dependencies
npm install

# Create .env file
cp .env.example .env
# Edit .env with your environment details
```

3. **Configure WordPress**
- Install WordPress locally
- Create database
- Configure wp-config.php
- Install The Events Calendar plugin

4. **Activate Plugin**
```bash
wp plugin activate hvac-community-events
```

## Coding Standards

### PHP Standards

1. **Follow WordPress Coding Standards**
```php
// Good
function hvac_get_trainer_events( $trainer_id ) {
    $args = array(
        'post_type'      => 'tribe_events',
        'posts_per_page' => -1,
        'meta_query'     => array(
            array(
                'key'     => '_EventTrainerID',
                'value'   => $trainer_id,
                'compare' => '='
            )
        )
    );
    
    return get_posts( $args );
}

// Bad
function getTrainerEvents($trainerId) {
    $args = [
        'post_type' => 'tribe_events',
        'posts_per_page' => -1,
        'meta_query' => [
            ['key' => '_EventTrainerID', 'value' => $trainerId, 'compare' => '=']
        ]
    ];
    return get_posts($args);
}
```

2. **Namespace Usage**
```php
// Use prefixes instead of PHP namespaces for WordPress compatibility
class HVAC_Event_Manager {
    // Class implementation
}
```

3. **Security First**
```php
// Always escape output
echo esc_html( $trainer_name );
echo esc_url( $profile_url );
echo esc_attr( $css_class );

// Sanitize input
$trainer_id = absint( $_GET['trainer_id'] );
$search = sanitize_text_field( $_POST['search'] );

// Verify nonces
if ( ! wp_verify_nonce( $_POST['hvac_nonce'], 'hvac_action' ) ) {
    wp_die( 'Security check failed' );
}
```

### JavaScript Standards

1. **jQuery Usage**
```javascript
// Always use jQuery in no-conflict mode
jQuery(document).ready(function($) {
    // $ is now safe to use
    $('.hvac-button').on('click', function(e) {
        e.preventDefault();
        // Handle click
    });
});
```

2. **AJAX Requests**
```javascript
jQuery.ajax({
    url: hvac_ajax.ajax_url,
    type: 'POST',
    data: {
        action: 'hvac_update_profile',
        nonce: hvac_ajax.nonce,
        data: formData
    },
    success: function(response) {
        if (response.success) {
            // Handle success
        } else {
            // Handle error
            console.error(response.data.message);
        }
    }
});
```

### CSS Standards

1. **BEM Methodology**
```css
/* Block */
.hvac-trainer-card {}

/* Element */
.hvac-trainer-card__header {}
.hvac-trainer-card__content {}

/* Modifier */
.hvac-trainer-card--featured {}
```

2. **Specificity Rules**
```css
/* Avoid overly specific selectors */
/* Bad */
body.logged-in .hvac-wrapper div.container .hvac-trainer-card {}

/* Good */
.hvac-trainer-card {}

/* When specificity is needed for theme overrides */
.hvac-astra-integrated .hvac-trainer-card {}
```

## Architecture Principles

### 1. Single Responsibility Principle
Each class should have one primary responsibility:
```php
// Good - Focused classes
class HVAC_Certificate_Generator {}  // Only handles PDF generation
class HVAC_Event_Manager {}         // Only manages events
class HVAC_Email_Sender {}          // Only sends emails

// Bad - Kitchen sink class
class HVAC_Everything {}  // Does certificates, events, emails, etc.
```

### 2. Dependency Injection
```php
class HVAC_Certificate_Service {
    private $generator;
    private $emailer;
    
    public function __construct( $generator, $emailer ) {
        $this->generator = $generator;
        $this->emailer = $emailer;
    }
}
```

### 3. Hook-Driven Architecture
```php
// Use WordPress hooks for extensibility
do_action( 'hvac_before_event_save', $event_data );
$event_data = apply_filters( 'hvac_event_data', $event_data );
do_action( 'hvac_after_event_save', $event_id );
```

### 4. Singleton Pattern (where appropriate)
```php
class HVAC_Plugin {
    private static $instance = null;
    
    public static function instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    private function __construct() {
        // Initialize
    }
}
```

## Development Workflow

### 1. Feature Development

```bash
# Create feature branch
git checkout -b feature/new-trainer-dashboard

# Make changes
# Test thoroughly
# Commit with meaningful messages
git add .
git commit -m "feat: Add advanced filtering to trainer dashboard

- Add date range picker
- Add event status filter
- Add export functionality"

# Push and create PR
git push origin feature/new-trainer-dashboard
```

### 2. Git Commit Messages
Follow conventional commits:
- `feat:` New feature
- `fix:` Bug fix
- `docs:` Documentation
- `style:` Formatting changes
- `refactor:` Code restructuring
- `test:` Test additions/changes
- `chore:` Maintenance tasks

### 3. Code Review Checklist
- [ ] Follows WordPress coding standards
- [ ] Security measures implemented (escaping, sanitization)
- [ ] Performance impact considered
- [ ] Backward compatibility maintained
- [ ] Documentation updated
- [ ] Tests written/updated

## Testing Guidelines

### 1. Unit Testing
```php
class Test_HVAC_Event_Manager extends WP_UnitTestCase {
    public function test_create_event() {
        $event_data = array(
            'post_title' => 'Test Event',
            'EventStartDate' => '2025-08-15 09:00:00'
        );
        
        $event_id = HVAC_Event_Manager::create_event( $event_data );
        
        $this->assertIsInt( $event_id );
        $this->assertGreaterThan( 0, $event_id );
    }
}
```

### 2. E2E Testing with Playwright
```javascript
test('Trainer can create event', async ({ page }) => {
    // Login
    await loginAsTrainer(page);
    
    // Navigate to event creation
    await page.goto('/trainer/event/manage/');
    
    // Fill form
    await page.fill('#event-title', 'HVAC Training Session');
    await page.selectOption('#event-venue', 'Main Campus');
    
    // Submit
    await page.click('button[type="submit"]');
    
    // Verify
    await expect(page).toHaveURL(/event-created/);
});
```

### 3. Manual Testing Checklist
- [ ] Test on staging before production
- [ ] Test with different user roles
- [ ] Test on mobile devices
- [ ] Test with different themes (especially Astra)
- [ ] Test with caching enabled

## Deployment Process

### 1. Pre-Deployment Checks
```bash
# Run validation
bin/pre-deployment-check.sh

# Run tests
npm test
phpunit
```

### 2. Staging Deployment
```bash
# Deploy to staging
scripts/deploy.sh staging

# Verify deployment
scripts/verify-plugin-fixes.sh
```

### 3. Production Deployment
```bash
# Only when explicitly requested
scripts/deploy.sh production
# Requires double confirmation
```

### 4. Post-Deployment
- Monitor error logs
- Check critical functionality
- Be ready to rollback if needed

## Security Best Practices

### 1. Data Validation
```php
// Input validation
if ( ! is_email( $email ) ) {
    wp_die( 'Invalid email address' );
}

// Type checking
$event_id = absint( $_POST['event_id'] );
if ( ! $event_id ) {
    wp_die( 'Invalid event ID' );
}
```

### 2. SQL Queries
```php
// Always use prepared statements
global $wpdb;
$results = $wpdb->get_results( 
    $wpdb->prepare(
        "SELECT * FROM {$wpdb->posts} WHERE post_author = %d AND post_type = %s",
        $user_id,
        'tribe_events'
    )
);
```

### 3. File Uploads
```php
// Validate file types
$allowed_types = array( 'jpg', 'jpeg', 'png', 'pdf' );
$file_type = wp_check_filetype( $file['name'] );

if ( ! in_array( $file_type['ext'], $allowed_types ) ) {
    wp_die( 'Invalid file type' );
}
```

### 4. Capability Checks
```php
// Always verify user permissions
if ( ! current_user_can( 'manage_own_events' ) ) {
    wp_die( 'Insufficient permissions' );
}
```

## Performance Optimization

### 1. Database Queries
```php
// Cache expensive queries
$cache_key = 'hvac_trainer_events_' . $trainer_id;
$events = wp_cache_get( $cache_key );

if ( false === $events ) {
    $events = get_posts( $args );
    wp_cache_set( $cache_key, $events, '', 3600 ); // 1 hour
}
```

### 2. Asset Loading
```php
// Load assets only where needed
public function enqueue_scripts() {
    if ( ! $this->is_plugin_page() ) {
        return;
    }
    
    wp_enqueue_script( 'hvac-dashboard' );
}
```

### 3. AJAX Optimization
```javascript
// Debounce search requests
let searchTimeout;
$('#search').on('keyup', function() {
    clearTimeout(searchTimeout);
    searchTimeout = setTimeout(function() {
        performSearch();
    }, 300);
});
```

### 4. Image Optimization
- Use appropriate image sizes
- Lazy load images
- Compress before upload
- Use WebP format when possible

## Common Patterns

### 1. AJAX Handler Pattern
```php
class HVAC_Ajax_Handler {
    public function __construct() {
        add_action( 'wp_ajax_hvac_action', array( $this, 'handle_request' ) );
    }
    
    public function handle_request() {
        // Verify nonce
        if ( ! wp_verify_nonce( $_POST['nonce'], 'hvac_nonce' ) ) {
            wp_send_json_error( 'Invalid nonce' );
        }
        
        // Check capabilities
        if ( ! current_user_can( 'required_capability' ) ) {
            wp_send_json_error( 'Insufficient permissions' );
        }
        
        // Process request
        $result = $this->process_data( $_POST['data'] );
        
        // Return response
        if ( $result ) {
            wp_send_json_success( $result );
        } else {
            wp_send_json_error( 'Processing failed' );
        }
    }
}
```

### 2. Settings Page Pattern
```php
class HVAC_Settings {
    public function __construct() {
        add_action( 'admin_menu', array( $this, 'add_menu' ) );
        add_action( 'admin_init', array( $this, 'register_settings' ) );
    }
    
    public function add_menu() {
        add_options_page(
            'HVAC Settings',
            'HVAC Events',
            'manage_options',
            'hvac-settings',
            array( $this, 'render_page' )
        );
    }
    
    public function register_settings() {
        register_setting( 'hvac_settings', 'hvac_options' );
    }
}
```

## Access Control Patterns

### Role-Based Field Access

The plugin implements sophisticated role-based access control for sensitive data:

```php
// Check permissions for certification field editing
$can_edit_certifications = current_user_can('administrator') || current_user_can('hvac_master_trainer');

if ( $can_edit_certifications ) {
    // Allow editing certification fields
    update_user_meta($user_id, 'certification_status', sanitize_text_field($_POST['certification_status']));
} else {
    // Show read-only display for regular trainers
    echo '<div class="hvac-read-only-field">' . esc_html($certification_status) . '</div>';
}
```

### Field-Level Access Control Implementation

```php
// Different access levels for different user types
if ( current_user_can('hvac_trainer') && ! current_user_can('hvac_master_trainer') ) {
    // Trainer: read-only access to certification fields
    echo '<input type="hidden" name="certification_type" value="' . esc_attr($certification_type) . '" />';
    echo '<div class="hvac-read-only-field">' . esc_html($certification_type) . '</div>';
} else if ( current_user_can('administrator') || current_user_can('hvac_master_trainer') ) {
    // Admin/Master Trainer: full edit access
    echo '<select name="certification_type">';
    // ... render editable dropdown
    echo '</select>';
}
```

### Access Control Best Practices

1. **Always validate permissions server-side** - Never rely on frontend-only restrictions
2. **Use capability checks** - Check specific capabilities rather than user roles when possible
3. **Implement graceful degradation** - Show read-only versions rather than hiding fields entirely
4. **Visual indicators** - Clearly indicate when fields are read-only
5. **Consistent patterns** - Use the same access control patterns throughout the plugin

## CSV Import System

### Enhanced CSV Import Architecture

The plugin includes a comprehensive CSV import system designed to process trainer profile data with full taxonomy integration.

#### File Structure
```
includes/
├── enhanced-csv-import-from-file.php    # Main CSV import class
├── class-hvac-geocoding-ajax.php        # AJAX handlers (updated)
└── taxonomy-migration.php               # Taxonomy migration utilities
```

#### CSV Import Class

```php
class HVAC_Enhanced_CSV_Import {
    /**
     * Execute comprehensive CSV import
     * @return array Import results and statistics
     */
    public function execute_import()
    
    /**
     * Process individual CSV row
     * @param array $headers CSV headers
     * @param array $row CSV row data
     * @param int $row_number Row number for error reporting
     */
    private function process_row($headers, $row, $row_number)
    
    /**
     * Create or update trainer profile
     * @param int $user_id WordPress user ID
     * @param array $data CSV row data
     * @return int Profile post ID
     */
    private function create_or_update_profile($user_id, $data)
    
    /**
     * Assign taxonomy terms to profile
     * @param int $profile_id Profile post ID
     * @param array $data CSV row data
     */
    private function assign_taxonomies($profile_id, $data)
}
```

#### Supported CSV Fields

The import system processes 19 CSV fields:

**Contact Information:**
- `Name`, `Last Name`, `Email`, `Phone Number`

**Professional Data:**
- `Company Name`, `Role`, `Company Website`

**Location Data:**
- `Country`, `State`, `City`

**Certification Information:**
- `Date Certified`, `Certification Type`, `Certification Status`

**Taxonomy Fields:**
- `Business Type` → `business_type` taxonomy
- `Training Audience` → `training_audience` taxonomy

**System Fields:**
- `User ID`, `Application Details`, `Create Venue`, `Create Organizer`

#### Multi-Value Taxonomy Handling

The system handles comma-separated taxonomy values:

```php
// Input: "Educator,Consultant" 
// Output: Two taxonomy terms assigned to profile

private function parse_comma_separated($value) {
    $items = explode(',', $value);
    return array_map('trim', $items);
}

private function assign_taxonomy_terms($profile_id, $taxonomy, $terms) {
    foreach ($terms as $term_name) {
        // Get or create term
        $term = get_term_by('name', $term_name, $taxonomy);
        if (!$term) {
            $term_data = wp_insert_term($term_name, $taxonomy);
        }
    }
    wp_set_object_terms($profile_id, $term_ids, $taxonomy);
}
```

#### AJAX Integration

The CSV import integrates with the existing AJAX system:

```javascript
// Execute enhanced CSV import
jQuery.post(hvac_ajax.ajax_url, {
    action: 'hvac_run_enhanced_import',
    nonce: hvac_ajax.nonce
}, function(response) {
    if (response.success) {
        console.log('Import completed:', response.data);
        // Display results to user
    }
});
```

#### Error Handling and Logging

```php
try {
    $results = $this->process_row($headers, $row, $row_number);
} catch (Exception $e) {
    $this->results['errors']++;
    $this->results['details'][] = "Row $row_number error: " . $e->getMessage();
    error_log("CSV Import Row $row_number Error: " . $e->getMessage());
}
```

#### Testing the CSV Import

```bash
# Test import locally
php test-enhanced-csv-import.php

# Test on staging
ssh user@staging-server "cd /path/to/plugin && php test-csv-import.php"
```

### Development Best Practices for CSV Import

1. **Always validate CSV structure** before processing
2. **Handle missing/malformed data gracefully**
3. **Use transactions for large imports** when possible
4. **Provide detailed progress feedback** to users
5. **Log all import activities** for debugging
6. **Test with various CSV formats and edge cases**

## Trainer Profile Sharing Implementation

### Overview

The trainer profile sharing system allows trainers to generate shareable URLs and QR codes for their profiles, enabling professional marketing and networking opportunities.

### Core Components

#### 1. HVAC_QR_Generator Class

The main class handling QR code generation and profile sharing functionality:

```php
class HVAC_QR_Generator {
    private static $instance = null;
    
    public static function instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    private function __construct() {
        $this->init_hooks();
    }
    
    private function init_hooks() {
        // AJAX handlers
        add_action('wp_ajax_hvac_get_profile_share_data', [$this, 'ajax_get_profile_share_data']);
        add_action('wp_ajax_nopriv_hvac_get_profile_share_data', [$this, 'ajax_get_profile_share_data']);
        
        // URL rewrite rules
        add_action('init', [$this, 'add_profile_rewrite_rules']);
        add_filter('query_vars', [$this, 'add_profile_query_vars']);
    }
}
```

#### 2. QR Code Generation

The system uses QR Server API for generating QR codes (switched from deprecated Google Charts API):

```php
public function generate_qr_url($data, $size = 200, $error_correction = 'M') {
    $encoded_data = urlencode($data);
    
    $qr_url = sprintf(
        'https://api.qrserver.com/v1/create-qr-code/?size=%dx%d&data=%s&ecc=%s',
        $size,
        $size,
        $encoded_data,
        strtoupper($error_correction)
    );
    
    return $qr_url;
}
```

**Key Implementation Notes:**
- **API Migration**: Switched from Google Charts API (deprecated) to QR Server API
- **URL Encoding**: Proper URL encoding prevents malformed QR codes
- **Error Correction**: Medium level (M) provides good balance of data capacity and error recovery
- **Size Flexibility**: Configurable size for different use cases

#### 3. Share URL Structure

Profile sharing URLs follow a hierarchical pattern with proper WordPress rewrite rules:

```php
public function add_profile_rewrite_rules() {
    add_rewrite_rule(
        '^find-a-trainer/profile/([0-9]+)/?$',
        'index.php?pagename=find-a-trainer&trainer_profile_id=$matches[1]',
        'top'
    );
}

public function get_trainer_profile_share_url($profile_id) {
    $find_trainer_page = get_page_by_path('find-a-trainer');
    if (!$find_trainer_page) {
        return false;
    }
    
    $base_url = get_permalink($find_trainer_page->ID);
    
    // CRITICAL: Include trailing slash for WordPress rewrite rules
    $profile_url = trailingslashit($base_url) . 'profile/' . $profile_id . '/';
    
    return $profile_url;
}
```

**Important Implementation Details:**
- **Trailing Slash Required**: WordPress rewrite rules require trailing slash
- **Query Variables**: Custom query var `trainer_profile_id` for profile identification
- **URL Pattern**: `/find-a-trainer/profile/{profile_id}/` structure

#### 4. AJAX Handler Implementation

The AJAX handler follows security best practices with nonce verification:

```php
public function ajax_get_profile_share_data() {
    // Security: Verify nonce
    if (!wp_verify_nonce($_POST['nonce'], 'hvac_profile_sharing')) {
        wp_send_json_error(['message' => 'Security check failed']);
        return;
    }
    
    $profile_id = intval($_POST['profile_id']);
    if (!$profile_id) {
        wp_send_json_error(['message' => 'Invalid profile ID']);
        return;
    }
    
    // Get comprehensive share data
    $share_data = $this->get_trainer_share_data($profile_id);
    
    if (!$share_data) {
        wp_send_json_error(['message' => 'Profile not found or not accessible']);
        return;
    }
    
    wp_send_json_success($share_data);
}
```

#### 5. Frontend JavaScript Implementation

The JavaScript component handles the share modal and user interactions:

```javascript
var ProfileSharing = {
    init: function() {
        this.bindEvents();
    },
    
    bindEvents: function() {
        $(document).on('click', '.hvac-share-profile-btn', this.openShareModal);
        $(document).on('click', '.hvac-copy-url-btn', this.copyShareUrl);
        $(document).on('click', '.hvac-modal-close', this.closeShareModal);
        
        // Escape key support
        $(document).on('keydown', function(e) {
            if (e.keyCode === 27 && $('.hvac-share-modal:visible').length) {
                ProfileSharing.closeShareModal();
            }
        });
    },
    
    loadShareData: function(profileId) {
        $.ajax({
            url: hvac_sharing.ajax_url,
            type: 'POST',
            data: {
                action: 'hvac_get_profile_share_data',
                profile_id: profileId,
                nonce: hvac_sharing.nonce
            },
            success: function(response) {
                if (response.success && response.data) {
                    ProfileSharing.populateShareData(response.data);
                } else {
                    ProfileSharing.showError(response.data ? response.data.message : 'Unknown error occurred');
                }
            },
            error: function(xhr, status, error) {
                ProfileSharing.showError('Network error occurred. Please try again.');
            }
        });
    }
};
```

### Development Guidelines for Profile Sharing

#### 1. Security Considerations

```php
// Always verify nonces in AJAX handlers
if (!wp_verify_nonce($_POST['nonce'], 'hvac_profile_sharing')) {
    wp_send_json_error(['message' => 'Security check failed']);
    return;
}

// Sanitize and validate input
$profile_id = intval($_POST['profile_id']);
if (!$profile_id || $profile_id <= 0) {
    wp_send_json_error(['message' => 'Invalid profile ID']);
    return;
}

// Check profile accessibility
$profile = get_post($profile_id);
if (!$profile || $profile->post_type !== 'trainer_profile') {
    wp_send_json_error(['message' => 'Profile not found']);
    return;
}
```

#### 2. Error Handling Patterns

```php
// Graceful degradation for missing data
$trainer_name = get_post_meta($profile_id, 'trainer_display_name', true) ?: $user->display_name ?: 'Unknown Trainer';

// API fallback handling
$qr_url = $this->generate_qr_url($profile_url, $size);
if (!$qr_url) {
    error_log("QR code generation failed for profile {$profile_id}");
    // Continue without QR code rather than failing completely
}
```

#### 3. Frontend User Experience

```javascript
// Loading states
$cardContainer.html(
    '<div class="hvac-share-card-loading">' +
        '<span class="dashicons dashicons-update spin"></span>' +
        '<p>Loading profile card...</p>' +
    '</div>'
);

// Error states with helpful messaging
ProfileSharing.showError = function(message) {
    $cardContainer.html(
        '<div class="hvac-share-card-loading">' +
            '<span class="dashicons dashicons-warning" style="color: #dc3545;"></span>' +
            '<p style="color: #dc3545;">' + message + '</p>' +
        '</div>'
    );
};

// Success feedback for copy operations
ProfileSharing.showCopySuccess = function($button) {
    var originalText = $button.text();
    $button.addClass('copied').text('Copied!');
    
    setTimeout(function() {
        $button.removeClass('copied').text(originalText);
    }, 2000);
};
```

#### 4. Template Integration

```php
// In page templates, add the share button
<button type="button" class="hvac-button hvac-button-secondary hvac-share-profile-btn" 
        data-profile-id="<?php echo esc_attr($profile->ID); ?>">
    <span class="dashicons dashicons-share"></span> Share Profile
</button>

// Include the modal HTML at the end of the template
<div id="hvac-share-profile-modal" class="hvac-share-modal" style="display: none;">
    <!-- Modal content -->
</div>
```

#### 5. Asset Management

```php
// In HVAC_Scripts_Styles class
public function localize_sharing_data($additional_data = []) {
    wp_localize_script('hvac-profile-sharing', 'hvac_sharing', array_merge([
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('hvac_profile_sharing'),
        'strings' => [
            'copied' => 'Copied!',
            'copy_error' => 'Copy failed'
        ]
    ], $additional_data));
}
```

### Testing Profile Sharing

#### 1. Unit Testing

```php
// Test QR URL generation
public function test_qr_url_generation() {
    $qr_generator = HVAC_QR_Generator::instance();
    $test_url = 'https://example.com/find-a-trainer/profile/123/';
    
    $qr_url = $qr_generator->generate_qr_url($test_url, 200, 'M');
    
    $this->assertStringContains('api.qrserver.com', $qr_url);
    $this->assertStringContains('size=200x200', $qr_url);
    $this->assertStringContains(urlencode($test_url), $qr_url);
}

// Test share URL generation
public function test_share_url_generation() {
    $qr_generator = HVAC_QR_Generator::instance();
    $profile_id = 123;
    
    $share_url = $qr_generator->get_trainer_profile_share_url($profile_id);
    
    $this->assertStringEndsWith('/', $share_url); // Must have trailing slash
    $this->assertStringContains('/profile/' . $profile_id . '/', $share_url);
}
```

#### 2. End-to-End Testing

```javascript
// Playwright test for profile sharing
test('trainer can share profile with QR code', async ({ page }) => {
    await page.goto('/trainer/profile/');
    await page.click('.hvac-share-profile-btn');
    
    // Wait for modal to appear
    await page.waitForSelector('#hvac-share-profile-modal');
    
    // Verify share URL is populated
    const shareUrl = await page.inputValue('#hvac-share-url');
    expect(shareUrl).toContain('/find-a-trainer/profile/');
    
    // Verify QR code image is loaded
    const qrImage = page.locator('.hvac-share-qr img');
    await expect(qrImage).toBeVisible();
    
    // Test copy functionality
    await page.click('.hvac-copy-url-btn');
    await expect(page.locator('.hvac-copy-url-btn')).toHaveClass(/copied/);
});
```

### Deployment Considerations

#### 1. URL Rewrite Rules

After deploying profile sharing functionality:

```bash
# Flush rewrite rules to activate new URL patterns
wp rewrite flush

# Verify rewrite rules are working
wp rewrite list | grep "find-a-trainer"
```

#### 2. QR Code API Dependencies

- **External Dependency**: QR Server API (https://api.qrserver.com)
- **Fallback**: Consider implementing fallback QR generation if API becomes unavailable
- **Caching**: QR URLs are generated dynamically but could be cached for performance

#### 3. Performance Monitoring

```php
// Add timing monitoring for QR generation
$start_time = microtime(true);
$qr_url = $this->generate_qr_url($data, $size);
$generation_time = microtime(true) - $start_time;

if ($generation_time > 2.0) {
    error_log("Slow QR generation: {$generation_time}s for profile {$profile_id}");
}
```

## Resources

- [WordPress Coding Standards](https://developer.wordpress.org/coding-standards/)
- [WordPress Plugin Handbook](https://developer.wordpress.org/plugins/)
- [The Events Calendar Documentation](https://theeventscalendar.com/knowledgebase/)
- [WordPress Taxonomy API](https://developer.wordpress.org/reference/functions/wp_insert_term/)
- [Playwright Documentation](https://playwright.dev/)