<template>
  <div class="bg-white rounded border border-gray-200 relative flex flex-col">
    <div class="px-6 pt-6 pb-5 font-bold border-b border-gray-200">
      <span class="card-title">Upload</span>
      <i class="fas fa-upload float-right text-green-400 text-2xl"></i>
    </div>
    <div class="p-6">
      <!-- Upload Dropbox -->
      <div
        class="w-full px-10 py-20 rounded text-center cursor-pointer border border-dashed border-gray-400 text-gray-400 transition duration-500 hover:text-white hover:bg-green-400 hover:border-green-400 hover:border-solid"
        :class="{ 'bg-green-400 border-green-400 border-solid': is_dragover }"
        accept="video/*"
        @drag.prevent.stop=""
        @dragstart.prevent.stop=""
        @dragend.prevent.stop="is_dragover = false"
        @dragover.prevent.stop="is_dragover = true"
        @dragenter.prevent.stop="is_dragover = true"
        @dragleave.prevent.stop="is_dragover = false"
        @drop.prevent.stop="upload($event)"
      >
        <h5>Drop your files here</h5>
      </div>
      <input type="file" multiple accept="video/*" @change="upload($event)" />
      <hr class="my-6" />
      <!-- Progess Bars -->
      <div class="mb-4" v-for="upload in uploads" :key="upload.name">
        <!-- File Name -->
        <div class="font-bold text-sm" :class="upload.text_class">
          <i :class="upload.icon"></i>{{ upload.name }}
        </div>
        <div class="flex h-4 overflow-hidden bg-gray-200 rounded">
          <!-- Inner Progress Bar -->
          <div
            class="transition-all progress-bar bg-blue-400"
            :class="upload.variant"
            :style="{ width: upload.current_progress + '%' }"
          ></div>
        </div>
      </div>
    </div>
  </div>
  <div></div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { getFunctions, httpsCallable } from 'firebase/functions';

// Firebase Functions

// Reactive State
const is_dragover = ref(false);

// Define type for each upload item
interface UploadItem {
  current_progress: number;
  name: string;
  variant: string;
  icon: string;
  text_class: string;
}

// Uploads list with typed items
const uploads = ref<UploadItem[]>([]);

// Upload handler function
const upload = async ($event: DragEvent | Event) => {
  is_dragover.value = false;

  const { $firebase } = useNuxtApp();
  const firebaseApp = $firebase.app();
  const functions = getFunctions(firebaseApp);

  const files =
    'dataTransfer' in $event
      ? [...($event as DragEvent).dataTransfer!.files]
      : [...($event.target as HTMLInputElement).files!];

  const uploadVideoToVimeo = async (file: File, uploadIndex: number) => {
    try {
      const fileSize = file.size;
      const getVimeoUploadDetails = httpsCallable(
        functions,
        'getVimeoUploadDetails'
      );
      const result = await getVimeoUploadDetails({ fileSize });

      if (!result.data || typeof result.data !== 'object') {
        throw new Error('No valid data received from the function');
      }

      const { uploadLink, completeUri } = result.data as {
        uploadLink: string;
        completeUri: string;
      };

      const formData = new FormData();
      formData.append('file_data', file);

      const uploadResponse = await fetch(uploadLink, {
        method: 'POST',
        body: formData,
      });

      if (!uploadResponse.ok) {
        throw new Error(`Failed to upload video: ${uploadResponse.statusText}`);
      }

      if (uploads.value[uploadIndex]) {
        uploads.value[uploadIndex].current_progress = 100;
        uploads.value[uploadIndex].variant = 'bg-green-400';
        uploads.value[uploadIndex].icon = 'fas fa-check';
        uploads.value[uploadIndex].text_class = 'text-green-400';
      }
    } catch (error) {
      console.error('Error uploading:', error);
      if (uploads.value[uploadIndex]) {
        uploads.value[uploadIndex].variant = 'bg-red-400';
        uploads.value[uploadIndex].icon = 'fas fa-times';
        uploads.value[uploadIndex].text_class = 'text-red-400';
      }
    }
  };

  files.forEach((file) => {
    const uploadIndex =
      uploads.value.push({
        current_progress: 0,
        name: file.name,
        variant: 'bg-blue-400',
        icon: 'fas fa-spinner fa-spin',
        text_class: '',
      }) - 1;

    uploadVideoToVimeo(file, uploadIndex);
  });
};
</script>
