
<?php
/**
 * QR Code Generator Class
 * PSAU GAD Information System
 * Uses QR Code API via CDN
 */

class QRCode {
    private $db;
    
    public function __construct() {
        $this->db = getDB();
    }
    
    /**
     * Generate QR code for activity registration
     */
    public function generateForRegistration($registrationId) {
        try {
            // Get registration details
            $stmt = $this->db->prepare("
                SELECT ar.*, a.title as activity_title, u.email,
                       CONCAT(ep.first_name, ' ', ep.last_name) as user_name
                FROM activity_registrations ar
                JOIN activities a ON ar.activity_id = a.activity_id
                JOIN users u ON ar.user_id = u.user_id
                LEFT JOIN employee_profiles ep ON u.user_id = ep.user_id
                WHERE ar.registration_id = ?
            ");
            $stmt->execute([$registrationId]);
            $registration = $stmt->fetch();

            if (!$registration) {
                return ['success' => false, 'message' => 'Registration not found'];
            }

            // Generate unique QR code data
            $qrData = $this->generateQRData($registrationId);

            // Update registration with QR code generated flag
            $updateStmt = $this->db->prepare("
                UPDATE activity_registrations
                SET qr_code = 'generated', qr_code_generated_at = NOW()
                WHERE registration_id = ?
            ");
            $updateStmt->execute([$registrationId]);

            return [
                'success' => true,
                'qr_data' => $qrData,
                'message' => 'QR code generated successfully'
            ];

        } catch (PDOException $e) {
            logError("QR Code generation error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Database error'];
        }
    }
    
    /**
     * Generate QR code data string
     */
    private function generateQRData($registrationId) {
        // Create a unique, encrypted string for the QR code
        $data = [
            'reg_id' => $registrationId,
            'timestamp' => time(),
            'hash' => hash('sha256', $registrationId . SITE_NAME . time())
        ];
        
        return base64_encode(json_encode($data));
    }
    
    /**
     * Generate QR code image URL using API
     */
    public function generateQRImage($data, $size = 300) {
        // Using QR Server API (free, no API key required)
        $encodedData = urlencode($data);
        return "https://api.qrserver.com/v1/create-qr-code/?size={$size}x{$size}&data={$encodedData}";
    }

    /**
     * Verify QR code data
     */
    public function verifyQRCode($qrData) {
        try {
            $decoded = json_decode(base64_decode($qrData), true);
            
            if (!$decoded || !isset($decoded['reg_id'])) {
                return ['success' => false, 'message' => 'Invalid QR code'];
            }
            
            $registrationId = $decoded['reg_id'];
            
            // Get registration details
            $stmt = $this->db->prepare("
                SELECT ar.*, a.title as activity_title, a.activity_date, a.start_time,
                       u.user_id, u.email,
                       CONCAT(ep.first_name, ' ', ep.last_name) as user_name,
                       ep.category, ep.position
                FROM activity_registrations ar
                JOIN activities a ON ar.activity_id = a.activity_id
                JOIN users u ON ar.user_id = u.user_id
                LEFT JOIN employee_profiles ep ON u.user_id = ep.user_id
                WHERE ar.registration_id = ? AND ar.is_approved = 1
            ");
            $stmt->execute([$registrationId]);
            $registration = $stmt->fetch();
            
            if (!$registration) {
                return ['success' => false, 'message' => 'Registration not found or not approved'];
            }
            
            // Check if already attended
            $checkStmt = $this->db->prepare("
                SELECT attendance_id FROM activity_attendance 
                WHERE registration_id = ?
            ");
            $checkStmt->execute([$registrationId]);
            
            if ($checkStmt->fetch()) {
                return ['success' => false, 'message' => 'Already marked as attended'];
            }
            
            return [
                'success' => true,
                'registration' => $registration
            ];
            
        } catch (Exception $e) {
            logError("QR Code verification error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Verification failed'];
        }
    }
    
    /**
     * Mark attendance using QR code
     */
    public function markAttendance($qrData, $scannedBy) {
        try {
            $verification = $this->verifyQRCode($qrData);
            
            if (!$verification['success']) {
                return $verification;
            }
            
            $registration = $verification['registration'];
            
            // Determine if late or on time
            $activityStartTime = strtotime($registration['activity_date'] . ' ' . $registration['start_time']);
            $cutoffTime = $activityStartTime + (ATTENDANCE_GRACE_PERIOD * 60);
            $currentTime = time();
            
            $status = ($currentTime <= $cutoffTime) ? 'present' : 'late';
            
            // Insert attendance record
            $stmt = $this->db->prepare("
                INSERT INTO activity_attendance 
                (activity_id, user_id, registration_id, attendance_type, status, scanned_by)
                VALUES (?, ?, ?, 'qr_scan', ?, ?)
            ");
            
            $stmt->execute([
                $registration['activity_id'],
                $registration['user_id'],
                $registration['registration_id'],
                $status,
                $scannedBy
            ]);
            
            return [
                'success' => true,
                'message' => 'Attendance marked successfully',
                'status' => $status,
                'user_name' => $registration['user_name']
            ];
            
        } catch (PDOException $e) {
            logError("Mark attendance error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to mark attendance'];
        }
    }
    
    /**
     * Get QR code image path
     */
    public function getQRCodePath($registrationId) {
        try {
            $stmt = $this->db->prepare("
                SELECT qr_code FROM activity_registrations 
                WHERE registration_id = ?
            ");
            $stmt->execute([$registrationId]);
            $result = $stmt->fetch();
            
            if ($result && $result['qr_code']) {
                return QR_CODES_PATH . '/' . $result['qr_code'];
            }
            
            return null;
        } catch (PDOException $e) {
            logError("Get QR code path error: " . $e->getMessage());
            return null;
        }
    }
    
    /**
     * Delete QR code file
     */
    public function deleteQRCode($registrationId) {
        $filepath = $this->getQRCodePath($registrationId);

        if ($filepath && file_exists($filepath)) {
            return unlink($filepath);
        }

        return false;
    }

    /**
     * Verify and mark attendance in one step (for scanner)
     */
    public function verifyAndMarkAttendance($qrData, $activityId) {
        try {
            $decoded = json_decode(base64_decode($qrData), true);

            if (!$decoded || !isset($decoded['reg_id'])) {
                return ['success' => false, 'message' => 'Invalid QR code format'];
            }

            $registrationId = $decoded['reg_id'];

            // Get registration details
            $stmt = $this->db->prepare("
                SELECT ar.*, a.title as activity_title, a.activity_date, a.start_time,
                       u.user_id, u.email,
                       CONCAT(ep.first_name, ' ', ep.last_name) as user_name,
                       ep.category, ep.position
                FROM activity_registrations ar
                JOIN activities a ON ar.activity_id = a.activity_id
                JOIN users u ON ar.user_id = u.user_id
                LEFT JOIN employee_profiles ep ON u.user_id = ep.user_id
                WHERE ar.registration_id = ? AND ar.status = 'approved' AND a.activity_id = ?
            ");
            $stmt->execute([$registrationId, $activityId]);
            $registration = $stmt->fetch();

            if (!$registration) {
                return ['success' => false, 'message' => 'Invalid QR code or registration not approved'];
            }

            // Check if already attended
            $checkStmt = $this->db->prepare("
                SELECT attendance_id FROM activity_attendance
                WHERE registration_id = ?
            ");
            $checkStmt->execute([$registrationId]);

            if ($checkStmt->fetch()) {
                return [
                    'success' => false,
                    'message' => 'Already marked as attended',
                    'employee_name' => $registration['user_name']
                ];
            }

            // Determine if late or on time
            $activityStartTime = strtotime($registration['activity_date'] . ' ' . $registration['start_time']);
            $cutoffTime = $activityStartTime + (ATTENDANCE_GRACE_PERIOD * 60);
            $currentTime = time();

            $status = ($currentTime <= $cutoffTime) ? 'present' : 'late';
            $statusText = $status === 'present' ? 'On Time' : 'Late';

            // Insert attendance record
            $stmt = $this->db->prepare("
                INSERT INTO activity_attendance
                (activity_id, user_id, registration_id, attendance_type, status, scanned_by)
                VALUES (?, ?, ?, 'qr_scan', ?, ?)
            ");

            $stmt->execute([
                $registration['activity_id'],
                $registration['user_id'],
                $registration['registration_id'],
                $status,
                getCurrentUserId()
            ]);

            return [
                'success' => true,
                'message' => 'Attendance marked successfully - ' . $statusText,
                'status' => $status,
                'status_text' => $statusText,
                'employee_name' => $registration['user_name'],
                'category' => $registration['category'],
                'position' => $registration['position']
            ];

        } catch (PDOException $e) {
            logError("Verify and mark attendance error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to mark attendance: ' . $e->getMessage()];
        }
    }

    /**
     * Generate QR code (simplified method for registration approval)
     */
    public function generateQRCode($registrationId) {
        return $this->generateForRegistration($registrationId);
    }
}

