<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../../includes/config.php';
require_once __DIR__ . '/../../includes/database.php';

// Initialize response array
$response = ['success' => false, 'data' => [], 'message' => ''];

try {
    // Check if file was uploaded
    if (!isset($_FILES['csv_file']) || $_FILES['csv_file']['error'] !== UPLOAD_ERR_OK) {
        throw new Exception('No file uploaded or upload error occurred');
    }
    
    $uploadedFile = $_FILES['csv_file'];
    $file = $uploadedFile['tmp_name'];
    
    // Validate file exists
    if (!file_exists($file)) {
        throw new Exception('Uploaded file not found on server');
    }
    
    // Check file size (max 5MB)
    if ($uploadedFile['size'] > 5 * 1024 * 1024) {
        throw new Exception('File size too large. Maximum 5MB allowed.');
    }
    
    // Check if file is readable
    if (!is_readable($file)) {
        throw new Exception('Cannot read uploaded file');
    }
    
    $pdo = Database::getInstance()->getConnection();
    
    // Read CSV file
    $handle = fopen($file, 'r');
    if (!$handle) {
        throw new Exception('Cannot open CSV file for reading');
    }
    
    // Read headers
    $headers = fgetcsv($handle);
    if ($headers === FALSE || count($headers) === 0) {
        fclose($handle);
        throw new Exception('Empty CSV file or invalid format');
    }
    
    // Clean headers and map to lowercase for comparison
    $headers = array_map('strtolower', array_map('trim', $headers));
    $expectedHeaders = ['full_name', 'email', 'username', 'password', 'role', 'status', 'department'];
    
    // Check if all required headers are present
    $missingHeaders = array_diff($expectedHeaders, $headers);
    if (!empty($missingHeaders)) {
        fclose($handle);
        throw new Exception('Missing CSV headers: ' . implode(', ', $missingHeaders) . 
                           '. Required headers: ' . implode(', ', $expectedHeaders));
    }
    
    $successCount = 0;
    $errors = [];
    $rowNumber = 1; // Header row is row 1
    
    // Process each row
    while (($data = fgetcsv($handle)) !== FALSE) {
        $rowNumber++;
        
        // Skip empty rows
        if ($data === null || count(array_filter($data)) === 0) {
            continue;
        }
        
        // Ensure we have enough columns
        if (count($data) < count($expectedHeaders)) {
            $errors[] = ['row' => $rowNumber, 'message' => 'Insufficient columns in row'];
            continue;
        }
        
        // Map data to associative array using header positions
        $userData = [];
        foreach ($expectedHeaders as $index => $header) {
            if (isset($headers[$index]) && isset($data[$index])) {
                $userData[$header] = trim($data[$index]);
            } else {
                $userData[$header] = '';
            }
        }
        
        // Validate required fields
        $required = ['full_name', 'email', 'username', 'password', 'role', 'status'];
        foreach ($required as $field) {
            if (empty($userData[$field])) {
                $errors[] = ['row' => $rowNumber, 'message' => "Missing required field: $field"];
                continue 2; // Skip to next row
            }
        }
        
        // Validate email format
        if (!filter_var($userData['email'], FILTER_VALIDATE_EMAIL)) {
            $errors[] = ['row' => $rowNumber, 'message' => "Invalid email format: " . $userData['email']];
            continue;
        }
        
        // Validate role and status
        $validRoles = ['user', 'admin', 'superuser'];
        $validStatuses = ['active', 'inactive'];
        
        if (!in_array(strtolower($userData['role']), $validRoles)) {
            $errors[] = ['row' => $rowNumber, 'message' => "Invalid role: " . $userData['role'] . ". Must be: " . implode(', ', $validRoles)];
            continue;
        }
        
        if (!in_array(strtolower($userData['status']), $validStatuses)) {
            $errors[] = ['row' => $rowNumber, 'message' => "Invalid status: " . $userData['status'] . ". Must be: " . implode(', ', $validStatuses)];
            continue;
        }
        
        // Check if user already exists
        $checkStmt = $pdo->prepare("SELECT id FROM users WHERE username = ? OR email = ?");
        $checkStmt->execute([$userData['username'], $userData['email']]);
        
        if ($checkStmt->fetch()) {
            $errors[] = ['row' => $rowNumber, 'message' => "Username or email already exists: " . $userData['username'] . " / " . $userData['email']];
            continue;
        }
        
        // Hash password
        $hashedPassword = password_hash($userData['password'], PASSWORD_DEFAULT);
        
        // Insert user
        $insertStmt = $pdo->prepare("INSERT INTO users (full_name, email, username, password, role, status, department) 
                                   VALUES (?, ?, ?, ?, ?, ?, ?)");
        
        try {
            $success = $insertStmt->execute([
                $userData['full_name'],
                $userData['email'],
                $userData['username'],
                $hashedPassword,
                strtolower($userData['role']),
                strtolower($userData['status']),
                $userData['department'] ?? ''
            ]);
            
            if ($success) {
                $successCount++;
            } else {
                $errorInfo = $insertStmt->errorInfo();
                $errors[] = ['row' => $rowNumber, 'message' => 'Database insertion failed: ' . ($errorInfo[2] ?? 'Unknown error')];
            }
        } catch (PDOException $e) {
            $errors[] = ['row' => $rowNumber, 'message' => 'Database error: ' . $e->getMessage()];
        }
    }
    
    fclose($handle);
    
    // Prepare success response
    $response['success'] = true;
    $response['data'] = [
        'success_count' => $successCount,
        'error_count' => count($errors),
        'errors' => $errors
    ];
    $response['message'] = "Bulk upload completed successfully. {$successCount} users created." . 
                          (count($errors) > 0 ? " {$errors} errors occurred." : "");
    
} catch (Exception $e) {
    $response['message'] = 'Error: ' . $e->getMessage();
}

// Ensure no output before this
if (ob_get_length()) {
    ob_clean();
}

echo json_encode($response);
exit;
?>