<?php

require_once __DIR__ . '/../app/auth.php';
require_once __DIR__ . '/../app/layout.php';
require_once __DIR__ . '/../app/helpers.php';
require_once __DIR__ . '/../app/gallery.php';

$user = sparrow_require_backyard_login();
function sparrow_bulk_gallery_json(array $data, int $status_code = 200): void
{
    http_response_code($status_code);
    header('Content-Type: application/json; charset=utf-8');
    header('Cache-Control: no-store');

    echo json_encode($data, JSON_UNESCAPED_SLASHES);
    exit;
}

function sparrow_bulk_gallery_upload_error(int $error_code): string
{
    return match ($error_code) {
        UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE => 'This image is larger than the server allows.',
        UPLOAD_ERR_PARTIAL => 'The image uploaded only partially. Please try it again.',
        UPLOAD_ERR_NO_FILE => 'No image was received.',
        UPLOAD_ERR_NO_TMP_DIR => 'The server upload folder is unavailable.',
        UPLOAD_ERR_CANT_WRITE => 'The server could not save the image.',
        UPLOAD_ERR_EXTENSION => 'The server stopped this image upload.',
        default => 'The image could not be uploaded.',
    };
}

function sparrow_bulk_gallery_title(string $original_name): string
{
    $title = pathinfo(basename($original_name), PATHINFO_FILENAME);
    $title = preg_replace('/[_-]+/', ' ', $title) ?? $title;
    $title = preg_replace('/\s+/', ' ', $title) ?? $title;
    $title = trim($title);

    return $title !== '' ? $title : 'Untitled Gallery Image';
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = $_POST['action'] ?? '';

    if ($action !== 'upload_gallery_image') {
        sparrow_bulk_gallery_json([
            'success' => false,
            'message' => 'Unknown bulk upload action.',
        ], 400);
    }

    $category = 'Uncategorized';
    $status = sparrow_gallery_normalize_status(trim($_POST['status'] ?? 'Published'));
    $show_public = !empty($_POST['show_public']);

    if (empty($_FILES['gallery_image']) || !is_array($_FILES['gallery_image'])) {
        sparrow_bulk_gallery_json([
            'success' => false,
            'message' => 'No image was received.',
        ], 422);
    }

    $upload = $_FILES['gallery_image'];
    $error_code = (int) ($upload['error'] ?? UPLOAD_ERR_NO_FILE);

    if ($error_code !== UPLOAD_ERR_OK) {
        sparrow_bulk_gallery_json([
            'success' => false,
            'message' => sparrow_bulk_gallery_upload_error($error_code),
        ], 422);
    }

    $tmp_name = (string) ($upload['tmp_name'] ?? '');
    $original_name = (string) ($upload['name'] ?? '');

    if ($tmp_name === '' || $original_name === '' || !is_uploaded_file($tmp_name)) {
        sparrow_bulk_gallery_json([
            'success' => false,
            'message' => 'The uploaded image could not be verified.',
        ], 422);
    }

    $allowed_mime_types = [
        'image/jpeg' => 'jpg',
        'image/png' => 'png',
        'image/gif' => 'gif',
        'image/webp' => 'webp',
    ];

    $file_info = new finfo(FILEINFO_MIME_TYPE);
    $mime_type = (string) $file_info->file($tmp_name);

    if (!isset($allowed_mime_types[$mime_type])) {
        sparrow_bulk_gallery_json([
            'success' => false,
            'message' => 'Only JPG, PNG, GIF, and WebP images are allowed.',
        ], 422);
    }

    if (@getimagesize($tmp_name) === false) {
        sparrow_bulk_gallery_json([
            'success' => false,
            'message' => 'This file does not appear to be a valid image.',
        ], 422);
    }

    $title = sparrow_bulk_gallery_title($original_name);
    $upload_dir = dirname(__DIR__) . '/storage/gallery/';
    $stored_file = '';
    $pdo = sparrow_db();

    try {
        if (!is_dir($upload_dir) && !mkdir($upload_dir, 0755, true) && !is_dir($upload_dir)) {
            throw new RuntimeException('The gallery storage folder could not be created.');
        }

        $pdo->beginTransaction();

        $gallery_item_id = sparrow_save_gallery_item([
            'title' => $title,
            'category' => $category,
            'description' => '',
            'featured' => 0,
            'show_public' => $show_public ? 1 : 0,
            'status' => $status,
            'sort_order' => 0,
        ]);

        $extension = $allowed_mime_types[$mime_type];
        $file_name = 'gallery-' . $gallery_item_id . '-' . time() . '-' . bin2hex(random_bytes(4)) . '.' . $extension;
        $stored_file = $upload_dir . $file_name;
        $image_path = '/storage/gallery/' . $file_name;

        if (!move_uploaded_file($tmp_name, $stored_file)) {
            throw new RuntimeException('The image could not be moved into gallery storage.');
        }

        sparrow_add_gallery_image(
            $gallery_item_id,
            $image_path,
            $title,
            true
        );

        $pdo->commit();

        sparrow_bulk_gallery_json([
            'success' => true,
            'item_id' => $gallery_item_id,
            'title' => $title,
            'category' => $category,
            'status' => $status,
            'show_public' => $show_public,
            'image_url' => sparrow_url($image_path),
            'edit_url' => sparrow_url('/backyard/gallery-edit.php?id=' . $gallery_item_id),
        ]);
    } catch (Throwable $e) {
        if ($pdo->inTransaction()) {
            $pdo->rollBack();
        }

        if ($stored_file !== '' && is_file($stored_file)) {
            @unlink($stored_file);
        }

        error_log('Sparrow gallery bulk upload failed: ' . $e->getMessage());

        sparrow_bulk_gallery_json([
            'success' => false,
            'message' => 'The image could not be saved. Please try it again.',
        ], 500);
    }
}

sparrow_backyard_header('Bulk Upload Gallery Images');

?>

<style>
    .gallery-bulk-options {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 16px;
        align-items: end;
    }

    .gallery-bulk-public {
        display: inline-flex;
        align-items: center;
        gap: 9px;
        min-height: 44px;
        margin: 0;
        cursor: pointer;
    }

    .gallery-bulk-public input[type="checkbox"] {
        width: 18px;
        height: 18px;
        min-width: 18px;
        margin: 0;
        padding: 0;
        accent-color: var(--sparrow-purple);
    }

    .gallery-bulk-picker {
        margin-top: 20px;
        padding: 18px;
        border: 1px dashed var(--sparrow-border);
        border-radius: 18px;
        background: #fff8fc;
    }

    .gallery-bulk-picker input[type="file"] {
        width: 100%;
    }

    .gallery-bulk-summary {
        display: flex;
        gap: 10px;
        flex-wrap: wrap;
        align-items: center;
        margin: 18px 0 0;
    }

    .gallery-bulk-grid {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
        gap: 16px;
        margin-top: 18px;
    }

    .gallery-bulk-card {
        overflow: hidden;
        border: 1px solid var(--sparrow-border);
        border-radius: 18px;
        background: #fffbfd;
        padding: 12px;
    }

    .gallery-bulk-card.is-uploading {
        border-color: #d5bced;
        box-shadow: 0 0 0 3px rgba(151, 102, 189, 0.08);
    }

    .gallery-bulk-card.is-complete {
        border-color: #b9dfc3;
        background: #f8fff9;
    }

    .gallery-bulk-card.is-failed {
        border-color: #efb9b9;
        background: #fff8f8;
    }

    .gallery-bulk-card img {
        display: block;
        width: 100%;
        height: 180px;
        object-fit: cover;
        border: 1px solid var(--sparrow-border);
        border-radius: 14px;
        background: #ffffff;
        margin-bottom: 10px;
    }

    .gallery-bulk-title {
        display: block;
        overflow-wrap: anywhere;
        color: var(--sparrow-purple-dark);
    }

    .gallery-bulk-status {
        min-height: 34px;
        margin: 7px 0 0;
        color: var(--sparrow-muted);
        font-size: 12px;
        line-height: 1.35;
    }

    .gallery-bulk-card.is-complete .gallery-bulk-status {
        color: #276738;
    }

    .gallery-bulk-card.is-failed .gallery-bulk-status {
        color: #8a2525;
    }

    .gallery-bulk-edit {
        display: none;
        margin-top: 10px;
    }

    .gallery-bulk-card.is-complete .gallery-bulk-edit {
        display: inline-flex;
    }

    @media (max-width: 760px) {
        .gallery-bulk-options {
            grid-template-columns: 1fr;
        }
    }
</style>

<section class="card">
    <div class="page-heading-row">
        <div>
            <h1>Bulk Upload Gallery Images</h1>
            <p class="muted">
                Each selected image will become its own gallery item.
            </p>
        </div>

        <div class="heading-actions">
            <a class="button button-secondary" href="<?php echo sparrow_escape(sparrow_url('/backyard/gallery.php')); ?>">
                Back to Gallery
            </a>
        </div>
    </div>
</section>

<section class="card">
    <h2>Batch Settings</h2>

    <p class="muted">
        The filename will be used as the temporary title. New images will be marked Uncategorized so you can choose each category from its Edit Item page.
    </p>

    <div class="gallery-bulk-options">
        <div>
            <label for="bulk_status">Status</label>
            <select id="bulk_status">
                <?php foreach (['Published', 'Draft', 'Hidden'] as $status): ?>
                    <option value="<?php echo sparrow_escape($status); ?>">
                        <?php echo sparrow_escape($status); ?>
                    </option>
                <?php endforeach; ?>
            </select>
        </div>

        <label class="gallery-bulk-public">
            <input type="checkbox" id="bulk_show_public" value="1" checked>
            <span>Show on public website</span>
        </label>
    </div>

    <div class="gallery-bulk-picker">
        <label for="bulk_gallery_images">Choose Gallery Images</label>
        <input
            type="file"
            id="bulk_gallery_images"
            accept="image/jpeg,image/png,image/gif,image/webp"
            multiple
        >

        <p class="muted">
            For a large gallery, upload manageable groups such as 20–40 images at a time.
        </p>
    </div>

    <div class="gallery-bulk-summary" aria-live="polite">
        <span class="gallery-pill" id="bulk_selected_count">0 selected</span>
        <span class="gallery-pill gallery-pill-green" id="bulk_uploaded_count">0 uploaded</span>
        <span class="gallery-pill gallery-pill-muted" id="bulk_failed_count">0 failed</span>

        <button type="button" class="button" id="bulk_upload_button" disabled>
            Upload Selected Images
        </button>
    </div>

    <div id="bulk_upload_notice" class="notice-success" hidden></div>
    <div id="bulk_gallery_grid" class="gallery-bulk-grid"></div>
</section>

<script>
document.addEventListener('DOMContentLoaded', function () {
    const fileInput = document.getElementById('bulk_gallery_images');
    const statusInput = document.getElementById('bulk_status');
    const showPublicInput = document.getElementById('bulk_show_public');
    const uploadButton = document.getElementById('bulk_upload_button');
    const grid = document.getElementById('bulk_gallery_grid');
    const selectedCount = document.getElementById('bulk_selected_count');
    const uploadedCount = document.getElementById('bulk_uploaded_count');
    const failedCount = document.getElementById('bulk_failed_count');
    const notice = document.getElementById('bulk_upload_notice');
    const endpoint = <?php echo json_encode(sparrow_url('/backyard/gallery-bulk-upload.php')); ?>;

    let entries = [];
    let uploadInProgress = false;

    function titleFromFilename(filename) {
        const withoutExtension = filename.replace(/\.[^.]+$/, '');
        const cleaned = withoutExtension.replace(/[_-]+/g, ' ').replace(/\s+/g, ' ').trim();

        return cleaned || 'Untitled Gallery Image';
    }

    function updateCounts() {
        const uploaded = entries.filter(entry => entry.state === 'complete').length;
        const failed = entries.filter(entry => entry.state === 'failed').length;

        selectedCount.textContent = entries.length + ' selected';
        uploadedCount.textContent = uploaded + ' uploaded';
        failedCount.textContent = failed + ' failed';
    }

    function buildCard(entry) {
        const card = document.createElement('article');
        card.className = 'gallery-bulk-card';

        const image = document.createElement('img');
        image.src = entry.previewUrl;
        image.alt = titleFromFilename(entry.file.name);

        const title = document.createElement('strong');
        title.className = 'gallery-bulk-title';
        title.textContent = titleFromFilename(entry.file.name);

        const status = document.createElement('p');
        status.className = 'gallery-bulk-status';
        status.textContent = 'Waiting to upload';

        const editLink = document.createElement('a');
        editLink.className = 'button button-secondary gallery-bulk-edit';
        editLink.textContent = 'Edit Item';

        card.append(image, title, status, editLink);

        entry.card = card;
        entry.image = image;
        entry.title = title;
        entry.status = status;
        entry.editLink = editLink;

        grid.appendChild(card);
    }

    function clearEntries() {
        entries.forEach(function (entry) {
            if (entry.previewUrl) {
                URL.revokeObjectURL(entry.previewUrl);
            }
        });

        entries = [];
        grid.innerHTML = '';
        notice.hidden = true;
        notice.textContent = '';
        updateCounts();
    }

    fileInput.addEventListener('change', function () {
        if (uploadInProgress) {
            return;
        }

        clearEntries();

        entries = Array.from(fileInput.files).map(function (file) {
            return {
                file: file,
                previewUrl: URL.createObjectURL(file),
                state: 'waiting'
            };
        });

        entries.forEach(buildCard);
        uploadButton.disabled = entries.length === 0;
        updateCounts();
    });

    async function uploadOne(entry) {
        entry.state = 'uploading';
        entry.card.classList.add('is-uploading');
        entry.status.textContent = 'Uploading...';

        const formData = new FormData();
        formData.append('action', 'upload_gallery_image');
        formData.append('gallery_image', entry.file);
        formData.append('status', statusInput.value);
        formData.append('show_public', showPublicInput.checked ? '1' : '0');

        try {
            const response = await fetch(endpoint, {
                method: 'POST',
                body: formData,
                credentials: 'same-origin'
            });

            const contentType = response.headers.get('content-type') || '';

            if (!contentType.includes('application/json')) {
                throw new Error('The server did not return an upload response. Your login may have expired.');
            }

            const result = await response.json();

            if (!response.ok || !result.success) {
                throw new Error(result.message || 'Image could not be uploaded.');
            }

            entry.state = 'complete';
            entry.card.classList.remove('is-uploading');
            entry.card.classList.add('is-complete');
            entry.image.src = result.image_url;
            entry.image.alt = result.title;
            entry.title.textContent = result.title;
            entry.status.textContent = 'Uploaded as ' + result.category + ' · ' + result.status;
            entry.editLink.href = result.edit_url;

            if (entry.previewUrl) {
                URL.revokeObjectURL(entry.previewUrl);
                entry.previewUrl = '';
            }
        } catch (error) {
            entry.state = 'failed';
            entry.card.classList.remove('is-uploading');
            entry.card.classList.add('is-failed');
            entry.status.textContent = error.message || 'Image could not be uploaded.';
        }

        updateCounts();
    }

    async function uploadWorker(queue) {
        while (queue.length > 0) {
            const entry = queue.shift();

            if (entry) {
                await uploadOne(entry);
            }
        }
    }

    uploadButton.addEventListener('click', async function () {
        if (uploadInProgress || entries.length === 0) {
            return;
        }

        uploadInProgress = true;
        uploadButton.disabled = true;
        fileInput.disabled = true;
        statusInput.disabled = true;
        showPublicInput.disabled = true;
        notice.hidden = true;

        const queue = entries.filter(entry => entry.state === 'waiting');
        const workerCount = Math.min(3, queue.length);
        const workers = [];

        for (let index = 0; index < workerCount; index += 1) {
            workers.push(uploadWorker(queue));
        }

        await Promise.all(workers);

        uploadInProgress = false;
        fileInput.disabled = false;
        statusInput.disabled = false;
        showPublicInput.disabled = false;

        const uploaded = entries.filter(entry => entry.state === 'complete').length;
        const failed = entries.filter(entry => entry.state === 'failed').length;

        notice.className = failed > 0 ? 'notice-error' : 'notice-success';
        notice.textContent = failed > 0
            ? uploaded + ' image(s) uploaded and ' + failed + ' failed. Failed images can be selected again in a new batch.'
            : 'All ' + uploaded + ' images uploaded successfully.';
        notice.hidden = false;
    });
});
</script>

<?php sparrow_backyard_footer(); ?>
