<?php
/**
 * AUTO TESTER Training System API
 * Comprehensive training management for engineering students
 */

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');

// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

// Load configuration
require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../database.php';

class TrainingSystem {
    private $db;
    private $currentUser;
    
    public function __construct() {
        $this->db = Database::getInstance();
        $this->currentUser = $this->getCurrentUser();
    }
    
    /**
     * Apply for training program
     */
    public function applyTraining() {
        // Validate required fields
        $required = ['full_name', 'email', 'phone', 'university', 'faculty', 'department', 'academic_year', 'preferred_start_date'];
        foreach ($required as $field) {
            if (empty($_POST[$field])) {
                return [
                    'success' => false,
                    'message' => "Missing required field: {$field}"
                ];
            }
        }
        
        try {
            $this->db->beginTransaction();
            
            // Create user account if not exists
            $userId = $this->createOrUpdateUser();
            
            // Create trainee record
            $traineeId = $this->createTrainee($userId);
            
            // Create training application
            $applicationId = $this->createTrainingApplication($traineeId);
            
            // Handle file uploads
            $this->handleFileUploads($applicationId);
            
            // Send notification
            $this->sendNotification($traineeId, 'application_received');
            
            $this->db->commit();
            
            return [
                'success' => true,
                'message' => 'Application submitted successfully',
                'data' => [
                    'application_id' => $applicationId,
                    'application_number' => $this->getApplicationNumber($applicationId),
                    'trainee_id' => $traineeId
                ]
            ];
            
        } catch (Exception $e) {
            $this->db->rollBack();
            error_log("Training application error: " . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Failed to submit application'
            ];
        }
    }
    
    /**
     * Get training statistics
     */
    public function getTrainingStatistics() {
        $stats = [];
        
        // Total applications
        $stmt = $this->db->prepare("SELECT COUNT(*) as count FROM training_applications");
        $stmt->execute();
        $stats['total_applications'] = $stmt->fetch()['count'];
        
        // Active trainees
        $stmt = $this->db->prepare("SELECT COUNT(*) as count FROM trainees WHERE status = 'active'");
        $stmt->execute();
        $stats['active_trainees'] = $stmt->fetch()['count'];
        
        // Completed trainees
        $stmt = $this->db->prepare("SELECT COUNT(*) as count FROM trainees WHERE status = 'completed'");
        $stmt->execute();
        $stats['completed_trainees'] = $stmt->fetch()['count'];
        
        // Universities
        $stmt = $this->db->prepare("SELECT COUNT(DISTINCT university) as count FROM trainees");
        $stmt->execute();
        $stats['universities'] = $stmt->fetch()['count'];
        
        // Pending applications
        $stmt = $this->db->prepare("SELECT COUNT(*) as count FROM training_applications WHERE status = 'pending'");
        $stmt->execute();
        $stats['pending_applications'] = $stmt->fetch()['count'];
        
        // Average score
        $stmt = $this->db->prepare("SELECT AVG(final_score) as avg_score FROM trainees WHERE final_score IS NOT NULL");
        $stmt->execute();
        $result = $stmt->fetch();
        $stats['average_score'] = $result['avg_score'] ? round($result['avg_score'], 2) : 0;
        
        // Average attendance
        $stmt = $this->db->prepare("SELECT AVG(attendance_percentage) as avg_attendance FROM trainees WHERE attendance_percentage > 0");
        $stmt->execute();
        $result = $stmt->fetch();
        $stats['average_attendance'] = $result['avg_attendance'] ? round($result['avg_attendance'], 2) : 0;
        
        return [
            'success' => true,
            'data' => $stats
        ];
    }
    
    /**
     * Get training applications
     */
    public function getTrainingApplications() {
        $status = $_GET['status'] ?? '';
        
        $sql = "
            SELECT 
                ta.*,
                t.university,
                t.faculty,
                u.full_name,
                u.email,
                u.phone
            FROM training_applications ta
            JOIN trainees t ON ta.trainee_id = t.id
            JOIN users u ON t.user_id = u.id
        ";
        
        $params = [];
        if ($status) {
            $sql .= " WHERE ta.status = ?";
            $params[] = $status;
        }
        
        $sql .= " ORDER BY ta.application_date DESC";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        
        return [
            'success' => true,
            'data' => $stmt->fetchAll(PDO::FETCH_ASSOC)
        ];
    }
    
    /**
     * Get active trainees
     */
    public function getActiveTrainees() {
        $stmt = $this->db->prepare("
            SELECT 
                t.*,
                u.full_name,
                u.email,
                u.phone,
                (SELECT COUNT(*) FROM trainee_attendance WHERE trainee_id = t.id AND date >= CURDATE() - INTERVAL 7 DAY) as days_this_week
            FROM trainees t
            JOIN users u ON t.user_id = u.id
            WHERE t.status = 'active'
            ORDER BY t.training_start_date DESC
        ");
        $stmt->execute();
        
        $trainees = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        // Calculate current week for each trainee
        foreach ($trainees as &$trainee) {
            $startDate = new DateTime($trainee['training_start_date']);
            $currentDate = new DateTime();
            $interval = $startDate->diff($currentDate);
            $trainee['current_week'] = min(4, max(1, $interval->days / 7 + 1));
        }
        
        return [
            'success' => true,
            'data' => $trainees
        ];
    }
    
    /**
     * Review application
     */
    public function reviewApplication() {
        $applicationId = $_POST['application_id'] ?? '';
        $decision = $_POST['decision'] ?? '';
        $interviewNotes = $_POST['interview_notes'] ?? '';
        $rejectionReason = $_POST['rejection_reason'] ?? '';
        
        if (!$applicationId || !$decision) {
            return [
                'success' => false,
                'message' => 'Missing required fields'
            ];
        }
        
        try {
            $this->db->beginTransaction();
            
            // Update application status
            $stmt = $this->db->prepare("
                UPDATE training_applications 
                SET status = ?, reviewed_by = ?, reviewed_at = NOW(), rejection_reason = ?
                WHERE id = ?
            ");
            $stmt->execute([$decision, $this->currentUser['id'], $rejectionReason, $applicationId]);
            
            // Get trainee ID
            $stmt = $this->db->prepare("SELECT trainee_id FROM training_applications WHERE id = ?");
            $stmt->execute([$applicationId]);
            $traineeId = $stmt->fetch()['trainee_id'];
            
            // Update trainee status if accepted
            if ($decision === 'accepted') {
                $stmt = $this->db->prepare("UPDATE trainees SET status = 'accepted' WHERE id = ?");
                $stmt->execute([$traineeId]);
                
                // Send acceptance notification
                $this->sendNotification($traineeId, 'application_accepted');
            } elseif ($decision === 'rejected') {
                $this->sendNotification($traineeId, 'application_rejected');
            }
            
            $this->db->commit();
            
            return [
                'success' => true,
                'message' => 'Application reviewed successfully'
            ];
            
        } catch (Exception $e) {
            $this->db->rollBack();
            error_log("Application review error: " . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Failed to review application'
            ];
        }
    }
    
    /**
     * Record attendance
     */
    public function recordAttendance() {
        $traineeId = $_POST['trainee_id'] ?? '';
        $date = $_POST['date'] ?? date('Y-m-d');
        $checkInTime = $_POST['check_in_time'] ?? '';
        $checkOutTime = $_POST['check_out_time'] ?? '';
        $status = $_POST['status'] ?? 'present';
        
        if (!$traineeId || !$checkInTime) {
            return [
                'success' => false,
                'message' => 'Missing required fields'
            ];
        }
        
        try {
            // Calculate working hours
            $workingHours = 0;
            if ($checkInTime && $checkOutTime) {
                $checkIn = new DateTime($checkInTime);
                $checkOut = new DateTime($checkOutTime);
                $interval = $checkIn->diff($checkOut);
                $workingHours = $interval->h + ($interval->i / 60);
            }
            
            $stmt = $this->db->prepare("
                INSERT INTO trainee_attendance 
                (trainee_id, date, check_in_time, check_out_time, status, working_hours, recorded_by)
                VALUES (?, ?, ?, ?, ?, ?, ?)
                ON DUPLICATE KEY UPDATE
                check_in_time = VALUES(check_in_time),
                check_out_time = VALUES(check_out_time),
                status = VALUES(status),
                working_hours = VALUES(working_hours),
                recorded_by = VALUES(recorded_by)
            ");
            
            $result = $stmt->execute([
                $traineeId, $date, $checkInTime, $checkOutTime, $status, $workingHours, $this->currentUser['id']
            ]);
            
            if ($result) {
                // Update attendance percentage trigger will handle this automatically
                return [
                    'success' => true,
                    'message' => 'Attendance recorded successfully'
                ];
            }
            
        } catch (Exception $e) {
            error_log("Attendance recording error: " . $e->getMessage());
        }
        
        return [
            'success' => false,
            'message' => 'Failed to record attendance'
        ];
    }
    
    /**
     * Get attendance
     */
    public function getAttendance() {
        $date = $_GET['date'] ?? date('Y-m-d');
        
        $stmt = $this->db->prepare("
            SELECT 
                ta.*,
                t.id as trainee_id,
                u.full_name as trainee_name
            FROM trainee_attendance ta
            JOIN trainees t ON ta.trainee_id = t.id
            JOIN users u ON t.user_id = u.id
            WHERE ta.date = ? AND t.status = 'active'
            ORDER BY u.full_name
        ");
        $stmt->execute([$date]);
        
        return [
            'success' => true,
            'data' => $stmt->fetchAll(PDO::FETCH_ASSOC)
        ];
    }
    
    /**
     * Submit evaluation
     */
    public function submitEvaluation() {
        $traineeId = $_POST['trainee_id'] ?? '';
        $weekNumber = $_POST['week_number'] ?? '';
        $practicalScore = $_POST['practical_score'] ?? 0;
        $theoreticalScore = $_POST['theoretical_score'] ?? 0;
        $attitudeScore = $_POST['attitude_score'] ?? 0;
        $teamworkScore = $_POST['teamwork_score'] ?? 0;
        $feedback = $_POST['feedback'] ?? '';
        
        if (!$traineeId || !$weekNumber) {
            return [
                'success' => false,
                'message' => 'Missing required fields'
            ];
        }
        
        // Calculate overall score
        $overallScore = ($practicalScore + $theoreticalScore + $attitudeScore + $teamworkScore) / 4;
        
        try {
            $stmt = $this->db->prepare("
                INSERT INTO trainee_evaluations 
                (trainee_id, evaluator_id, week_number, practical_score, theoretical_score, attitude_score, teamwork_score, overall_score, feedback)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
                ON DUPLICATE KEY UPDATE
                practical_score = VALUES(practical_score),
                theoretical_score = VALUES(theoretical_score),
                attitude_score = VALUES(attitude_score),
                teamwork_score = VALUES(teamwork_score),
                overall_score = VALUES(overall_score),
                feedback = VALUES(feedback),
                evaluated_at = NOW()
            ");
            
            $result = $stmt->execute([
                $traineeId, $this->currentUser['id'], $weekNumber,
                $practicalScore, $theoreticalScore, $attitudeScore, $teamworkScore,
                $overallScore, $feedback
            ]);
            
            if ($result) {
                return [
                    'success' => true,
                    'message' => 'Evaluation submitted successfully',
                    'data' => ['overall_score' => round($overallScore, 2)]
                ];
            }
            
        } catch (Exception $e) {
            error_log("Evaluation submission error: " . $e->getMessage());
        }
        
        return [
            'success' => false,
            'message' => 'Failed to submit evaluation'
        ];
    }
    
    /**
     * Get evaluations
     */
    public function getEvaluations() {
        $stmt = $this->db->prepare("
            SELECT 
                te.*,
                u.full_name as trainee_name,
                evaluator.full_name as evaluator_name
            FROM trainee_evaluations te
            JOIN trainees t ON te.trainee_id = t.id
            JOIN users u ON t.user_id = u.id
            JOIN users evaluator ON te.evaluator_id = evaluator.id
            ORDER BY te.evaluated_at DESC
        ");
        $stmt->execute();
        
        return [
            'success' => true,
            'data' => $stmt->fetchAll(PDO::FETCH_ASSOC)
        ];
    }
    
    /**
     * Issue certificate
     */
    public function issueCertificate() {
        $traineeId = $_POST['trainee_id'] ?? '';
        
        if (!$traineeId) {
            return [
                'success' => false,
                'message' => 'Trainee ID is required'
            ];
        }
        
        try {
            $this->db->beginTransaction();
            
            // Calculate final score
            $stmt = $this->db->prepare("
                SELECT AVG(overall_score) as final_score 
                FROM trainee_evaluations 
                WHERE trainee_id = ?
            ");
            $stmt->execute([$traineeId]);
            $result = $stmt->fetch();
            $finalScore = round($result['final_score'], 2);
            
            // Determine grade
            $grade = $this->calculateGrade($finalScore);
            
            // Generate certificate number
            $certificateNumber = $this->generateCertificateNumber();
            
            // Create certificate record
            $stmt = $this->db->prepare("
                INSERT INTO training_certificates 
                (trainee_id, certificate_number, issue_date, completion_date, final_score, grade, issued_by, verification_code)
                VALUES (?, ?, CURDATE(), CURDATE(), ?, ?, ?, ?)
            ");
            
            $verificationCode = $this->generateVerificationCode();
            $result = $stmt->execute([
                $traineeId, $certificateNumber, $finalScore, $grade, 
                $this->currentUser['id'], $verificationCode
            ]);
            
            if ($result) {
                // Update trainee status
                $stmt = $this->db->prepare("
                    UPDATE trainees 
                    SET status = 'completed', final_score = ?, certificate_issued = TRUE
                    WHERE id = ?
                ");
                $stmt->execute([$finalScore, $traineeId]);
                
                // Generate PDF certificate
                $certificateId = $this->db->lastInsertId();
                $this->generateCertificatePDF($certificateId, $traineeId);
                
                // Send notification
                $this->sendNotification($traineeId, 'certificate_issued');
                
                $this->db->commit();
                
                return [
                    'success' => true,
                    'message' => 'Certificate issued successfully',
                    'data' => [
                        'certificate_id' => $certificateId,
                        'certificate_number' => $certificateNumber,
                        'final_score' => $finalScore,
                        'grade' => $grade
                    ]
                ];
            }
            
        } catch (Exception $e) {
            $this->db->rollBack();
            error_log("Certificate issuance error: " . $e->getMessage());
        }
        
        return [
            'success' => false,
            'message' => 'Failed to issue certificate'
        ];
    }
    
    /**
     * Get certificates
     */
    public function getCertificates() {
        $stmt = $this->db->prepare("
            SELECT 
                tc.*,
                u.full_name as trainee_name
            FROM training_certificates tc
            JOIN trainees t ON tc.trainee_id = t.id
            JOIN users u ON t.user_id = u.id
            ORDER BY tc.issue_date DESC
        ");
        $stmt->execute();
        
        return [
            'success' => true,
            'data' => $stmt->fetchAll(PDO::FETCH_ASSOC)
        ];
    }
    
    /**
     * Get training schedule
     */
    public function getTrainingSchedule() {
        $stmt = $this->db->prepare("
            SELECT 
                ts.*,
                u.full_name as instructor_name
            FROM training_schedule ts
            LEFT JOIN users u ON ts.instructor_id = u.id
            WHERE ts.is_active = TRUE
            ORDER BY ts.week_number, ts.day_number
        ");
        $stmt->execute();
        
        return [
            'success' => true,
            'data' => $stmt->fetchAll(PDO::FETCH_ASSOC)
        ];
    }
    
    // Private helper methods
    
    private function getCurrentUser() {
        // This would typically get the current user from session or token
        // For now, return a default admin user
        return [
            'id' => 1,
            'name' => 'System Admin',
            'role' => 'admin'
        ];
    }
    
    private function createOrUpdateUser() {
        $email = $_POST['email'];
        $fullName = $_POST['full_name'];
        $phone = $_POST['phone'];
        
        // Check if user exists
        $stmt = $this->db->prepare("SELECT id FROM users WHERE email = ?");
        $stmt->execute([$email]);
        $user = $stmt->fetch();
        
        if ($user) {
            return $user['id'];
        }
        
        // Create new user
        $stmt = $this->db->prepare("
            INSERT INTO users (full_name, email, phone, role, is_active, created_at)
            VALUES (?, ?, ?, 'trainee', TRUE, NOW())
        ");
        $stmt->execute([$fullName, $email, $phone]);
        
        return $this->db->lastInsertId();
    }
    
    private function createTrainee($userId) {
        $stmt = $this->db->prepare("
            INSERT INTO trainees (
                user_id, university, faculty, department, academic_year, gpa,
                graduation_year, student_id, national_id, training_start_date,
                training_end_date, status
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending')
        ");
        
        $stmt->execute([
            $userId,
            $_POST['university'],
            $_POST['faculty'],
            $_POST['department'],
            $_POST['academic_year'],
            $_POST['gpa'] ?? null,
            $_POST['graduation_year'] ?? null,
            $_POST['student_id'] ?? null,
            $_POST['national_id'] ?? null,
            $_POST['preferred_start_date'],
            $_POST['preferred_end_date']
        ]);
        
        return $this->db->lastInsertId();
    }
    
    private function createTrainingApplication($traineeId) {
        $stmt = $this->db->prepare("
            INSERT INTO training_applications (
                trainee_id, application_date, cover_letter,
                preferred_start_date, preferred_end_date, status
            ) VALUES (?, CURDATE(), ?, ?, ?, 'pending')
        ");
        
        $stmt->execute([
            $traineeId,
            $_POST['notes'] ?? '',
            $_POST['preferred_start_date'],
            $_POST['preferred_end_date']
        ]);
        
        return $this->db->lastInsertId();
    }
    
    private function handleFileUploads($applicationId) {
        // Handle CV upload
        if (isset($_FILES['cv_file']) && $_FILES['cv_file']['error'] === 0) {
            $cvPath = $this->uploadFile($_FILES['cv_file'], 'cv');
            if ($cvPath) {
                $stmt = $this->db->prepare("UPDATE training_applications SET cv_file = ? WHERE id = ?");
                $stmt->execute([$cvPath, $applicationId]);
            }
        }
        
        // Handle recommendation letter upload
        if (isset($_FILES['recommendation_letter']) && $_FILES['recommendation_letter']['error'] === 0) {
            $recPath = $this->uploadFile($_FILES['recommendation_letter'], 'recommendation');
            if ($recPath) {
                $stmt = $this->db->prepare("UPDATE training_applications SET recommendation_letter = ? WHERE id = ?");
                $stmt->execute([$recPath, $applicationId]);
            }
        }
    }
    
    private function uploadFile($file, $type) {
        $uploadDir = __DIR__ . '/../../uploads/training/' . $type . '/';
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0777, true);
        }
        
        $fileName = uniqid() . '_' . basename($file['name']);
        $filePath = $uploadDir . $fileName;
        
        if (move_uploaded_file($file['tmp_name'], $filePath)) {
            return '/uploads/training/' . $type . '/' . $fileName;
        }
        
        return false;
    }
    
    private function sendNotification($traineeId, $type) {
        $stmt = $this->db->prepare("
            INSERT INTO training_notifications (trainee_id, type, title, message)
            VALUES (?, ?, ?, ?)
        ");
        
        $messages = [
            'application_received' => ['Application Received', 'Your training application has been received successfully'],
            'application_accepted' => ['Application Accepted', 'Congratulations! Your application has been accepted'],
            'application_rejected' => ['Application Rejected', 'We regret to inform you that your application was not accepted'],
            'certificate_issued' => ['Certificate Issued', 'Your training certificate has been issued']
        ];
        
        if (isset($messages[$type])) {
            $stmt->execute([$traineeId, $type, $messages[$type][0], $messages[$type][1]]);
        }
    }
    
    private function getApplicationNumber($applicationId) {
        $stmt = $this->db->prepare("SELECT application_number FROM training_applications WHERE id = ?");
        $stmt->execute([$applicationId]);
        $result = $stmt->fetch();
        return $result['application_number'] ?? '';
    }
    
    private function calculateGrade($score) {
        if ($score >= 85) return 'excellent';
        if ($score >= 75) return 'very_good';
        if ($score >= 65) return 'good';
        if ($score >= 60) return 'pass';
        return 'fail';
    }
    
    private function generateCertificateNumber() {
        return 'CERT' . date('Y') . str_pad(mt_rand(1, 9999), 4, '0', STR_PAD_LEFT);
    }
    
    private function generateVerificationCode() {
        return strtoupper(substr(md5(uniqid()), 0, 8));
    }
    
    private function generateCertificatePDF($certificateId, $traineeId) {
        // This would generate a PDF certificate
        // For now, just create a placeholder URL
        $certificateUrl = "/uploads/certificates/certificate_{$certificateId}.pdf";
        
        $stmt = $this->db->prepare("UPDATE training_certificates SET certificate_url = ? WHERE id = ?");
        $stmt->execute([$certificateUrl, $certificateId]);
        
        return $certificateUrl;
    }
}

// Handle API requests
try {
    $training = new TrainingSystem();
    $action = $_GET['action'] ?? '';
    
    switch ($action) {
        case 'apply_training':
            echo json_encode($training->applyTraining(), JSON_UNESCAPED_UNICODE);
            break;
            
        case 'get_training_statistics':
            echo json_encode($training->getTrainingStatistics(), JSON_UNESCAPED_UNICODE);
            break;
            
        case 'get_training_applications':
            echo json_encode($training->getTrainingApplications(), JSON_UNESCAPED_UNICODE);
            break;
            
        case 'get_active_trainees':
            echo json_encode($training->getActiveTrainees(), JSON_UNESCAPED_UNICODE);
            break;
            
        case 'review_application':
            echo json_encode($training->reviewApplication(), JSON_UNESCAPED_UNICODE);
            break;
            
        case 'record_attendance':
            echo json_encode($training->recordAttendance(), JSON_UNESCAPED_UNICODE);
            break;
            
        case 'get_attendance':
            echo json_encode($training->getAttendance(), JSON_UNESCAPED_UNICODE);
            break;
            
        case 'submit_evaluation':
            echo json_encode($training->submitEvaluation(), JSON_UNESCAPED_UNICODE);
            break;
            
        case 'get_evaluations':
            echo json_encode($training->getEvaluations(), JSON_UNESCAPED_UNICODE);
            break;
            
        case 'issue_certificate':
            echo json_encode($training->issueCertificate(), JSON_UNESCAPED_UNICODE);
            break;
            
        case 'get_certificates':
            echo json_encode($training->getCertificates(), JSON_UNESCAPED_UNICODE);
            break;
            
        case 'get_training_schedule':
            echo json_encode($training->getTrainingSchedule(), JSON_UNESCAPED_UNICODE);
            break;
            
        default:
            http_response_code(400);
            echo json_encode([
                'success' => false,
                'message' => 'Invalid action'
            ]);
    }
    
} catch (Exception $e) {
    error_log("Training API Error: " . $e->getMessage());
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'message' => 'Internal server error'
    ]);
}
?>
