Sindbad~EG File Manager

Current Path : /home/copmadinaarea/thecopmadinaarea.org/portal/modules/membership/
Upload File :
Current File : /home/copmadinaarea/thecopmadinaarea.org/portal/modules/membership/special_upload.php

<?php
require_once '../../config/config.php';
require_once '../../classes/MembershipCard.php';
checkLogin();

$pageTitle = 'Special Upload - ' . APP_NAME;
$db = Database::getInstance()->getConnection();

$successMessage = '';
$errorMessage = '';
$uploadResults = [];

// Access
$accessLevel = $_SESSION['access_level'] ?? 'assembly';
$areaId = $_SESSION['area_id'] ?? null;
$districtId = $_SESSION['district_id'] ?? null;
$assemblyId = $_SESSION['assembly_id'] ?? null;

// Helpers from upload.php
if (!function_exists('generateMembershipId')) {
    function generateMembershipId() {
        return 'MEM' . date('Y') . str_pad(mt_rand(1, 999999), 6, '0', STR_PAD_LEFT);
    }
}

if (!function_exists('generateTrackingCode')) {
    function generateTrackingCode($type = 'member') {
        $prefix = $type === 'member' ? 'MEM' : 'USR';
        return $prefix . date('Y') . str_pad(mt_rand(1, 999999), 6, '0', STR_PAD_LEFT);
    }
}

if (!function_exists('generateBarcode')) {
    function generateBarcode($code) {
        $width = 200;
        $height = 50;
        $image = imagecreate($width, $height);
        $white = imagecolorallocate($image, 255, 255, 255);
        $black = imagecolorallocate($image, 0, 0, 0);
        imagefill($image, 0, 0, $white);
        $codeLength = strlen($code);
        $x = 10;
        for ($i = 0; $i < $codeLength; $i++) {
            $char = ord($code[$i]);
            $pattern = $char % 4;
            for ($j = 0; $j < 3; $j++) {
                $barWidth = ($pattern & (1 << $j)) ? 3 : 1;
                imagefilledrectangle($image, $x, 5, $x + $barWidth, 35, $black);
                $x += $barWidth + 1;
            }
        }
        imagestring($image, 2, 10, 37, substr($code, 0, 20), $black);
        ob_start();
        imagepng($image);
        $imageData = ob_get_contents();
        ob_end_clean();
        imagedestroy($image);
        return 'data:image/png;base64,' . base64_encode($imageData);
    }
}

if (!function_exists('generateQRCode')) {
    function generateQRCode($code) {
        $size = 100;
        $image = imagecreate($size, $size);
        $white = imagecolorallocate($image, 255, 255, 255);
        $black = imagecolorallocate($image, 0, 0, 0);
        imagefill($image, 0, 0, $white);
        $codeHash = md5($code);
        $blockSize = 5;
        imagefilledrectangle($image, 5, 5, 30, 30, $black);
        imagefilledrectangle($image, 70, 5, 95, 30, $black);
        imagefilledrectangle($image, 5, 70, 30, 95, $black);
        imagefilledrectangle($image, 10, 10, 25, 25, $white);
        imagefilledrectangle($image, 75, 10, 90, 25, $white);
        imagefilledrectangle($image, 10, 75, 25, 90, $white);
        imagefilledrectangle($image, 15, 15, 20, 20, $black);
        imagefilledrectangle($image, 80, 15, 85, 20, $black);
        imagefilledrectangle($image, 15, 80, 20, 85, $black);
        for ($i = 0; $i < 32; $i++) {
            $hexChar = hexdec($codeHash[$i]);
            for ($bit = 0; $bit < 4; $bit++) {
                if ($hexChar & (1 << $bit)) {
                    $x = 35 + (($i * 2 + $bit) % 6) * $blockSize;
                    $y = 35 + floor(($i * 2 + $bit) / 6) * $blockSize;
                    if ($x < 95 && $y < 95) {
                        imagefilledrectangle($image, $x, $y, $x + $blockSize - 1, $y + $blockSize - 1, $black);
                    }
                }
            }
        }
        ob_start();
        imagepng($image);
        $imageData = ob_get_contents();
        ob_end_clean();
        imagedestroy($image);
        return 'data:image/png;base64,' . base64_encode($imageData);
    }
}

if (!function_exists('createMemberUserCode')) {
    function createMemberUserCode(PDO $db, $memberId, $createdBy) {
        try {
            $memberId = (int)$memberId;
            if ($memberId <= 0) {
                return;
            }
            $existingStmt = $db->prepare('SELECT id FROM memberuser_codes WHERE member_id = :member_id LIMIT 1');
            $existingStmt->execute(['member_id' => $memberId]);
            if ($existingStmt->fetch()) {
                return;
            }
            do {
                $trackingCode = generateTrackingCode('member');
                $checkStmt = $db->prepare('SELECT id FROM memberuser_codes WHERE tracking_code = :code');
                $checkStmt->execute(['code' => $trackingCode]);
            } while ($checkStmt->fetch());

            $code = 'MC' . date('Ymd') . str_pad($memberId, 4, '0', STR_PAD_LEFT) . mt_rand(100, 999);
            $barcode = generateBarcode($trackingCode);
            $qrcode = generateQRCode($trackingCode);

            $eventStmt = $db->prepare("SELECT id FROM events WHERE name = 'Attendance' AND is_active = 1 LIMIT 1");
            $eventStmt->execute();
            $defaultEvent = $eventStmt->fetch();
            $eventId = $defaultEvent ? $defaultEvent['id'] : null;

            $codeStmt = $db->prepare('
                INSERT INTO memberuser_codes (
                    code, description, member_id, event_id, code_type, tracking_code,
                    barcode, qrcode, created_by, is_active
                ) VALUES (
                    :code, :description, :member_id, :event_id, \'member\', :tracking_code,
                    :barcode, :qrcode, :created_by, 1
                )
            ');
            $codeStmt->execute([
                'code' => $code,
                'description' => 'Auto-generated member tracking code',
                'member_id' => $memberId,
                'event_id' => $eventId,
                'tracking_code' => $trackingCode,
                'barcode' => $barcode,
                'qrcode' => $qrcode,
                'created_by' => $createdBy
            ]);
        } catch (Exception $e) {
        }
    }
}

// Step 2: finalize upload using stored rows and chosen location
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['finalize_upload'])) {
    $selectedAreaId = (int)($_POST['area_id'] ?? 0);
    $selectedDistrictId = (int)($_POST['district_id'] ?? 0);
    $selectedAssemblyId = (int)($_POST['assembly_id'] ?? 0);

    if ($selectedAreaId <= 0 || $selectedDistrictId <= 0 || $selectedAssemblyId <= 0) {
        $errorMessage = 'Please select Area, District and Assembly before uploading.';
    } elseif (empty($_SESSION['special_upload_rows']) || empty($_SESSION['special_upload_headers'])) {
        $errorMessage = 'No uploaded data found. Please upload a file again.';
    } else {
        $rows = $_SESSION['special_upload_rows'];
        $headers = $_SESSION['special_upload_headers'];

        $successCount = 0;
        $errorCount = 0;

        try {
            $db->beginTransaction();

            foreach ($rows as $index => $data) {
                $rowNum = $index + 2; // assuming first data row after header
                $memberData = is_array($data) && array_keys($data) !== range(0, count($data) - 1)
                    ? $data
                    : array_combine($headers, $data);

                // Basic required fields
                if (empty($memberData['first_name']) || empty($memberData['last_name']) || empty($memberData['gender'])) {
                    $errorCount++;
                    $uploadResults[] = [
                        'row' => $rowNum,
                        'name' => trim(($memberData['first_name'] ?? '') . ' ' . ($memberData['last_name'] ?? '')),
                        'status' => 'error',
                        'message' => 'Missing required fields (first_name, last_name, gender).'
                    ];
                    continue;
                }

                // Auto email if empty
                if (empty($memberData['email']) || stripos((string)$memberData['email'], 'leave empty') !== false || stripos((string)$memberData['email'], '@email.com') !== false) {
                    $firstName = strtolower(trim($memberData['first_name']));
                    $lastName = strtolower(trim($memberData['last_name']));
                    $memberData['email'] = $firstName . '.' . $lastName . '@church.auto';
                }

                // Use globally-selected location for ALL rows
                $memberAreaId = $selectedAreaId;
                $memberDistrictId = $selectedDistrictId;
                $memberAssemblyId = $selectedAssemblyId;

                try {
                    // Check if member already exists (same name and DOB)
                    $duplicateCheckStmt = $db->prepare('
                        SELECT id, membershipcard_id FROM members 
                        WHERE first_name = :first_name 
                        AND last_name = :last_name 
                        AND COALESCE(date_of_birth, "0000-00-00") = :date_of_birth
                        LIMIT 1
                    ');
                    $duplicateCheckStmt->execute([
                        'first_name' => $memberData['first_name'],
                        'last_name' => $memberData['last_name'],
                        'date_of_birth' => !empty($memberData['date_of_birth']) ? $memberData['date_of_birth'] : '0000-00-00'
                    ]);
                    
                    if ($existingMember = $duplicateCheckStmt->fetch()) {
                        $errorCount++;
                        $uploadResults[] = [
                            'row' => $rowNum,
                            'name' => $memberData['first_name'] . ' ' . $memberData['last_name'],
                            'status' => 'error',
                            'message' => 'Member already exists in database with card number: ' . $existingMember['membershipcard_id']
                        ];
                        continue;
                    }
                    
                    // Unique membershipcard_id
                    $tempCardGen = new MembershipCard();
                    do {
                        $membershipCardId = $tempCardGen->generateCardNumber();
                        $checkStmt = $db->prepare('SELECT id FROM members WHERE membershipcard_id = :membershipcard_id');
                        $checkStmt->execute(['membershipcard_id' => $membershipCardId]);
                    } while ($checkStmt->fetch());

                    // Unique membership_id
                    do {
                        $membershipId = generateMembershipId();
                        $checkMidStmt = $db->prepare('SELECT id FROM members WHERE membership_id = :membership_id');
                        $checkMidStmt->execute(['membership_id' => $membershipId]);
                    } while ($checkMidStmt->fetch());

                    $stmt = $db->prepare('
                        INSERT INTO members (
                            area_id, district_id, assembly_id, membershipcard_id, membership_id, family_id, title,
                            first_name, middle_name, last_name, gender, date_of_birth,
                            place_of_birth, phone, email, member_type, marital_status,
                            address_line1, gps_address, street_name, city, hometown,
                            water_baptism, date_of_baptism, place_of_baptism, officiating_minister_baptism,
                            officiating_ministers_district, holyghost_baptism, date_of_holyspirit_baptism,
                            communicant, dedicated, dedication_date, name_of_officiating_minister,
                            church_where_dedication_done, date_of_conversion, date_of_joining,
                            occupation, level_of_education, parent_name, parent_relationship,
                            created_by, is_active, created_at
                        ) VALUES (
                            :area_id, :district_id, :assembly_id, :membershipcard_id, :membership_id, :family_id, :title,
                            :first_name, :middle_name, :last_name, :gender, :date_of_birth,
                            :place_of_birth, :phone, :email, :member_type, :marital_status,
                            :address_line1, :gps_address, :street_name, :city, :hometown,
                            :water_baptism, :date_of_baptism, :place_of_baptism, :officiating_minister_baptism,
                            :officiating_ministers_district, :holyghost_baptism, :date_of_holyspirit_baptism,
                            :communicant, :dedicated, :dedication_date, :name_of_officiating_minister,
                            :church_where_dedication_done, :date_of_conversion, :date_of_joining,
                            :occupation, :level_of_education, :parent_name, :parent_relationship,
                            :created_by, 1, NOW()
                        )
                    ');

                    $stmt->execute([
                        'area_id' => $memberAreaId,
                        'district_id' => $memberDistrictId,
                        'assembly_id' => $memberAssemblyId,
                        'membershipcard_id' => $membershipCardId,
                        'membership_id' => $membershipId,
                        'family_id' => !empty($memberData['family_id']) ? $memberData['family_id'] : null,
                        'title' => $memberData['title'] ?? null,
                        'first_name' => $memberData['first_name'],
                        'middle_name' => $memberData['middle_name'] ?? null,
                        'last_name' => $memberData['last_name'],
                        'gender' => $memberData['gender'],
                        'date_of_birth' => !empty($memberData['date_of_birth']) ? $memberData['date_of_birth'] : null,
                        'place_of_birth' => $memberData['place_of_birth'] ?? null,
                        'phone' => $memberData['phone'] ?? null,
                        'email' => $memberData['email'],
                        'member_type' => $memberData['member_type'] ?? 'Full Member',
                        'marital_status' => $memberData['marital_status'] ?? null,
                        'address_line1' => $memberData['address_line1'] ?? null,
                        'gps_address' => $memberData['gps_address'] ?? null,
                        'street_name' => $memberData['street_name'] ?? null,
                        'city' => $memberData['city'] ?? null,
                        'hometown' => $memberData['hometown'] ?? null,
                        'water_baptism' => ($memberData['water_baptism'] ?? '0') == '1' ? 1 : 0,
                        'date_of_baptism' => !empty($memberData['date_of_baptism']) ? $memberData['date_of_baptism'] : null,
                        'place_of_baptism' => $memberData['place_of_baptism'] ?? null,
                        'officiating_minister_baptism' => $memberData['officiating_minister_baptism'] ?? null,
                        'officiating_ministers_district' => $memberData['officiating_ministers_district'] ?? null,
                        'holyghost_baptism' => ($memberData['holyghost_baptism'] ?? '0') == '1' ? 1 : 0,
                        'date_of_holyspirit_baptism' => !empty($memberData['date_of_holyspirit_baptism']) ? $memberData['date_of_holyspirit_baptism'] : null,
                        'communicant' => ($memberData['communicant'] ?? '0') == '1' ? 1 : 0,
                        'dedicated' => ($memberData['dedicated'] ?? '0') == '1' ? 1 : 0,
                        'dedication_date' => !empty($memberData['dedication_date']) ? $memberData['dedication_date'] : null,
                        'name_of_officiating_minister' => $memberData['name_of_officiating_minister'] ?? null,
                        'church_where_dedication_done' => $memberData['church_where_dedication_done'] ?? null,
                        'date_of_conversion' => !empty($memberData['date_of_conversion']) ? $memberData['date_of_conversion'] : null,
                        'date_of_joining' => !empty($memberData['date_of_joining']) ? $memberData['date_of_joining'] : null,
                        'occupation' => $memberData['occupation'] ?? null,
                        'level_of_education' => $memberData['level_of_education'] ?? null,
                        'parent_name' => $memberData['parent_name'] ?? null,
                        'parent_relationship' => $memberData['parent_relationship'] ?? null,
                        'created_by' => $_SESSION['user_id']
                    ]);

                    $newMemberId = $db->lastInsertId();

                    // Tracking code
                    createMemberUserCode($db, $newMemberId, $_SESSION['user_id']);

                    // Card + account
                    try {
                        $membershipCard = new MembershipCard();
                        $cardResult = $membershipCard->createCard($newMemberId);
                        $cardNumber = $cardResult['card_number'] ?? null;

                        try {
                            // Generate unique username to avoid duplicates
                            $baseUsername = strtolower($memberData['first_name']) . '.' . strtolower($memberData['last_name']);
                            $username = $baseUsername;
                            $counter = 1;
                            
                            // Check if username already exists and make it unique
                            do {
                                $checkUsernameStmt = $db->prepare('SELECT id FROM member_accounts WHERE username = :username');
                                $checkUsernameStmt->execute(['username' => $username]);
                                if ($checkUsernameStmt->fetch()) {
                                    $username = $baseUsername . $counter;
                                    $counter++;
                                } else {
                                    break;
                                }
                            } while (true);
                            
                            $defaultPassword = 'Member@' . date('Y');
                            $passwordHash = password_hash($defaultPassword, PASSWORD_DEFAULT);
                            $fullName = trim(($memberData['title'] ?? '') . ' ' . $memberData['first_name'] . ' ' . ($memberData['middle_name'] ?? '') . ' ' . $memberData['last_name']);

                            $accountStmt = $db->prepare('
                                INSERT INTO member_accounts (
                                    member_id, username, email, password_hash, full_name, phone,
                                    access_level, area_id, district_id, assembly_id, is_active
                                ) VALUES (
                                    :member_id, :username, :email, :password_hash, :full_name, :phone,
                                    \'member\', :area_id, :district_id, :assembly_id, 1
                                )
                            ');

                            // Check if email already exists in member_accounts
                            $emailToUse = $memberData['email'];
                            $checkEmailStmt = $db->prepare('SELECT id FROM member_accounts WHERE email = :email');
                            $checkEmailStmt->execute(['email' => $emailToUse]);
                            if ($checkEmailStmt->fetch()) {
                                // Email exists, make it unique by appending member ID
                                $emailParts = explode('@', $emailToUse);
                                $emailToUse = $emailParts[0] . '.' . $newMemberId . '@' . $emailParts[1];
                            }
                            
                            $accountStmt->execute([
                                'member_id' => $newMemberId,
                                'username' => $username,
                                'email' => $emailToUse,
                                'password_hash' => $passwordHash,
                                'full_name' => $fullName,
                                'phone' => $memberData['phone'] ?? null,
                                'area_id' => $memberAreaId,
                                'district_id' => $memberDistrictId,
                                'assembly_id' => $memberAssemblyId
                            ]);

                            $uploadResults[] = [
                                'row' => $rowNum,
                                'name' => $memberData['first_name'] . ' ' . $memberData['last_name'],
                                'status' => 'success',
                                'card_number' => $cardNumber,
                                'message' => 'Member, Card & Account created. Username: ' . $username . ', Password: ' . $defaultPassword
                            ];
                        } catch (Exception $accountError) {
                            error_log('Account creation failed for member ID ' . $newMemberId . ': ' . $accountError->getMessage());
                            $uploadResults[] = [
                                'row' => $rowNum,
                                'name' => $memberData['first_name'] . ' ' . $memberData['last_name'],
                                'status' => 'warning',
                                'card_number' => $cardNumber ?? null,
                                'message' => 'Member & Card created, but account creation failed: ' . $accountError->getMessage()
                            ];
                        }

                        $successCount++;
                    } catch (Exception $cardError) {
                        $uploadResults[] = [
                            'row' => $rowNum,
                            'name' => $memberData['first_name'] . ' ' . $memberData['last_name'],
                            'status' => 'warning',
                            'message' => 'Member created but card generation failed: ' . $cardError->getMessage()
                        ];
                        $successCount++;
                    }
                } catch (Exception $rowError) {
                    $errorCount++;
                    $uploadResults[] = [
                        'row' => $rowNum,
                        'name' => trim(($memberData['first_name'] ?? '') . ' ' . ($memberData['last_name'] ?? '')),
                        'status' => 'error',
                        'message' => $rowError->getMessage()
                    ];
                }
            }

            $db->commit();

            $_SESSION['upload_results'] = $uploadResults;
            $_SESSION['upload_date'] = date('Y-m-d H:i:s');

            unset($_SESSION['special_upload_rows'], $_SESSION['special_upload_headers']);

            $successMessage = "Successfully uploaded {$successCount} members with membership cards and accounts!";
            if ($errorCount > 0) {
                $errorMessage = "{$errorCount} rows had errors and were skipped.";
            }
        } catch (Exception $e) {
            $db->rollBack();
            $errorMessage = 'Special upload failed: ' . $e->getMessage();
        }
    }
}

// Step 1: upload file and store rows in session for preview
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['member_file']) && !isset($_POST['finalize_upload'])) {
    try {
        $file = $_FILES['member_file'];
        if ($file['error'] !== UPLOAD_ERR_OK) {
            throw new Exception('File upload error');
        }
        $fileExt = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        if (!in_array($fileExt, ['csv', 'xlsx', 'xls'])) {
            throw new Exception('Please upload a CSV or Excel file');
        }

        $headers = [];
        $rows = [];

        if ($fileExt === 'csv') {
            $handle = fopen($file['tmp_name'], 'r');
            if ($handle === false) {
                throw new Exception('Could not open file');
            }
            $headers = fgetcsv($handle);
            if ($headers === false) {
                throw new Exception('Could not read file headers');
            }
            $row = 1;
            while (($data = fgetcsv($handle)) !== false) {
                $row++;
                $isEmptyRow = true;
                foreach ($data as $value) {
                    if (trim((string)$value) !== '') {
                        $isEmptyRow = false;
                        break;
                    }
                }
                if ($isEmptyRow) {
                    continue;
                }
                if (isset($data[0]) && stripos((string)$data[0], 'Mr/Mrs') !== false) {
                    continue;
                }
                $rows[] = array_combine($headers, $data);
            }
            fclose($handle);
        } else {
            require_once '../../vendor/autoload.php';
            $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file['tmp_name']);
            $sheet = $spreadsheet->getActiveSheet();
            $allRows = $sheet->toArray();
            if (empty($allRows)) {
                throw new Exception('Excel file is empty');
            }
            $headers = array_shift($allRows);
            $rowNum = 1;
            foreach ($allRows as $data) {
                $rowNum++;
                $isEmptyRow = true;
                foreach ($data as $value) {
                    if (trim((string)$value) !== '') {
                        $isEmptyRow = false;
                        break;
                    }
                }
                if ($isEmptyRow) {
                    continue;
                }
                if (isset($data[0]) && (stripos((string)$data[0], 'Mr/Mrs') !== false || $data[0] == 'Mr')) {
                    continue;
                }
                $rows[] = array_combine($headers, $data);
            }
        }

        if (empty($rows)) {
            throw new Exception('No valid data rows found in file');
        }

        $_SESSION['special_upload_headers'] = $headers;
        $_SESSION['special_upload_rows'] = $rows;
        $successMessage = 'File loaded successfully. Please choose Area, District and Assembly, review preview and click Final Upload.';
    } catch (Exception $e) {
        $errorMessage = 'Failed to load file: ' . $e->getMessage();
    }
}

// Load areas/districts/assemblies for global location selection
$areas = [];
$districts = [];
$assemblies = [];

try {
    $areasQuery = 'SELECT id, area_name FROM areas WHERE is_active = 1';
    if ($accessLevel === 'area' && $areaId) {
        $areasQuery .= ' AND id = ' . (int)$areaId;
    }
    $areasQuery .= ' ORDER BY area_name';
    $areas = $db->query($areasQuery)->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
}

try {
    $districtsStmt = $db->query('SELECT id, district_name, area_id FROM districts WHERE is_active = 1 ORDER BY district_name');
    $districts = $districtsStmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
}

try {
    $assembliesStmt = $db->query('SELECT id, assembly_name, district_id FROM assemblies WHERE is_active = 1 ORDER BY assembly_name');
    $assemblies = $assembliesStmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
}

$previewHeaders = $_SESSION['special_upload_headers'] ?? [];
$previewRows = $_SESSION['special_upload_rows'] ?? [];

include '../../includes/header.php';
include '../../includes/sidebar.php';
?>

<main class="flex-1 md:ml-64 mt-16 min-h-screen bg-gray-50">
    <div class="container mx-auto px-4 py-8">
        <!-- Page Header -->
        <div class="gradient-bg rounded-2xl shadow-2xl p-8 mb-8 text-white">
            <div class="flex items-center justify-between flex-wrap gap-4">
                <div>
                    <h1 class="text-4xl font-bold mb-2">
                        <i class="fas fa-upload mr-3"></i>Special Upload
                    </h1>
                    <p class="text-white/90 text-lg">Bulk import members and force a single Area/District/Assembly for all rows</p>
                </div>
                <div class="flex items-center gap-3">
                    <a href="upload.php" class="px-6 py-3 bg-white/20 hover:bg-white/30 text-white rounded-full font-semibold transition backdrop-blur-sm">
                        <i class="fas fa-arrow-left mr-2"></i>Standard Upload
                    </a>
                    <a href="index.php" class="px-6 py-3 bg-white/20 hover:bg-white/30 text-white rounded-full font-semibold transition backdrop-blur-sm">
                        <i class="fas fa-users mr-2"></i>Back to Members
                    </a>
                </div>
            </div>
        </div>

        <?php if ($successMessage): ?>
            <div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-6 rounded-lg mb-6">
                <div class="flex items-center">
                    <i class="fas fa-check-circle text-3xl mr-4"></i>
                    <div>
                        <p class="font-bold text-lg"><?php echo $successMessage; ?></p>
                    </div>
                </div>
            </div>
        <?php endif; ?>

        <?php if ($errorMessage): ?>
            <div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-6 rounded-lg mb-6">
                <div class="flex items-center">
                    <i class="fas fa-exclamation-circle text-3xl mr-4"></i>
                    <p class="font-bold text-lg"><?php echo $errorMessage; ?></p>
                </div>
            </div>
        <?php endif; ?>

        <?php if (!empty($uploadResults)): ?>
            <div class="bg-white rounded-2xl shadow-lg p-6 mb-8">
                <div class="flex items-center justify-between mb-4">
                    <h3 class="text-2xl font-bold text-gray-800">
                        <i class="fas fa-list-check mr-2 text-gradient"></i>Special Upload Results
                    </h3>
                </div>
                <div class="overflow-x-auto">
                    <table class="w-full">
                        <thead class="bg-gray-100">
                            <tr>
                                <th class="px-4 py-3 text-left text-sm font-semibold text-gray-700">Row</th>
                                <th class="px-4 py-3 text-left text-sm font-semibold text-gray-700">Member Name</th>
                                <th class="px-4 py-3 text-left text-sm font-semibold text-gray-700">Status</th>
                                <th class="px-4 py-3 text-left text-sm font-semibold text-gray-700">Card Number</th>
                                <th class="px-4 py-3 text-left text-sm font-semibold text-gray-700">Message</th>
                            </tr>
                        </thead>
                        <tbody class="divide-y divide-gray-200">
                            <?php foreach ($uploadResults as $result): ?>
                                <tr>
                                    <td class="px-4 py-3 text-sm"><?php echo $result['row']; ?></td>
                                    <td class="px-4 py-3 text-sm font-medium"><?php echo htmlspecialchars($result['name']); ?></td>
                                    <td class="px-4 py-3 text-sm">
                                        <?php if ($result['status'] == 'success'): ?>
                                            <span class="px-3 py-1 rounded-full text-xs font-semibold bg-green-100 text-green-800">
                                                <i class="fas fa-check mr-1"></i>Success
                                            </span>
                                        <?php elseif ($result['status'] == 'warning'): ?>
                                            <span class="px-3 py-1 rounded-full text-xs font-semibold bg-yellow-100 text-yellow-800">
                                                <i class="fas fa-exclamation-triangle mr-1"></i>Warning
                                            </span>
                                        <?php else: ?>
                                            <span class="px-3 py-1 rounded-full text-xs font-semibold bg-red-100 text-red-800">
                                                <i class="fas fa-times mr-1"></i>Error
                                            </span>
                                        <?php endif; ?>
                                    </td>
                                    <td class="px-4 py-3 text-sm font-mono"><?php echo $result['card_number'] ?? '-'; ?></td>
                                    <td class="px-4 py-3 text-sm text-gray-600"><?php echo $result['message'] ?? '-'; ?></td>
                                </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>
                </div>
            </div>
        <?php endif; ?>

        <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
            <!-- Left: Upload file -->
            <div class="bg-white rounded-2xl shadow-lg p-8">
                <h2 class="text-2xl font-bold text-gray-800 mb-6">
                    <i class="fas fa-cloud-upload-alt mr-2 text-green-600"></i>Step 1: Upload File
                </h2>
                <form method="POST" enctype="multipart/form-data" class="space-y-6">
                    <div>
                        <label class="block text-sm font-bold text-gray-700 mb-3">Select CSV or Excel File</label>
                        <div class="border-2 border-dashed border-gray-300 rounded-xl p-8 text-center hover:border-blue-500 transition">
                            <i class="fas fa-file-upload text-5xl text-gray-400 mb-4"></i>
                            <input type="file"
                                   name="member_file"
                                   accept=".csv,.xlsx,.xls"
                                   required
                                   class="block w-full text-sm text-gray-500 file:mr-4 file:py-3 file:px-6 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100 cursor-pointer">
                            <p class="text-sm text-gray-500 mt-2">CSV, XLSX or XLS (Max 10MB)</p>
                        </div>
                    </div>
                    <button type="submit" class="btn-gradient w-full text-white px-8 py-4 rounded-full font-bold text-lg shadow-xl hover:shadow-2xl transition">
                        <i class="fas fa-eye mr-2"></i>Load & Preview
                    </button>
                </form>
            </div>

            <!-- Right: Global location + preview -->
            <div class="bg-white rounded-2xl shadow-lg p-8">
                <h2 class="text-2xl font-bold text-gray-800 mb-4">
                    <i class="fas fa-map-marker-alt mr-2 text-blue-600"></i>Step 2: Set Location & Final Upload
                </h2>
                <p class="text-sm text-gray-600 mb-4">Choose the Area, District and Assembly that should be applied to <strong>all</strong> rows in this upload.</p>

                <form method="POST" class="space-y-4">
                    <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
                        <div>
                            <label class="block text-xs font-semibold text-gray-600 mb-1">Area</label>
                            <select name="area_id" id="areaSelect" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm" required>
                                <option value="">Select Area</option>
                                <?php foreach ($areas as $area): ?>
                                    <option value="<?php echo $area['id']; ?>" <?php echo ($areaId && $areaId == $area['id']) ? 'selected' : ''; ?>>
                                        <?php echo htmlspecialchars($area['area_name']); ?>
                                    </option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                        <div>
                            <label class="block text-xs font-semibold text-gray-600 mb-1">District</label>
                            <select name="district_id" id="districtSelect" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm" required>
                                <option value="">Select District</option>
                                <?php foreach ($districts as $dist): ?>
                                    <option value="<?php echo $dist['id']; ?>" data-area-id="<?php echo $dist['area_id']; ?>" <?php echo ($districtId && $districtId == $dist['id']) ? 'selected' : ''; ?>>
                                        <?php echo htmlspecialchars($dist['district_name']); ?>
                                    </option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                        <div>
                            <label class="block text-xs font-semibold text-gray-600 mb-1">Assembly</label>
                            <select name="assembly_id" id="assemblySelect" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm" required>
                                <option value="">Select Assembly</option>
                                <?php foreach ($assemblies as $asm): ?>
                                    <option value="<?php echo $asm['id']; ?>" data-district-id="<?php echo $asm['district_id']; ?>" <?php echo ($assemblyId && $assemblyId == $asm['id']) ? 'selected' : ''; ?>>
                                        <?php echo htmlspecialchars($asm['assembly_name']); ?>
                                    </option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                    </div>

                    <div class="mt-4">
                        <h3 class="text-sm font-semibold text-gray-800 mb-2">Preview (first 10 rows)</h3>
                        <?php if (empty($previewRows)): ?>
                            <p class="text-xs text-gray-500">Upload a file in Step 1 to see the preview here.</p>
                        <?php else: ?>
                            <div class="border border-gray-200 rounded-lg max-h-64 overflow-auto text-xs">
                                <table class="min-w-full">
                                    <thead class="bg-gray-100">
                                        <tr>
                                            <?php foreach ($previewHeaders as $h): ?>
                                                <th class="px-2 py-1 text-left font-semibold text-gray-700"><?php echo htmlspecialchars($h); ?></th>
                                            <?php endforeach; ?>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <?php $maxPreview = min(10, count($previewRows)); ?>
                                        <?php for ($i = 0; $i < $maxPreview; $i++): $row = $previewRows[$i]; ?>
                                            <tr class="border-t border-gray-100">
                                                <?php foreach ($previewHeaders as $h): ?>
                                                    <td class="px-2 py-1 text-gray-700"><?php echo htmlspecialchars($row[$h] ?? ''); ?></td>
                                                <?php endforeach; ?>
                                            </tr>
                                        <?php endfor; ?>
                                    </tbody>
                                </table>
                            </div>
                        <?php endif; ?>
                    </div>

                    <div class="mt-4">
                        <button type="submit" name="finalize_upload" value="1" class="btn-gradient w-full text-white px-8 py-4 rounded-full font-bold text-lg shadow-xl hover:shadow-2xl transition" <?php echo empty($previewRows) ? 'disabled' : ''; ?>>
                            <i class="fas fa-upload mr-2"></i>Final Upload with Selected Location
                        </button>
                        <?php if (empty($previewRows)): ?>
                            <p class="text-xs text-gray-500 mt-1">Load a file first before final upload.</p>
                        <?php endif; ?>
                    </div>
                </form>
            </div>
        </div>
    </div>

    <script>
    document.addEventListener('DOMContentLoaded', function() {
        var areaSelect = document.getElementById('areaSelect');
        var districtSelect = document.getElementById('districtSelect');
        var assemblySelect = document.getElementById('assemblySelect');

        function filterDistricts() {
            var areaId = areaSelect.value;
            var options = districtSelect.querySelectorAll('option');
            options.forEach(function(opt) {
                if (!opt.dataset.areaId) { opt.style.display = ''; return; }
                if (!areaId || opt.dataset.areaId === areaId) {
                    opt.style.display = '';
                } else {
                    opt.style.display = 'none';
                }
            });
        }

        function filterAssemblies() {
            var districtId = districtSelect.value;
            var options = assemblySelect.querySelectorAll('option');
            options.forEach(function(opt) {
                if (!opt.dataset.districtId) { opt.style.display = ''; return; }
                if (!districtId || opt.dataset.districtId === districtId) {
                    opt.style.display = '';
                } else {
                    opt.style.display = 'none';
                }
            });
        }

        if (areaSelect && districtSelect && assemblySelect) {
            filterDistricts();
            filterAssemblies();
            areaSelect.addEventListener('change', function() {
                districtSelect.value = '';
                assemblySelect.value = '';
                filterDistricts();
                filterAssemblies();
            });
            districtSelect.addEventListener('change', function() {
                assemblySelect.value = '';
                filterAssemblies();
            });
        }
    });
    </script>
</main>

<?php include '../../includes/footer.php'; ?>

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists