<?php
/**
 * Certificate Generator Class
 *
 * Handles the generation of PDF certificates using TCPDF.
 *
 * @package HVAC_Community_Events
 * @subpackage Certificates
 */

// Exit if accessed directly
if (!defined('ABSPATH')) {
    exit;
}

// Include TCPDF library if not already included
if (!class_exists('TCPDF')) {
    $tcpdf_path = HVAC_PLUGIN_DIR . 'vendor/tecnickcom/tcpdf/tcpdf.php';
    if (file_exists($tcpdf_path)) {
        require_once $tcpdf_path;
    } else {
        // Log warning about missing TCPDF dependency
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('HVAC Plugin: TCPDF library not found. Certificate generation will be disabled until Composer dependencies are installed.');
        }
    }
}

/**
 * Certificate Generator class.
 *
 * Handles PDF certificate generation using TCPDF.
 *
 * @since 1.0.0
 */
class HVAC_Certificate_Generator {

    /**
     * The single instance of the class.
     *
     * @var HVAC_Certificate_Generator
     */
    protected static $_instance = null;

    /**
     * Main HVAC_Certificate_Generator Instance.
     *
     * Ensures only one instance of HVAC_Certificate_Generator is loaded or can be loaded.
     *
     * @return HVAC_Certificate_Generator - Main instance.
     */
    public static function instance() {
        if (is_null(self::$_instance)) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    /**
     * Certificate Manager instance.
     *
     * @var HVAC_Certificate_Manager
     */
    protected $certificate_manager;

    /**
     * Constructor.
     */
    public function __construct() {
        require_once HVAC_PLUGIN_DIR . 'includes/certificates/class-certificate-manager.php';
        $this->certificate_manager = HVAC_Certificate_Manager::instance();
    }

    /**
     * Generate a certificate for an attendee.
     *
     * @param int   $event_id     The event ID.
     * @param int   $attendee_id  The attendee ID.
     * @param array $custom_data  Optional custom data to override defaults.
     * @param int   $generated_by The ID of the user who generated the certificate.
     * 
     * @return int|false The certificate ID if successful, false otherwise.
     */
    public function generate_certificate($event_id, $attendee_id, $custom_data = array(), $generated_by = 0) {
        // Check if TCPDF is available
        if (!class_exists('TCPDF')) {
            HVAC_Logger::error("Cannot generate certificate: TCPDF library not found. Please install Composer dependencies.", 'Certificates');
            return false;
        }
        // Check if certificate already exists
        if ($this->certificate_manager->certificate_exists($event_id, $attendee_id)) {
            HVAC_Logger::warning("Certificate already exists for event $event_id and attendee $attendee_id", 'Certificates');
            return false;
        }
        
        // Get attendee data
        $attendee_data = $this->get_attendee_data($attendee_id);
        
        if (empty($attendee_data)) {
            HVAC_Logger::error("Failed to retrieve attendee data for ID: $attendee_id", 'Certificates');
            return false;
        }
        
        // Get event data
        $event_data = $this->get_event_data($event_id);
        
        if (empty($event_data)) {
            HVAC_Logger::error("Failed to retrieve event data for ID: $event_id", 'Certificates');
            return false;
        }
        
        // Merge custom data
        $certificate_data = array_merge($attendee_data, $event_data, $custom_data);
        
        // Create certificate record first
        $user_id = $attendee_data['user_id'] ?? 0;
        $certificate_id = $this->certificate_manager->create_certificate($event_id, $attendee_id, $user_id, '', $generated_by);
        
        if (!$certificate_id) {
            HVAC_Logger::error("Failed to create certificate record for event $event_id and attendee $attendee_id", 'Certificates');
            return false;
        }
        
        // Generate PDF and get file path
        $file_path = $this->generate_pdf($certificate_id, $certificate_data);
        
        if (!$file_path) {
            // Delete the certificate record if PDF generation failed
            $this->certificate_manager->delete_certificate($certificate_id);
            
            HVAC_Logger::error("Failed to generate PDF for certificate ID: $certificate_id", 'Certificates');
            return false;
        }
        
        // Generate PNG version for preview purposes
        $png_path = $this->generate_png($certificate_id, $certificate_data);
        if ($png_path) {
            HVAC_Logger::info("Generated PNG version: $png_path", 'Certificates');
        }
        
        // Update certificate record with file paths
        $this->certificate_manager->update_certificate_file($certificate_id, $file_path, $png_path);
        
        return $certificate_id;
    }

    /**
     * Generate a PDF certificate.
     *
     * @param int   $certificate_id   The certificate ID.
     * @param array $certificate_data The certificate data.
     * 
     * @return string|false The relative file path if successful, false otherwise.
     */
    protected function generate_pdf($certificate_id, $certificate_data) {
        // Check if TCPDF is available
        if (!class_exists('TCPDF')) {
            return false;
        }
        
        // Get certificate and verify it exists
        $certificate = $this->certificate_manager->get_certificate($certificate_id);
        
        if (!$certificate) {
            return false;
        }
        
        // Create a custom TCPDF class extension (for header/footer)
        $pdf = $this->create_certificate_pdf();
        
        // Add a page
        $pdf->AddPage('L', 'LETTER'); // Landscape, Letter size
        
        // Set document metadata
        $event_name = $certificate_data['event_name'] ?? 'HVAC Training';
        $attendee_name = $certificate_data['attendee_name'] ?? 'Attendee';
        
        $pdf->SetCreator('HVAC Community Events');
        $pdf->SetAuthor('Upskill HVAC');
        $pdf->SetTitle("Certificate of Completion - $event_name");
        $pdf->SetSubject("Certificate for $attendee_name");
        $pdf->SetKeywords("HVAC, Certificate, Training, $event_name");
        
        // Render certificate content
        $this->render_certificate_content($pdf, $certificate, $certificate_data);
        
        // Get certificate storage path
        $upload_dir = wp_upload_dir();
        $cert_dir = $upload_dir['basedir'] . '/' . get_option('hvac_certificate_storage_path', 'hvac-certificates');
        
        // Create directory if it doesn't exist
        if (!file_exists($cert_dir)) {
            wp_mkdir_p($cert_dir);
        }
        
        // Define file name and path
        $file_name = sanitize_file_name(
            'certificate-' . $certificate->certificate_number . '-' . 
            sanitize_title($attendee_name) . '.pdf'
        );
        
        $event_dir = $cert_dir . '/' . $certificate->event_id;
        
        // Create event directory if it doesn't exist
        if (!file_exists($event_dir)) {
            wp_mkdir_p($event_dir);
        }
        
        $full_path = $event_dir . '/' . $file_name;
        $relative_path = get_option('hvac_certificate_storage_path', 'hvac-certificates') . 
                        '/' . $certificate->event_id . '/' . $file_name;
        
        // Save the PDF file
        try {
            $pdf->Output($full_path, 'F'); // F means save to file
            
            if (file_exists($full_path)) {
                return $relative_path;
            }
        } catch (Exception $e) {
            HVAC_Logger::error("Failed to save PDF file: " . $e->getMessage(), 'Certificates');
        }
        
        return false;
    }

    /**
     * Generate a PNG version of the certificate for preview purposes.
     *
     * @param int   $certificate_id   The certificate ID.
     * @param array $certificate_data The certificate data.
     * 
     * @return string|false The relative file path if successful, false otherwise.
     */
    protected function generate_png($certificate_id, $certificate_data) {
        // Check if TCPDF is available
        if (!class_exists('TCPDF')) {
            return false;
        }
        
        // Get certificate and verify it exists
        $certificate = $this->certificate_manager->get_certificate($certificate_id);
        
        if (!$certificate) {
            return false;
        }
        
        // Create PDF for conversion to PNG
        $pdf = $this->create_certificate_pdf();
        $pdf->AddPage();
        
        // Render certificate content
        $this->render_certificate_content($pdf, $certificate, $certificate_data);
        
        // Get certificate storage path
        $upload_dir = wp_upload_dir();
        $cert_dir = $upload_dir['basedir'] . '/' . get_option('hvac_certificate_storage_path', 'hvac-certificates');
        
        // Create directory if it doesn't exist
        if (!file_exists($cert_dir)) {
            wp_mkdir_p($cert_dir);
        }
        
        $attendee_name = isset($certificate_data['attendee_name']) ? $certificate_data['attendee_name'] : 'unknown';
        
        // Define file name and path
        $file_name = sanitize_file_name(
            'certificate-' . $certificate->certificate_number . '-' . 
            sanitize_title($attendee_name) . '.png'
        );
        
        $event_dir = $cert_dir . '/' . $certificate->event_id;
        
        // Create event directory if it doesn't exist
        if (!file_exists($event_dir)) {
            wp_mkdir_p($event_dir);
        }
        
        $full_path = $event_dir . '/' . $file_name;
        $relative_path = get_option('hvac_certificate_storage_path', 'hvac-certificates') . 
                        '/' . $certificate->event_id . '/' . $file_name;
        
        // Convert PDF to PNG using TCPDF's image output
        try {
            // Set high DPI for better quality
            $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
            
            // Output as PNG (using TCPDF's built-in PNG output)
            // Note: This requires TCPDF to be compiled with PNG support
            $pdf->Output($full_path, 'F'); // Save PDF first
            
            // Convert PDF to PNG using ImageMagick if available
            if (class_exists('Imagick')) {
                $imagick = new Imagick();
                $imagick->setResolution(300, 300); // High resolution
                $imagick->readImage($full_path); // Read the PDF
                $imagick->setImageFormat('png');
                $imagick->setImageCompressionQuality(90);
                
                // Replace .pdf with .png in the path
                $png_full_path = str_replace('.pdf', '.png', $full_path);
                $png_relative_path = str_replace('.pdf', '.png', $relative_path);
                
                $imagick->writeImage($png_full_path);
                $imagick->clear();
                
                if (file_exists($png_full_path)) {
                    return $png_relative_path;
                }
            } else {
                // Fallback: Log that ImageMagick is not available
                HVAC_Logger::info("ImageMagick not available for PNG conversion. PNG generation skipped.", 'Certificates');
                return false;
            }
            
        } catch (Exception $e) {
            HVAC_Logger::error("Failed to generate PNG file: " . $e->getMessage(), 'Certificates');
        }
        
        return false;
    }

    /**
     * Create a TCPDF instance for certificate generation.
     *
     * @return TCPDF The TCPDF instance.
     */
    protected function create_certificate_pdf() {
        // Check if TCPDF is available
        if (!class_exists('TCPDF')) {
            return false;
        }
        
        // Create new PDF document
        $pdf = new TCPDF('L', 'mm', 'LETTER', true, 'UTF-8', false);
        
        // Set document information
        $pdf->SetTitle('Certificate of Completion');
        $pdf->SetAuthor('Upskill HVAC');
        
        // Set margins
        $pdf->SetMargins(15, 15, 15);
        
        // Remove default header/footer
        $pdf->setPrintHeader(false);
        $pdf->setPrintFooter(false);
        
        // Set auto page breaks
        $pdf->SetAutoPageBreak(false, 0);
        
        // Set default font
        $pdf->SetFont('helvetica', '', 10);
        
        return $pdf;
    }

    /**
     * Render certificate content on PDF.
     *
     * @param TCPDF $pdf              The TCPDF instance.
     * @param object $certificate     The certificate object.
     * @param array  $certificate_data The certificate data.
     */
    protected function render_certificate_content($pdf, $certificate, $certificate_data) {
        // Set background image if available
        $this->add_certificate_background($pdf);
        
        // Add Upskill HVAC logo at the top
        $this->add_upskill_logo($pdf);
        
        // Certificate title
        $pdf->SetFont('helvetica', 'B', 30);
        $pdf->SetTextColor(0, 77, 155); // Blue
        $pdf->SetY(45); // Moved down to accommodate logo
        $pdf->Cell(0, 20, 'CERTIFICATE OF COMPLETION', 0, 1, 'C');
        
        // Description text
        $pdf->SetFont('helvetica', '', 12);
        $pdf->SetTextColor(77, 77, 77); // Dark gray
        $pdf->SetY(70);
        $pdf->Cell(0, 10, 'This certificate is awarded to', 0, 1, 'C');
        
        // Attendee name - prominently displayed
        $attendee_name = $certificate_data['attendee_name'] ?? 'Attendee Name';
        $pdf->SetFont('helvetica', 'B', 26);
        $pdf->SetTextColor(0, 0, 0); // Black
        $pdf->Cell(0, 20, $attendee_name, 0, 1, 'C');
        
        // Course completion text
        $pdf->SetFont('helvetica', '', 12);
        $pdf->SetTextColor(77, 77, 77); // Dark gray
        $pdf->Cell(0, 10, 'for successfully completing', 0, 1, 'C');
        
        // Event name
        $event_name = $certificate_data['event_name'] ?? 'HVAC Training Course';
        $pdf->SetFont('helvetica', 'B', 18);
        $pdf->SetTextColor(0, 77, 155); // Blue
        $pdf->Cell(0, 15, $event_name, 0, 1, 'C');
        
        // Event date
        $event_date = $certificate_data['event_date_formatted'] ?? date('F j, Y');
        $pdf->SetFont('helvetica', '', 12);
        $pdf->SetTextColor(77, 77, 77); // Dark gray
        $pdf->Cell(0, 10, 'on ' . $event_date, 0, 1, 'C');
        
        // Get instructor/trainer name properly
        $instructor_name = $certificate_data['instructor_name'] ?? '';
        if (empty($instructor_name) && !empty($certificate_data['trainer_name'])) {
            $instructor_name = $certificate_data['trainer_name'];
        }
        if (empty($instructor_name)) {
            // Try to get from event organizer
            $instructor_name = $certificate_data['organization_name'] ?? 'Instructor';
        }
        
        // Draw a line for signature
        $pdf->SetDrawColor(0, 77, 155); // Blue
        $pdf->SetLineWidth(0.5);
        $pdf->Line(70, 155, 190, 155);
        
        // Add instructor signature if available
        if (!empty($certificate_data['instructor_signature'])) {
            $signature_path = $certificate_data['instructor_signature'];
            if (file_exists($signature_path)) {
                $pdf->Image($signature_path, 110, 135, 40, 0, '', '', '', false, 300);
            }
        }
        
        // Instructor name and title
        $pdf->SetY(160);
        $pdf->SetFont('helvetica', 'B', 14);
        $pdf->SetTextColor(0, 0, 0); // Black
        $pdf->Cell(0, 10, $instructor_name, 0, 1, 'C');
        
        $pdf->SetFont('helvetica', '', 11);
        $pdf->SetTextColor(77, 77, 77); // Dark gray
        $pdf->Cell(0, 8, 'Instructor / Trainer', 0, 1, 'C');
        
        // Add organization name
        $organization_name = 'Upskill HVAC';
        $pdf->SetY(180);
        $pdf->SetFont('helvetica', 'B', 11);
        $pdf->SetTextColor(0, 0, 0); // Black
        $pdf->Cell(0, 8, $organization_name, 0, 1, 'C');
        
        // Add venue info if available
        $venue_name = $certificate_data['venue_name'] ?? '';
        if (!empty($venue_name)) {
            $pdf->SetFont('helvetica', '', 10);
            $pdf->SetTextColor(77, 77, 77); // Dark gray
            $pdf->Cell(0, 8, $venue_name, 0, 1, 'C');
        }
        
        // Add certificate details at the bottom
        $pdf->SetFont('helvetica', '', 8);
        $pdf->SetTextColor(128, 128, 128); // Light gray
        $pdf->SetY(195);
        $pdf->Cell(0, 10, 'Certificate #: ' . $certificate->certificate_number . ' | Issue Date: ' . date('F j, Y', strtotime($certificate->date_generated)), 0, 1, 'C');
        
        // Add decorative elements (optional)
        $this->add_decorative_elements($pdf);
    }

    /**
     * Add certificate background.
     *
     * @param TCPDF $pdf The TCPDF instance.
     */
    protected function add_certificate_background($pdf) {
        // Check if custom background exists
        $background_path = HVAC_PLUGIN_DIR . 'assets/images/certificate-background.jpg';
        
        if (file_exists($background_path)) {
            // Add background
            $pdf->Image($background_path, 0, 0, $pdf->getPageWidth(), $pdf->getPageHeight(), '', '', '', false, 300);
        } else {
            // Create a simple background with border
            $pdf->SetFillColor(255, 255, 255);
            $pdf->Rect(0, 0, $pdf->getPageWidth(), $pdf->getPageHeight(), 'F');
            
            // Add border
            $pdf->SetDrawColor(0, 77, 155); // Blue
            $pdf->SetLineWidth(1.5);
            $pdf->Rect(5, 5, $pdf->getPageWidth() - 10, $pdf->getPageHeight() - 10, 'D');
            
            // Add inner border
            $pdf->SetDrawColor(200, 200, 200); // Light gray
            $pdf->SetLineWidth(0.5);
            $pdf->Rect(10, 10, $pdf->getPageWidth() - 20, $pdf->getPageHeight() - 20, 'D');
        }
    }

    /**
     * Add logo to certificate.
     *
     * @param TCPDF $pdf The TCPDF instance.
     */
    protected function add_logo($pdf) {
        // Check if logo exists
        $logo_path = HVAC_PLUGIN_DIR . 'assets/images/certificate-logo.png';
        
        if (file_exists($logo_path)) {
            // Add logo at top left
            $pdf->Image($logo_path, 15, 15, 40, 0, '', '', '', false, 300);
        }
    }
    
    /**
     * Add Upskill HVAC logo to certificate.
     *
     * @param TCPDF $pdf The TCPDF instance.
     */
    protected function add_upskill_logo($pdf) {
        // Check for uploaded logo in WordPress uploads directory
        $upload_dir = wp_upload_dir();
        $logo_path = $upload_dir['basedir'] . '/2025/05/UpskillHVAC-Logo_Black_NoOutline.png';
        
        // Fallback to 2024 directory if 2025 doesn't exist
        if (!file_exists($logo_path)) {
            $logo_path = $upload_dir['basedir'] . '/2024/05/UpskillHVAC-Logo_Black_NoOutline.png';
        }
        
        // Check plugin assets directory as another fallback
        if (!file_exists($logo_path)) {
            $logo_path = HVAC_PLUGIN_DIR . 'assets/images/upskill-hvac-logo.png';
        }
        
        if (file_exists($logo_path)) {
            // Add logo at top center
            // Calculate center position - assuming letter size landscape (279.4mm wide)
            $page_width = $pdf->getPageWidth();
            $logo_width = 50; // 50mm wide logo
            $x_position = ($page_width - $logo_width) / 2;
            
            $pdf->Image($logo_path, $x_position, 10, $logo_width, 0, '', '', '', false, 300);
        } else {
            // If no logo found, add text branding
            $pdf->SetFont('helvetica', 'B', 16);
            $pdf->SetTextColor(0, 77, 155); // Blue
            $pdf->SetY(15);
            $pdf->Cell(0, 10, 'UPSKILL HVAC', 0, 1, 'C');
        }
    }
    
    /**
     * Add decorative elements to certificate.
     *
     * @param TCPDF $pdf The TCPDF instance.
     */
    protected function add_decorative_elements($pdf) {
        // Add decorative corner elements
        $pdf->SetDrawColor(0, 77, 155); // Blue
        $pdf->SetLineWidth(0.5);
        
        // Top left corner
        $pdf->Line(10, 10, 30, 10);
        $pdf->Line(10, 10, 10, 30);
        
        // Top right corner
        $page_width = $pdf->getPageWidth();
        $pdf->Line($page_width - 30, 10, $page_width - 10, 10);
        $pdf->Line($page_width - 10, 10, $page_width - 10, 30);
        
        // Bottom left corner
        $page_height = $pdf->getPageHeight();
        $pdf->Line(10, $page_height - 30, 10, $page_height - 10);
        $pdf->Line(10, $page_height - 10, 30, $page_height - 10);
        
        // Bottom right corner
        $pdf->Line($page_width - 30, $page_height - 10, $page_width - 10, $page_height - 10);
        $pdf->Line($page_width - 10, $page_height - 30, $page_width - 10, $page_height - 10);
    }

    /**
     * Get attendee data from Event Tickets.
     *
     * @param int $attendee_id The attendee ID.
     * 
     * @return array Attendee data.
     */
    protected function get_attendee_data($attendee_id) {
        $attendee_data = array();
        
        // Get attendee post
        $attendee = get_post($attendee_id);
        
        if (!$attendee) {
            return $attendee_data;
        }
        
        // Try multiple meta keys for attendee name (matching the template query)
        $meta_keys_for_name = array(
            '_tec_tickets_commerce_full_name',  // TEC Commerce
            '_tribe_tpp_full_name',              // Tribe PayPal Tickets
            '_tribe_tickets_full_name',          // Event Tickets
            '_tribe_rsvp_full_name',             // RSVP
            'attendee_full_name',                // Legacy
            '_name',                             // Generic
            'name'                               // Generic
        );
        
        $attendee_name = '';
        foreach ($meta_keys_for_name as $meta_key) {
            $name = get_post_meta($attendee_id, $meta_key, true);
            if (!empty($name)) {
                $attendee_name = $name;
                break;
            }
        }
        
        // If still no name, try first and last name separately
        if (empty($attendee_name)) {
            $first_name_keys = array(
                '_tribe_tickets_first_name',
                '_tribe_tpp_first_name',
                '_tec_tickets_commerce_first_name',
                'attendee_first_name',
                'first_name'
            );
            
            $last_name_keys = array(
                '_tribe_tickets_last_name',
                '_tribe_tpp_last_name',
                '_tec_tickets_commerce_last_name',
                'attendee_last_name',
                'last_name'
            );
            
            $first_name = '';
            $last_name = '';
            
            foreach ($first_name_keys as $key) {
                $fname = get_post_meta($attendee_id, $key, true);
                if (!empty($fname)) {
                    $first_name = $fname;
                    break;
                }
            }
            
            foreach ($last_name_keys as $key) {
                $lname = get_post_meta($attendee_id, $key, true);
                if (!empty($lname)) {
                    $last_name = $lname;
                    break;
                }
            }
            
            if (!empty($first_name) || !empty($last_name)) {
                $attendee_name = trim($first_name . ' ' . $last_name);
            }
        }
        
        // Try multiple meta keys for email (matching the template query)
        $meta_keys_for_email = array(
            '_tec_tickets_commerce_email',
            '_tribe_tpp_email',
            '_tribe_tickets_email',
            '_tribe_tpp_attendee_email',
            '_tribe_rsvp_email',
            'attendee_email',
            '_email',
            'email'
        );
        
        $attendee_email = '';
        foreach ($meta_keys_for_email as $meta_key) {
            $email = get_post_meta($attendee_id, $meta_key, true);
            if (!empty($email) && is_email($email)) {
                $attendee_email = $email;
                break;
            }
        }
        
        // Try to find user by email
        $user_id = 0;
        if (!empty($attendee_email)) {
            $user = get_user_by('email', $attendee_email);
            if ($user) {
                $user_id = $user->ID;
            }
        }
        
        // If still no name, use email prefix or "Attendee"
        if (empty($attendee_name)) {
            if (!empty($attendee_email)) {
                $email_parts = explode('@', $attendee_email);
                $attendee_name = ucwords(str_replace(array('.', '_', '-'), ' ', $email_parts[0]));
            } else {
                $attendee_name = 'Attendee #' . $attendee_id;
            }
        }
        
        // Build attendee data
        $attendee_data = array(
            'attendee_id' => $attendee_id,
            'attendee_name' => $attendee_name,
            'attendee_email' => $attendee_email,
            'user_id' => $user_id
        );
        
        // Log for debugging
        if (defined('WP_DEBUG') && WP_DEBUG && empty($attendee_name)) {
            error_log("Certificate Generator: No name found for attendee ID $attendee_id");
        }
        
        return $attendee_data;
    }

    /**
     * Get event data from The Events Calendar.
     *
     * @param int $event_id The event ID.
     * 
     * @return array Event data.
     */
    protected function get_event_data($event_id) {
        $event_data = array();
        
        // Get event post
        $event = get_post($event_id);
        
        if (!$event) {
            return $event_data;
        }
        
        // Get event details
        $event_name = $event->post_title;
        $event_date = tribe_get_start_date($event_id, false, 'F j, Y');
        
        // Get venue details
        $venue_id = tribe_get_venue_id($event_id);
        $venue_name = tribe_get_venue($event_id);
        
        // Get organizer details
        $organizer_id = tribe_get_organizer_id($event_id);
        $organizer_name = tribe_get_organizer($event_id);
        
        // Get trainer/instructor name
        // First check if this event has a trainer/author
        $trainer_id = $event->post_author;
        $trainer = get_userdata($trainer_id);
        $instructor_name = '';
        
        if ($trainer) {
            // Try to get display name first
            $instructor_name = $trainer->display_name;
            
            // If no display name, try full name
            if (empty($instructor_name) || $instructor_name == $trainer->user_login) {
                $first_name = get_user_meta($trainer_id, 'first_name', true);
                $last_name = get_user_meta($trainer_id, 'last_name', true);
                if ($first_name || $last_name) {
                    $instructor_name = trim($first_name . ' ' . $last_name);
                }
            }
            
            // Fallback to organizer name if still empty
            if (empty($instructor_name)) {
                $instructor_name = $organizer_name;
            }
        } else {
            // Use organizer name as fallback
            $instructor_name = $organizer_name;
        }
        
        // Build event data
        $event_data = array(
            'event_id' => $event_id,
            'event_name' => $event_name,
            'event_date' => get_post_meta($event_id, '_EventStartDate', true),
            'event_date_formatted' => $event_date,
            'venue_id' => $venue_id,
            'venue_name' => $venue_name,
            'organizer_id' => $organizer_id,
            'organization_name' => $organizer_name,
            'instructor_name' => $instructor_name,
            'trainer_name' => $instructor_name, // Also include as trainer_name for compatibility
            'trainer_id' => $trainer_id
        );
        
        return $event_data;
    }

    /**
     * Generate certificates in batch.
     *
     * @param int   $event_id         The event ID.
     * @param array $attendee_ids     Array of attendee IDs.
     * @param array $custom_data      Optional custom data to override defaults.
     * @param int   $generated_by     The ID of the user who generated the certificates.
     * @param bool  $checked_in_only  Whether to generate certificates only for checked-in attendees.
     * 
     * @return array Results with success and error counts.
     */
    public function generate_certificates_batch($event_id, $attendee_ids, $custom_data = array(), $generated_by = 0, $checked_in_only = false) {
        $results = array(
            'success' => 0,
            'error' => 0,
            'duplicate' => 0,
            'not_checked_in' => 0,
            'certificate_ids' => array()
        );
        
        // Check if TCPDF is available
        if (!class_exists('TCPDF')) {
            HVAC_Logger::error("Cannot generate certificates: TCPDF library not found. Please install Composer dependencies.", 'Certificates');
            return $results;
        }
        
        if (empty($attendee_ids) || !is_array($attendee_ids)) {
            return $results;
        }
        
        foreach ($attendee_ids as $attendee_id) {
            // Check if certificate already exists
            if ($this->certificate_manager->certificate_exists($event_id, $attendee_id)) {
                $results['duplicate']++;
                continue;
            }
            
            // Check attendee check-in status if required
            if ($checked_in_only) {
                $is_checked_in = $this->is_attendee_checked_in($attendee_id);
                
                if (!$is_checked_in) {
                    $results['not_checked_in']++;
                    continue;
                }
            }
            
            $certificate_id = $this->generate_certificate($event_id, $attendee_id, $custom_data, $generated_by);
            
            if ($certificate_id) {
                $results['success']++;
                $results['certificate_ids'][] = $certificate_id;
            } else {
                $results['error']++;
            }
        }
        
        return $results;
    }
    
    /**
     * Check if an attendee is checked in.
     *
     * @param int $attendee_id The attendee ID.
     * 
     * @return bool True if checked in, false otherwise.
     */
    protected function is_attendee_checked_in($attendee_id) {
        // Get attendee check-in status from Event Tickets
        $check_in = get_post_meta($attendee_id, '_tribe_rsvp_checkedin', true);
        
        // For Event Tickets Plus we need to check a different meta key
        if (empty($check_in)) {
            $check_in = get_post_meta($attendee_id, '_tribe_tpp_checkedin', true);
        }
        
        // If still empty, check the more general meta key
        if (empty($check_in)) {
            $check_in = get_post_meta($attendee_id, '_tribe_checkedin', true);
        }
        
        return !empty($check_in) && $check_in == 1;
    }
}