<div class="mb-6 flex items-center gap-3" x-data="backupRestoreUploader()">
    <!-- Backup All Button -->
    <x-jetstream.secondary-button wire:click="backup" wire:loading.attr="disabled">
        <x-icon class="mr-2 h-4 w-4" name="archive-box" />
        <span wire:loading.remove wire:target="backup">{{ __('Backup all') }}</span>
        <span wire:loading wire:target="backup">{{ __('Creating backup...') }}</span>
    </x-jetstream.secondary-button>

    <!-- Backup Selected Button (optional) -->
    @if ($showBackupSelected)
        <x-jetstream.secondary-button
            wire:click="backupSelected"
            wire:loading.attr="disabled"
            :disabled="empty($selectedTranslationIds)"
            class="{{ empty($selectedTranslationIds) ? 'opacity-50 cursor-not-allowed' : '' }}">
            <x-icon class="mr-2 h-4 w-4" name="arrow-down-tray" />
            <span wire:loading.remove wire:target="backupSelected">
                {{ __('Backup selected') }}
                @if (!empty($selectedTranslationIds))
                    ({{ count($selectedTranslationIds) }})
                @endif
            </span>
            <span wire:loading wire:target="backupSelected">{{ __('Creating backup...') }}</span>
        </x-jetstream.secondary-button>
    @endif

    <!-- Restore Button -->
    <x-jetstream.secondary-button wire:click="openRestoreModal">
        <x-icon class="mr-2 h-4 w-4" name="arrow-up-tray" />
        {{ __('Restore') }}
    </x-jetstream.secondary-button>

    <!-- Restore Modal -->
    <x-jetstream.dialog-modal wire:model.live="showRestoreModal" maxWidth="2xl">
        <x-slot name="title">
            {{ __('Restore Posts') }}
        </x-slot>

        <x-slot name="content">
            @if (empty($restoreStats))
                <!-- File Upload -->
                <div class="mb-6">
                    <label class="block text-sm font-medium text-gray-700 mb-2">
                        {{ __('Select backup file') }}
                    </label>
                    <input type="file"
                           x-ref="fileInput"
                           x-on:change="handleFileSelected($event)"
                           accept=".json,.zip"
                           :disabled="parsing || uploading"
                           class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-theme-brand file:text-white hover:file:bg-opacity-80">
                    <p class="mt-1 text-xs text-gray-500">
                        {{ __('Accepts ZIP archives (with media) or JSON files (without media)') }}
                    </p>
                    @error('restoreFile')
                        <p class="mt-1 text-sm text-red-600">{{ $message }}</p>
                    @enderror

                    <!-- Parsing indicator -->
                    <div x-show="parsing" x-cloak class="mt-2 text-sm text-gray-500">
                        {{ __('Reading file...') }}
                    </div>

                    <!-- Parse error -->
                    <template x-if="parseError">
                        <p class="mt-1 text-sm text-red-600" x-text="parseError"></p>
                    </template>

                    <!-- Upload progress bar -->
                    <div x-show="uploading" x-cloak class="mt-3">
                        <div class="flex items-center justify-between text-sm text-gray-600 mb-1">
                            <span>{{ __('Uploading...') }}</span>
                            <span x-text="uploadProgress + '%'"></span>
                        </div>
                        <div class="w-full bg-gray-200 rounded-full h-2">
                            <div class="bg-theme-brand h-2 rounded-full transition-all duration-300"
                                 :style="'width: ' + uploadProgress + '%'"></div>
                        </div>
                        <p class="mt-1 text-xs text-gray-500" x-text="uploadStatus"></p>
                    </div>

                    <!-- Upload error -->
                    <template x-if="uploadError">
                        <p class="mt-2 text-sm text-red-600" x-text="uploadError"></p>
                    </template>
                </div>

                <!-- Preview -->
                @if (!empty($restorePreview))
                    <div class="mb-6 p-4 bg-gray-50 rounded-lg">
                        <h4 class="font-semibold text-gray-700 mb-3">{{ __('Backup file info') }}</h4>
                        <dl class="grid grid-cols-2 gap-2 text-sm">
                            <dt class="text-gray-500">{{ __('Source') }}:</dt>
                            <dd class="text-gray-900">{{ $restorePreview['source_database'] }}</dd>

                            <dt class="text-gray-500">{{ __('Created') }}:</dt>
                            <dd class="text-gray-900">{{ \Carbon\Carbon::parse($restorePreview['created_at'])->format('Y-m-d H:i') }}</dd>

                            <dt class="text-gray-500">{{ __('Posts') }}:</dt>
                            <dd class="text-gray-900">{{ $restorePreview['posts'] }}</dd>

                            <dt class="text-gray-500">{{ __('Translations') }}:</dt>
                            <dd class="text-gray-900">{{ $restorePreview['translations'] }}</dd>

                            <dt class="text-gray-500">{{ __('Meetings') }}:</dt>
                            <dd class="text-gray-900">{{ $restorePreview['meetings'] }}</dd>

                            @if (!empty($restorePreview['includes_media']))
                                <dt class="text-gray-500">{{ __('Media files') }}:</dt>
                                <dd class="text-gray-900">{{ $restorePreview['media_files'] ?? 0 }}</dd>
                            @endif

                            <dt class="text-gray-500">{{ __('Format') }}:</dt>
                            <dd class="text-gray-900">
                                @if (!empty($restorePreview['is_zip']))
                                    <span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-green-100 text-green-800">
                                        ZIP {{ __('with media') }}
                                    </span>
                                @else
                                    <span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-gray-100 text-gray-800">
                                        JSON {{ __('without media') }}
                                    </span>
                                @endif
                            </dd>
                        </dl>

                        @if ($restorePreview['duplicates'] > 0)
                            <div class="mt-4 p-3 bg-yellow-50 border border-yellow-200 rounded-md">
                                <div class="flex items-start">
                                    <x-icon name="exclamation-triangle" class="h-5 w-5 text-yellow-600 mr-2 flex-shrink-0" />
                                    <div>
                                        <p class="text-sm font-medium text-yellow-800">
                                            {{ __(':count duplicate slug(s) found', ['count' => $restorePreview['duplicates']]) }}
                                        </p>
                                        @if (!empty($restorePreview['duplicate_slugs']))
                                            <p class="mt-1 text-xs text-yellow-700">
                                                {{ implode(', ', $restorePreview['duplicate_slugs']) }}
                                                @if ($restorePreview['duplicates'] > 10)
                                                    ...
                                                @endif
                                            </p>
                                        @endif
                                    </div>
                                </div>

                                <div class="mt-3">
                                    <label class="block text-sm font-medium text-yellow-800 mb-2">
                                        {{ __('How to handle duplicates?') }}
                                    </label>
                                    <div class="space-y-2">
                                        <label class="flex items-center">
                                            <input type="radio" wire:model="duplicateAction" value="skip"
                                                   class="text-theme-brand focus:ring-theme-brand">
                                            <span class="ml-2 text-sm text-yellow-800">{{ __('Skip duplicates') }}</span>
                                        </label>
                                        <label class="flex items-center">
                                            <input type="radio" wire:model="duplicateAction" value="overwrite"
                                                   class="text-theme-brand focus:ring-theme-brand">
                                            <span class="ml-2 text-sm text-yellow-800">{{ __('Overwrite existing') }}</span>
                                        </label>
                                    </div>
                                </div>
                            </div>
                        @endif
                    </div>

                    {{-- Post selection list --}}
                    @if (!empty($restorePostList))
                        <div class="mb-6">
                            <div class="flex items-center justify-between mb-3">
                                <h4 class="font-semibold text-gray-700">{{ __('Select posts to restore') }}</h4>
                                <label class="flex items-center space-x-2 text-sm text-gray-600 cursor-pointer">
                                    <input type="checkbox"
                                           wire:model.live="selectAllPosts"
                                           wire:change="toggleSelectAll"
                                           class="rounded border-gray-300 text-theme-brand focus:ring-theme-brand">
                                    <span>{{ __('Select all') }} ({{ count($selectedPostIndices) }}/{{ count($restorePostList) }})</span>
                                </label>
                            </div>

                            <div class="max-h-64 overflow-y-auto border border-gray-200 rounded-lg">
                                @foreach ($restorePostList as $postItem)
                                    <label class="flex items-start px-4 py-3 hover:bg-gray-50 cursor-pointer border-b border-gray-100 last:border-b-0">
                                        <input type="checkbox"
                                               wire:model.live="selectedPostIndices"
                                               value="{{ $postItem['index'] }}"
                                               class="mt-0.5 rounded border-gray-300 text-theme-brand focus:ring-theme-brand">
                                        <div class="ml-3 min-w-0 flex-1">
                                            <div class="text-sm font-medium text-gray-900 truncate">
                                                {{ $postItem['title'] }}
                                            </div>
                                            <div class="text-xs text-gray-500 flex items-center flex-wrap gap-x-3 gap-y-1 mt-1">
                                                <span class="truncate">{{ $postItem['slug'] }}</span>
                                                <span>{{ implode(', ', $postItem['locales']) }}</span>
                                                @if ($postItem['has_meeting'])
                                                    <span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs bg-blue-100 text-blue-700">
                                                        {{ __('Meeting') }}
                                                    </span>
                                                @endif
                                                @if ($postItem['has_media'])
                                                    <span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs bg-green-100 text-green-700">
                                                        {{ __('Media') }}
                                                    </span>
                                                @endif
                                            </div>
                                        </div>
                                    </label>
                                @endforeach
                            </div>
                        </div>
                    @endif

                    <p class="text-sm text-gray-500">
                        {{ __('Posts will be assigned to your current active profile.') }}
                    </p>
                @endif
            @else
                <!-- Restore Results -->
                <div class="p-4 bg-green-50 border border-green-200 rounded-lg">
                    <div class="flex items-center mb-3">
                        <x-icon name="check-circle" class="h-6 w-6 text-green-600 mr-2" />
                        <h4 class="font-semibold text-green-800">{{ __('Restore completed') }}</h4>
                    </div>
                    <dl class="grid grid-cols-2 gap-2 text-sm">
                        <dt class="text-green-700">{{ __('Posts created') }}:</dt>
                        <dd class="text-green-900 font-medium">{{ $restoreStats['posts_created'] ?? 0 }}</dd>

                        @if (($restoreStats['posts_skipped'] ?? 0) > 0)
                            <dt class="text-yellow-700">{{ __('Posts skipped') }}:</dt>
                            <dd class="text-yellow-900 font-medium">{{ $restoreStats['posts_skipped'] }}</dd>
                        @endif

                        @if (($restoreStats['posts_overwritten'] ?? 0) > 0)
                            <dt class="text-orange-700">{{ __('Posts overwritten') }}:</dt>
                            <dd class="text-orange-900 font-medium">{{ $restoreStats['posts_overwritten'] }}</dd>
                        @endif

                        <dt class="text-green-700">{{ __('Translations created') }}:</dt>
                        <dd class="text-green-900 font-medium">{{ $restoreStats['translations_created'] ?? 0 }}</dd>

                        <dt class="text-green-700">{{ __('Meetings created') }}:</dt>
                        <dd class="text-green-900 font-medium">{{ $restoreStats['meetings_created'] ?? 0 }}</dd>

                        @if (($restoreStats['media_restored'] ?? 0) > 0)
                            <dt class="text-green-700">{{ __('Media restored') }}:</dt>
                            <dd class="text-green-900 font-medium">{{ $restoreStats['media_restored'] }}</dd>
                        @endif

                        @if (($restoreStats['media_skipped'] ?? 0) > 0)
                            <dt class="text-yellow-700">{{ __('Media skipped') }}:</dt>
                            <dd class="text-yellow-900 font-medium">{{ $restoreStats['media_skipped'] }}</dd>
                        @endif
                    </dl>
                </div>
            @endif
        </x-slot>

        <x-slot name="footer">
            <x-jetstream.secondary-button wire:click="closeRestoreModal">
                {{ empty($restoreStats) ? __('Cancel') : __('Close') }}
            </x-jetstream.secondary-button>

            @if (empty($restoreStats) && !empty($restorePreview))
                <x-jetstream.button
                    class="ml-3"
                    x-on:click="startChunkedUpload()"
                    x-bind:disabled="uploading || restoring"
                    wire:loading.attr="disabled"
                    wire:target="restore"
                    :disabled="$isRestoring || empty($selectedPostIndices)">
                    <span x-show="!uploading && !restoring" wire:loading.remove wire:target="restore">
                        {{ __('Restore') }} ({{ count($selectedPostIndices) }})
                    </span>
                    <span x-show="uploading" x-cloak>{{ __('Uploading...') }}</span>
                    <span x-show="restoring" x-cloak wire:loading wire:target="restore">{{ __('Restoring...') }}</span>
                </x-jetstream.button>
            @endif
        </x-slot>
    </x-jetstream.dialog-modal>
</div>

@script
<script>
    Alpine.data('backupRestoreUploader', () => ({
        file: null,
        isZip: false,
        parsing: false,
        parseError: null,
        uploading: false,
        uploadProgress: 0,
        uploadStatus: '',
        uploadError: null,
        restoring: false,

        resetState() {
            this.file = null;
            this.isZip = false;
            this.parsing = false;
            this.parseError = null;
            this.uploading = false;
            this.uploadProgress = 0;
            this.uploadStatus = '';
            this.uploadError = null;
            this.restoring = false;
            if (this.$refs.fileInput) {
                this.$refs.fileInput.value = '';
            }
        },

        async handleFileSelected(event) {
            const file = event.target.files[0];
            if (!file) return;

            this.file = file;
            this.parseError = null;
            this.uploadError = null;
            this.parsing = true;

            const ext = file.name.split('.').pop().toLowerCase();

            if (ext !== 'json' && ext !== 'zip') {
                this.parseError = '{{ __("Only .json and .zip files are accepted") }}';
                this.parsing = false;
                return;
            }

            this.isZip = ext === 'zip';

            try {
                let jsonString;

                if (this.isZip) {
                    // Use JSZip to extract backup.json client-side
                    const JSZip = await window.loadJSZip();
                    const zip = await JSZip.loadAsync(file);
                    const backupEntry = zip.file('backup.json');

                    if (!backupEntry) {
                        this.parseError = '{{ __("Invalid ZIP archive: missing backup.json") }}';
                        this.parsing = false;
                        return;
                    }

                    jsonString = await backupEntry.async('string');
                } else {
                    // Read JSON file directly
                    jsonString = await file.text();
                }

                // Parse JSON client-side and extract only lightweight summary data
                const data = JSON.parse(jsonString);

                if (!data.meta || !data.posts) {
                    this.parseError = '{{ __("Invalid backup file format") }}';
                    this.parsing = false;
                    return;
                }

                const baseLocale = '{{ config("app.locale") }}';
                const postSummaries = data.posts.map((post, index) => {
                    let title = null;
                    let slug = null;
                    const locales = [];
                    const slugs = [];

                    (post.translations || []).forEach(t => {
                        locales.push(t.locale);
                        slugs.push(t.slug);
                        if (t.locale === baseLocale) {
                            title = t.title;
                            slug = t.slug;
                        }
                    });

                    // Fallback to first translation
                    if (title === null && post.translations && post.translations.length > 0) {
                        title = post.translations[0].title;
                        slug = post.translations[0].slug;
                    }

                    return {
                        index: index,
                        title: title || '{{ __("Untitled") }}',
                        slug: slug || '',
                        locales: locales,
                        slugs: slugs,
                        has_meeting: !!post.meeting,
                        has_media: !!post.media,
                        category_type: post.category_type || null,
                    };
                });

                // Send only meta + lightweight summaries to Livewire (a few KB, not MB)
                await $wire.parseBackupPreview(data.meta, postSummaries, file.name, this.isZip);

            } catch (e) {
                this.parseError = '{{ __("Error reading file: ") }}' + e.message;
            }

            this.parsing = false;
        },

        async startChunkedUpload() {
            if (!this.file || this.uploading || this.restoring) return;

            this.uploading = true;
            this.uploadError = null;
            this.uploadProgress = 0;

            const chunkSize = 2 * 1024 * 1024; // 2MB chunks
            const totalChunks = Math.ceil(this.file.size / chunkSize);
            const uploadId = crypto.randomUUID();
            const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content;

            try {
                // Upload chunks sequentially
                for (let i = 0; i < totalChunks; i++) {
                    const start = i * chunkSize;
                    const end = Math.min(start + chunkSize, this.file.size);
                    const chunk = this.file.slice(start, end);

                    const formData = new FormData();
                    formData.append('uploadId', uploadId);
                    formData.append('chunkIndex', i);
                    formData.append('totalChunks', totalChunks);
                    formData.append('chunk', chunk, 'chunk');

                    this.uploadStatus = `{{ __("Chunk") }} ${i + 1} / ${totalChunks}`;

                    const response = await window.axios.post(
                        '{{ route("posts.backup-upload-chunk") }}',
                        formData,
                        {
                            headers: {
                                'X-CSRF-TOKEN': csrfToken,
                                'Content-Type': 'multipart/form-data',
                            }
                        }
                    );

                    if (!response.data.success) {
                        throw new Error(response.data.error || 'Chunk upload failed');
                    }

                    this.uploadProgress = Math.round(((i + 1) / totalChunks) * 90);
                }

                // Finalize - reassemble chunks on server
                this.uploadStatus = '{{ __("Finalizing...") }}';
                const finalizeResponse = await window.axios.post(
                    '{{ route("posts.backup-upload-finalize") }}',
                    {
                        uploadId: uploadId,
                        totalChunks: totalChunks,
                        fileName: this.file.name,
                    },
                    {
                        headers: {
                            'X-CSRF-TOKEN': csrfToken,
                        }
                    }
                );

                if (!finalizeResponse.data.success) {
                    throw new Error(finalizeResponse.data.error || 'Finalization failed');
                }

                this.uploadProgress = 95;
                this.uploadStatus = '{{ __("Restoring posts...") }}';

                // Tell Livewire to pick up the assembled file
                await $wire.setUploadedFilePath(uploadId);

                this.uploading = false;
                this.restoring = true;

                // Trigger the actual restore
                await $wire.restore();

                this.restoring = false;
                this.uploadProgress = 100;

            } catch (e) {
                this.uploading = false;
                this.restoring = false;

                const msg = e.response?.data?.error || e.response?.data?.message || e.message;
                this.uploadError = '{{ __("Upload failed: ") }}' + msg;
            }
        },
    }));

    $wire.on('backup-ready', ({ filename }) => {
        // Redirect browser to the dedicated download route (bypasses Livewire response buffering)
        window.location.href = '{{ route("posts.backup-download", ["filename" => "__FILENAME__"]) }}'.replace('__FILENAME__', filename);
    });
</script>
@endscript
