<!--/* v8 ignore next 1 */ -->
<template>
  <v-dialog v-model="modalState" width="535" class="modal-dialog">
    <v-card>
      <v-card-title class="text-left font-weight-bold mt-3 mb-3 ml-2 mr-2">
        <span class="text-h4">Upload DICOM to cloud</span>
        <v-btn
          data-testid="close"
          variant="text"
          size="default"
          icon="close"
          color="shark_400"
          @click="modalState = false"
          class="position-absolute"
          style="top: 8px; right: 0"
        />
      </v-card-title>
      <v-divider color="shark_400" class="mb-1" />
      <CloudDropZone
        class="ml-4 mr-4 mt-4 mb-4"
        :onFilesDropped="handleFilesDropped"
        accept=".dcm,.unity,.png,.jpg,.jpeg,.pdf"
      />
      <v-divider color="shark_400" class="ml-4 mr-4 mb-4" />

      <div v-if="droppedFiles.length > 0" class="file-list ml-4 mr-4">
        <div
          v-for="(upload, index) in droppedFiles"
          :key="index"
          :data-testid="`file-item-${upload.id}`"
          class="file-item mt-1 mb-1 pl-4 pr-4 position-relative"
        >
          <v-icon color="minsk_200" icon="draft" size="x-large" />
          <div class="file-info">
            <div class="file-name text-sm-semibold pl-3">
              {{ upload.title }}
              <v-btn
                variant="text"
                size="medium"
                icon="delete"
                color="shark_600"
                @click="deleteFile(upload)"
                class="position-absolute"
                style="right: 16px; top: 12px"
              />
            </div>
            <div class="file-name-sub text-xs-regular pl-3 pt-1 pb-2">{{ upload.title }}</div>
            <div v-if="upload.status === 'uploading'" class="progress-container pl-3 pr-4 pb-3">
              <v-progress-linear :value="getProgress(upload)" max="100" class="custom-progress" />
              <span class="progress-percentage text-xs-medium">{{ getProgress(upload) }}%</span>
            </div>
            <div v-else-if="upload.status === 'failed'" class="error-message pl-3">
              <span class="error-text">
                Error! Failed to upload.
                <a @click="retryUpload(upload)">Try again</a>
              </span>
            </div>
          </div>
        </div>
      </div>
      <v-divider class="mb-3 mt-2" />
      <div class="ml-auto mb-3">
        <v-btn
          data-testid="cancel"
          variant="text"
          text="Cancel"
          class="mr-2"
          color="minsk_900"
          @click="modalState = false"
        />
        <v-btn data-testid="done" text="Done" class="mr-2" color="minsk_900" @click="goToPricing" />
      </div>
    </v-card>
  </v-dialog>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { storeToRefs } from 'pinia';
import { useViewerStore } from '@/stores/viewer.store';
import CloudDropZone from './CloudDropZone.vue';
import { Upload } from '@3cr/viewer-types-ts';
import { openUrl } from '@/functions/openUrl';
import { PRICING_URL } from '@/constants';
import { v4 } from 'uuid';

const { options } = storeToRefs(useViewerStore());

const droppedFiles = ref<Upload[]>([]);

const modalState = defineModel<boolean>('modal', { default: false });

function getProgress(upload: Upload): number {
  const value = upload.progress ?? 0;
  return value * 100;
}

async function onComplete(files: Array<File>): Promise<void> {
  if (options.value.onCloudStorage) {
    const acceptedExtensions = ['.dcm', '.unity', '.png', '.jpg', '.pdf'];
    const filteredFiles = files.filter((file) =>
      acceptedExtensions.some((ext) => file.name.toLowerCase().endsWith(ext))
    );

    await options.value.onCloudStorage(filteredFiles);
  }
}
async function goToPricing(): Promise<void> {
  openUrl(PRICING_URL);
  modalState.value = false;
}
async function handleFilesDropped(files: Array<File>): Promise<void> {
  files.forEach((file) => {
    const id = v4();
    droppedFiles.value.push({ id, title: file.name, subtitle: 'Uploading', progress: 0, status: 'uploading' });
    simulateUploadProgress(id);
  });
  await onComplete(files);
}

function simulateUploadProgress(id: string): void {
  let progress = 0;
  const interval = setInterval(() => {
    if (progress < 100) {
      progress += 10;
      const fileIndex = droppedFiles.value.findIndex((f) => f.id === id);
      if (fileIndex !== -1) {
        droppedFiles.value[fileIndex].progress = progress;
      }
    } else {
      clearInterval(interval);
    }
  }, 500);
}

function retryUpload(upload: Upload): void {
  const fileIndex = droppedFiles.value.findIndex((u) => upload.id === u.id);
  if (fileIndex !== -1) {
    droppedFiles.value[fileIndex].progress = 0;
    droppedFiles.value[fileIndex].status = 'uploading';
    simulateUploadProgress(droppedFiles.value[fileIndex].id);
  }
}

function deleteFile(upload: Upload): void {
  const fileIndex = droppedFiles.value.findIndex((f) => f.id === upload.id);
  if (fileIndex !== -1) {
    droppedFiles.value.splice(fileIndex, 1);
  }
}

defineExpose({
  deleteFile,
  retryUpload,
  simulateUploadProgress,
  handleFilesDropped,
  getProgress,
  droppedFiles
});
</script>

<style scoped lang="scss">
.file-list {
  text-align: left;
  margin: 0px 0px !important;
}

.file-item {
  display: flex;
  align-items: center;
  background-color: #f7f7f8;
  margin: 16px;
  border-radius: 8px;
  padding: 4px;
}

.file-info {
  display: flex;
  flex-direction: column;
}

.file-name {
  color: #1d1d20;
}

.file-name-sub {
  color: #5e5e6b;
}

.progress-container {
  display: flex;
  align-items: center;
}

progress {
  margin-right: 10px;
}

.custom-progress {
  width: 378px;
  height: 8px;
  background-color: #d9d9de;
  border-radius: 4px;
  overflow: hidden;
}

.custom-progress::-webkit-progress-bar {
  background-color: #d9d9de;
}

.custom-progress::-webkit-progress-value {
  background-color: #6875ec;
}

.progress-percentage {
  color: #333;
}

.error-message a {
  color: #721c24;
  font-size: 14px;
  cursor: pointer;
  text-decoration: underline;
}
</style>
