import JSZip from 'jszip';
import $, {ajax} from "jquery";
import Dropzone from 'dropzone';

interface DropzoneFileWithServerId extends Dropzone.DropzoneFile {
    serverId?: string;
}

$(function () {
    $(".dz-button").removeClass("dz-button").addClass("btn btn-light dz-cust");
    $('#submitbutton').prop("disabled", true);

    if (window.location.href.indexOf("/de/") > -1) {
        $(".dz-cust").html("<i class=\"icofont-plus-circle f-22\"></i> <span style='font-size: 26px'> Dateien hochladen</span>");
    }

    if (window.location.href.indexOf("/en/") > -1) {
        $(".dz-cust").html("<i class=\"icofont-plus-circle f-22\"></i> <span style='font-size: 22px'> Upload Files</span>");
    }

    if (window.location.href.indexOf("/es/") > -1) {
        $(".dz-cust").html("<i class=\"icofont-plus-circle f-22\"></i> <span style='font-size: 26px'> Cargar archivos</span>");
    }

    if (window.location.href.indexOf("/ru/") > -1) {
        $(".dz-cust").html("<i class=\"icofont-plus-circle f-22\"></i> <span style='font-size: 26px'> Загрузка файлов</span>");
    }

    $('#shared_file_contact').on('change', function () {
        checkFormState();
    });

    $('#chooseUserFree').on('input', function () {
        checkFormState();
    });

    $('#shared_file_title, #shared_file_message').on('input', function () {
        checkFormState();
    });

    $('#shared_file_contactEmail').on('input', function () {
        checkFormState();
    });
})

const license: string = $('#aLXq676F8V6arDsukGLrsnKkdvc7Jv5TKu9F6aSWaVaVaujkmF').val() as string

let maxFilesizeVal = 200000;
let maxFilesizeValShow = Number(maxFilesizeVal / 1000) + ' GB'
if (license == 'o9zZ') {
    maxFilesizeVal = 200000
    maxFilesizeValShow = Number(maxFilesizeVal / 1000) + ' GB'
}
$('#maxUploadSize').text(maxFilesizeValShow)

// @ts-ignore
Dropzone.options.docUpload = {
    // Chunking configuration
    chunking: true,
    forceChunking: true,
    chunkSize: 52428800, // 50 MB
    parallelChunkUploads: false,
    retryChunks: true,
    retryChunksLimit: 3,

    // Other settings
    maxFilesize: maxFilesizeVal,
    addRemoveLinks: true,
    timeout: 300000, // 5 minutes timeout for each chunk

    // Параметры для правильной передачи имени файла
    paramName: "file",
    // @ts-ignore
    renameFile: function (file) {
        return file.name;
    },

    dictCancelUpload: '<i class="icofont-stop icofont-2x" style="position: absolute; cursor: pointer; margin-top: -20px; margin-left: -15px; z-index: 10000"></i>',
    dictRemoveFile: "<i class=\"d-none d-md-block icofont-delete-alt icofont-2x text-danger\" style=\"position: absolute; cursor: pointer; margin-top: -28px; margin-left: 45px;z-index: 10000\"></i><svg class='d-block d-md-none' style=' position: absolute; margin-left: -26px; cursor: pointer; z-index: 10000;' width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M18 6L6 18\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 6L18 18\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n",

    init: function () {
        this.on("success", function (file: DropzoneFileWithServerId, response: any) {
            console.log('Upload success response:', response);

            if (response.success) {
                file.serverId = response.id;
                $('.dz-default').show();
                $('.dz-cust').show();
                $(file.previewElement).find('.dz-success-mark').remove();
                $('#the-progress-div').hide();
                updateFileVisibility();
                checkFormState();

                // Показываем сообщение о завершении для больших файлов
                if (response.completed) {
                    console.log('File upload completed:', response.file);
                }
            } else {
                console.error('Upload failed:', response.error);
                // @ts-ignore
                this.removeFile(file);
                alert('Upload failed: ' + response.error);
            }
        });

        this.on("error", function (file: DropzoneFileWithServerId, errorMessage: any) {
            console.error('Upload error:', errorMessage);

            // Показываем пользователю понятную ошибку
            let message = 'Upload failed';
            if (typeof errorMessage === 'string') {
                message = errorMessage;
            } else if (errorMessage.error) {
                message = errorMessage.error;
            }

            alert('Error uploading file: ' + message);
            // @ts-ignore
            this.removeFile(file);
        });

        this.on("sending", function (file, xhr, formData) {
            console.log('Sending file:', file.name);
            console.log('File size:', file.size);
            console.log('File type:', file.type);

            // Проверим, что передается в formData
            console.log('FormData entries:');
            // @ts-ignore
            for (let pair of formData.entries()) {
                console.log(pair[0] + ': ' + pair[1]);
            }

            $('#the-progress-div').show();
            $('#submitbutton').prop("disabled", true);
        });

        this.on("uploadprogress", function (file, progress, bytesSent) {
            console.log('Upload progress:', progress + '%', 'Bytes sent:', bytesSent);
        });

        this.on("totaluploadprogress", function (progress) {
            $("#the-progress-div").width(progress.toFixed(0) + '%');
            $(".the-progress-text").text(progress.toFixed(0) + '%');
        });

        this.on("removedfile", function (file: DropzoneFileWithServerId) {
            if (file.serverId) {
                const locale = window.location.pathname.split('/')[2];
                const url = `/app/${locale}/upload/${file.serverId}/remove`;
                console.log('Removing file:', file.serverId);

                ajax({
                    method: 'POST',
                    url: url,
                    success: function (response: any) {
                        if (response.success === true) {
                            updateFileVisibility();
                            checkFormState();
                        }
                    },
                    error: function (xhr, status, error) {
                        console.error('Error removing file:', error);
                    }
                });
            }
        });

        // Обработка chunked upload
        this.on("chunksUploaded", function (file: DropzoneFileWithServerId, done: Function) {
            console.log('All chunks uploaded for file:', file.name);
            // Dropzone автоматически вызовет done() когда получит успешный ответ
            done();
        });
    }
};

const fileContainer = $('#docUpload');
const toggleButton = $('<button id="toggleFiles" class="toggle-files" type="button" style="display: none;">Show more</button>');
fileContainer.after(toggleButton);

function updateFileVisibility() {
    const filePreviews = fileContainer.find('.dz-preview');

    if (!fileContainer.hasClass('show-all')) {
        filePreviews.each(function (index) {
            if (index >= 3) {
                $(this).addClass('d-none');
            } else {
                $(this).removeClass('d-none');
            }
        });
    }

    if (filePreviews.length > 3) {
        toggleButton.show();
        if (!fileContainer.hasClass('show-all')) {
            toggleButton.text('Show more');
        }
    } else {
        toggleButton.hide();
    }
}

toggleButton.on('click', function () {
    if (fileContainer.hasClass('show-all')) {
        fileContainer.removeClass('show-all');
        fileContainer.find('.dz-preview').each(function (index) {
            if (index >= 3) {
                $(this).addClass('d-none');
            }
        });
        toggleButton.text('Show more');
    } else {
        fileContainer.addClass('show-all');
        fileContainer.find('.dz-preview').removeClass('d-none');
        toggleButton.text('Hide');
    }
});

const folderInput = document.getElementById('folderInput') as HTMLInputElement;
const uploadFolderButton = document.getElementById('uploadFolderBtn') as HTMLButtonElement;

uploadFolderButton.addEventListener('click', () => {
    folderInput.click();
});

folderInput.addEventListener('change', async (event: Event) => {
    const input = event.target as HTMLInputElement;
    if (input.files && input.files.length > 0) {
        const files = Array.from(input.files);
        const firstFile = files[0];
        const folderName = firstFile.webkitRelativePath.split('/')[0];

        console.log(`Processing ${files.length} files for folder: ${folderName}`);

        // Если файлов слишком много, предупреждаем пользователя
        if (files.length > 10000) {
            const proceed = confirm(`This folder contains ${files.length} files. Creating an archive may take a long time and use significant memory. Continue?`);
            if (!proceed) {
                input.value = '';
                return;
            }
        }

        try {
            // Показать индикатор загрузки
            $('#the-progress-div').show();
            $('.the-progress-text').text('Preparing archive...');

            // Создаем архив пакетами для экономии памяти
            const zip = new JSZip();
            const BATCH_SIZE = 100; // Обрабатываем по 100 файлов за раз
            let processedFiles = 0;
            let successfulFiles = 0;
            let skippedFiles = 0;

            // Обработка файлов пакетами
            for (let i = 0; i < files.length; i += BATCH_SIZE) {
                const batch = files.slice(i, i + BATCH_SIZE);

                for (const file of batch) {
                    try {
                        // Проверяем доступность файла
                        if (file.size === 0) {
                            console.warn(`Skipping empty file: ${file.webkitRelativePath}`);
                            skippedFiles++;
                            continue;
                        }

                        // Проверяем, что файл все еще доступен
                        if (file.lastModified === undefined) {
                            console.warn(`Skipping inaccessible file: ${file.webkitRelativePath}`);
                            skippedFiles++;
                            continue;
                        }

                        // Добавляем файл в ZIP без немедленного чтения
                        zip.file(file.webkitRelativePath, file, {
                            compression: 'DEFLATE',
                            compressionOptions: {
                                level: 1 // Минимальное сжатие
                            }
                        });

                        successfulFiles++;
                    } catch (fileError) {
                        console.error(`Error processing file ${file.webkitRelativePath}:`, fileError);
                        skippedFiles++;
                    }

                    processedFiles++;
                }

                // Обновляем прогресс
                const progress = (processedFiles / files.length) * 50;
                $('#the-progress-div').width(progress + '%');
                $('.the-progress-text').text(`Preparing: ${processedFiles}/${files.length} files`);

                // Даем браузеру время на обработку
                await new Promise(resolve => setTimeout(resolve, 50));
            }

            console.log(`Successfully processed ${successfulFiles} files, skipped ${skippedFiles} files`);

            if (successfulFiles === 0) {
                throw new Error('No files could be processed');
            }

            $('.the-progress-text').text('Creating archive...');

            // Генерация ZIP с обработкой больших архивов
            const zipBlob = await zip.generateAsync({
                type: 'blob',
                compression: 'DEFLATE',
                compressionOptions: {
                    level: 1 // Минимальное сжатие для скорости
                },
                streamFiles: true // Потоковая обработка для экономии памяти
            }, (metadata) => {
                // Обновляем прогресс генерации ZIP
                const progress = 50 + (metadata.percent / 2);
                $('#the-progress-div').width(progress + '%');
                $('.the-progress-text').text(`Creating archive: ${Math.round(metadata.percent)}%`);
            });

            const zipFileName = folderName ? `${folderName}.zip` : 'archive.zip';
            const zipFile = new File([zipBlob], zipFileName, {type: 'application/zip'});

            console.log(`Archive created: ${zipFileName}, size: ${(zipFile.size / 1024 / 1024).toFixed(2)} MB`);
            console.log(`Files in archive: ${successfulFiles}, skipped: ${skippedFiles}`);

            // Скрываем индикатор подготовки
            $('#the-progress-div').hide();
            $('.the-progress-text').text('0%');

            // Добавляем файл в Dropzone
            const dropzoneInstance = Dropzone.forElement('#docUpload');
            dropzoneInstance.addFile(zipFile as any);

            // Очищаем input
            input.value = '';

            // Показываем статистику если были пропущенные файлы
            if (skippedFiles > 0) {
                alert(`Archive created successfully!\nFiles processed: ${successfulFiles}\nFiles skipped: ${skippedFiles}`);
            }

        } catch (error) {
            console.error('Error creating archive:', error);

            // Скрываем индикатор загрузки
            $('#the-progress-div').hide();
            $('.the-progress-text').text('0%');

            // Показываем ошибку пользователю
            let errorMessage = 'Failed to create archive from folder';
            if (error instanceof Error) {
                errorMessage += ': ' + error.message;
            }

            // Предлагаем альтернативные решения
            errorMessage += '\n\nTry:\n- Selecting a smaller folder\n- Using a desktop archiving tool\n- Uploading files in smaller batches';

            alert(errorMessage);

            // Очищаем input
            input.value = '';
        }
    }
});
function checkFormState() {
    const userSelected = $('#shared_file_contact').val() || $('#chooseUserFree').val();
    const filesUploaded = fileContainer.find('.dz-preview').length > 0;
    const emailSelected = String($('#shared_file_contactEmail').val()).trim() !== '';

    const titleFilled = String($('#shared_file_title').val()).trim() !== '';
    const messageFilled = String($('#shared_file_message').val()).trim() !== '';

    if (filesUploaded && titleFilled && messageFilled) {
        if (userSelected || emailSelected) {
            $('#submitbutton').prop("disabled", false);
            return true;
        }
    } else {
        $('#submitbutton').prop("disabled", true);
        return false;
    }
}