 @extends('layouts.backendTemplate')

 @section('content')

     <style>
         #progressBar {
             display: none;
         }

         .progress-bar {
             width: 100%;
             height: 10px;
             border-radius: 5px;
             margin-top: 10px;
             appearance: none;
         }

         .progress-bar::-webkit-progress-value {
             background-color: #4CAF50;
             border-radius: 5px;
         }

         .progress-text {
             margin-top: 10px;
             font-size: 16px;
             font-weight: bold;
             color: #333;
         }
     </style>

     <!--begin::Main-->
     <div class="app-main flex-column flex-row-fluid" id="kt_app_main">

         <div class="d-flex flex-column flex-column-fluid">


             @include('uc.admin.breadcrumb', [
                 'title' => 'Sound Add',
                 'pageName' => 'Add',
                 'pageParent' => 'Sound Management',
                 'pageParentLink' => url('sound'),
             ])

             <div id="kt_app_content" class="app-content flex-column-fluid">
                 <div id="kt_app_content_container" class="app-container container-xxl">



                     <form id="frmAdd" class="form d-flex flex-column flex-lg-row" method="post"
                         enctype="multipart/form-data">

                         <input type="hidden" name="_method" value="POST">
                         <input type="hidden" name="_token" value="{{ csrf_token() }}">


                         <div class="d-flex flex-column flex-row-fluid gap-7 gap-lg-10">

                             <div class="card card-flush py-4">


                                 @if (Session::has('messageSuccess'))
                                     <div class="card-body">
                                         @include('uc/messageSuccess')
                                     </div>
                                 @endif

                                 @if (Session::has('messageFail'))
                                     <div class="card-body">
                                         @include('uc/messageFail')
                                     </div>
                                 @endif

                                 <div class="card-header">
                                     <div class="card-title">
                                         <h2>Overview</h2>
                                     </div>
                                 </div>

                                 <div class="card-body pt-0">

                                     <div class="mb-10">
                                         <label class="form-label required">File Sound</label>

                                         <input class="fileInput file-input" type="file" id="fileInput" name="fileInput"
                                             multiple accept=".m4a, .mp4, .mp3, .wav">

                                         <progress id="progressBar" class="progress-bar" value="0"
                                             max="100"></progress>
                                         <div id="progressText" class="progress-text">0%</div>

                                         <div class="text-muted fs-7">Allowed Types .m4a, .mp4, .mp3, .wav</div>
                                     </div>


                                 </div>

                             </div>

                             <div class="d-flex justify-content-end">

                                 <a href="{{ url('sound') }}" id="kt_ecommerce_add_product_cancel"
                                     class="btn btn-light me-5">Cancel</a>

                                 <button type="button" id="btn_submit" class="btn btn-primary">
                                     <span class="indicator-label">Save</span>
                                 </button>

                             </div>

                         </div>


                     </form>
                 </div>

             </div>

         </div>

     </div>


 @stop


 @section('script')

     <script>
         const baseApiUrl = "{{ env('API_URL') }}";

         $(document).on("click", "#btn_submit", async function(e) {

             e.preventDefault();

             alertLoading("Loading")

             await uploadFile();

         });


         // Step 1
         async function uploadFile() {

             const fileInput = document.getElementById("fileInput");

             const progressBar = document.getElementById("progressBar");
             const progressText = document.getElementById("progressText");

             if (!fileInput || fileInput?.files?.length === 0) {
                 alertFail("Notice", "Please select one or more files.");
                 hideLoading();
                 return;
             }
             const files = Array.from(fileInput.files); // Get all selected files

             $("#progressBar").show();

             // Upload all files sequentially (or use Promise.all for parallel uploads)
             for (const file of files) {
                 await uploadSingleFile(file, progressBar, progressText);
             }
             alertSuccessWithUrl("Notice", "All files uploaded successfully", "{{ url('sound') }}");

         }

         async function uploadSingleFile(file, progressBar, progressText) {
             const uploadId = await initiateMultipartUpload(file.name);
             const partSize = 500 * 1024 * 1024; // 500 MB per part
             const parts = [];
             let uploadedSize = 0;

             const uploadPromises = Array.from({
                     length: Math.ceil(file.size / partSize)
                 },
                 (_, index) => {
                     const partNumber = index + 1;
                     const chunk = file.slice(index * partSize, (index + 1) * partSize);

                     return (async () => {
                         const presignedUrl = await getPresignedUrl(uploadId, partNumber, file.name);
                         const etag = await uploadPartToS3(presignedUrl, chunk);

                         parts.push({
                             PartNumber: partNumber,
                             ETag: etag
                         });

                         uploadedSize += chunk.size;
                         const finalPercent = Math.floor((uploadedSize / file.size) * 100);
                         await animateProgress(progressBar, progressText, finalPercent);
                     })();
                 }
             );

             await Promise.all(uploadPromises);
             await completeMultipartUpload(uploadId, parts, file.name);
             await saveFileNameToDB(file.name);
         }

         // Step 2
         async function initiateMultipartUpload(fileName) {
             const urlUploadImage = `${baseApiUrl}/initiate-multipart-upload`;
             const response = await fetch(
                 urlUploadImage, {
                     method: "POST",
                     headers: {
                         "Content-Type": "application/json",
                     },
                     body: JSON.stringify({
                         fileName
                     }),
                 }
             );

             const {
                 uploadId
             } = await response.json();

             return uploadId;
         }

         // Step 3
         async function getPresignedUrl(uploadId, partNumber, fileName) {

             const urlPresigned = `${baseApiUrl}/get-presigned-url`
             const response = await fetch(
                 urlPresigned, {
                     method: "POST",
                     headers: {
                         "Content-Type": "application/json",
                     },
                     body: JSON.stringify({
                         uploadId,
                         partNumber,
                         fileName
                     }),
                 }
             );
             const {
                 url
             } = await response.json();
             return url;
         }

         // Step 4
         async function uploadPartToS3(url, chunk) {
             const response = await fetch(url, {
                 method: "PUT",
                 headers: {
                     "Content-Type": "application/octet-stream",
                 },
                 body: chunk,
             });
             if (!response.ok) {
                 alertFail("Notice", "Failed to upload part")
                 hideLoading();
                 //throw new Error("Failed to upload part");
             }

             const etag = `${response.headers.get("ETag")}`.replace(/"/g, "");

             if (!etag) {
                 throw new Error("Failed to retrieve ETag from the response.");
             }

             return etag;
         }

         // Step 5
         async function completeMultipartUpload(uploadId, parts, fileName) {
             const urlUploadComplete = `${baseApiUrl}/complete-multipart-upload`;
             const response = await fetch(urlUploadComplete, {
                 method: "POST",
                 headers: {
                     "Content-Type": "application/json",
                 },
                 body: JSON.stringify({
                     uploadId,
                     parts,
                     fileName
                 }),
             });
             if (response.ok) {
                 //window.location.href = "{{ url('image') }}";
             } else {
                 alertFail("Notice", "Failed to upload part");
                 hideLoading();
                 return;
             }
         }

         /**
          * Smoothly animates the progress bar and percentage text.
          */
         async function animateProgress(progressBar, progressText, targetPercent) {
             const currentPercent = parseInt(progressBar.value) || 0;
             // Increment the percentage smoothly
             for (let percent = currentPercent + 1; percent <= targetPercent; percent++) {
                 progressBar.value = percent;
                 progressText.textContent = `${percent}%`;

                 // Add a small delay to make the increment visible (10ms delay)
                 await new Promise((resolve) => setTimeout(resolve, 10));
             }
         }

         /**
          * Sends the uploaded file name to the server using AJAX.
          */
         function saveFileNameToDB(fileName) {
             initAjaxSetupToken();

             const folderId = "{{ $folderIdView }}";
             const url = "{{ url('') }}";

             return $.ajax({
                 url: `${url}/sound/insert`,
                 type: 'POST',
                 contentType: 'application/json',
                 data: JSON.stringify({
                     fileName,
                     folderId
                 }),
                 success: (response) => {
                     console.log('File name saved:', response);
                 },
                 error: (err) => {
                     console.error('Error saving file name:', err);
                     alertFail("Notice", "There was an error saving the file name.");
                     hideLoading();
                     return;
                 }
             });
         }
     </script>

     <script>
         $('.file-input').fileuploader({
             extensions: ['m4a', 'mp4', 'mp3', 'wav'],
             limit: null,
             fileMaxSize: null,
             changeInput: '<div class="fileuploader-input">' +
                 '<div class="fileuploader-input-inner">' +
                 '<p><i class="fileuploader-icon-main"></i></p>' +
                 '<h6>Drag and drop files here</h6>' +
                 '<p>or</p>' +
                 '<br>' +
                 '<button type="button" class="fileuploader-input-button"><span>${captions.button}</span></button>' +
                 '</div>' +
                 '</div>',
             theme: 'dragdrop',
         });
     </script>

 @endsection
