<template>
    <span>
      <a
        :class="[customClass, { 'link-disabled': isDownloading }]"
        @click.prevent="handleClick"
        v-tooltip:top="tooltip ? tooltip : ''">
        <slot></slot>
        <span v-if="isDownloading && showSpinner" class="spinner"></span>
      </a>
    </span>
  </template>

  <script setup lang="ts">
import { ref } from 'vue';
import { useAuthStore } from '@/stores/auth';
import { useRequest } from '@/composables/useRequest';

const props = withDefaults(defineProps<{
    url: string;
    isUrlProtected?: boolean;
    customClass?: string;
    tooltip?: string;
    showSpinner?: boolean;
    section?: string;
}>(), {
    isUrlProtected: false,
    customClass: '',
    tooltip: '',
    showSpinner: true,
});

const authStore = useAuthStore();
const { submit } = useRequest();

const isDownloading = ref(false);

const successHandler = (response: any) => {
    if (window.LARAVEL_VAPOR_ENABLED) {
        if (response.payload !== undefined && response.payload.src) {
            window.open(response.payload.src, '_blank');
        } else if (response.src) {
            window.open(response.src, '_blank');
        }
    }
    isDownloading.value = false;
};

const download = () => {
    fetch(props.url, {
        method: 'GET',
        headers: {
            'Authorization': 'Bearer ' + authStore.getAccessToken,
        },
    })
    .then((response) => {
        if (response.status === 200) {
            const contentDisposition = response.headers.get('Content-Disposition');
            const filename = contentDisposition ? contentDisposition.split('filename=')[1] : 'downloaded_file';

            return response.blob()
            .then((blob) => {
                const blobUrl = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = blobUrl;
                a.download = filename;
                a.style.display = 'none';
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                window.URL.revokeObjectURL(blobUrl);
            });
        } else {
            console.error('Request failed with status:', response.status);
        }
        isDownloading.value = false;
    })
    .catch((error) => {
        console.error('Network error:', error);
        isDownloading.value = false;
    });
};

const handleClick = () => {
    isDownloading.value = true;
    if (window.LARAVEL_VAPOR_ENABLED) {
        submit(props.url, 'get', props.section, false, false, undefined, { successHandler });
    } else if (props.isUrlProtected) {
        download();
    } else {
        window.open(props.url, '_blank');
        isDownloading.value = false;
    }
};
</script>

<style scoped>
    /* .a-link {
        display: inline-block;
        transition: transform 0.3s ease-in-out;
        position: relative;
    } */

    .spinner {
        border: 2px solid rgba(0, 0, 0, 0.1);
        border-left-color: #000;
        border-radius: 50%;
        width: 20px;
        height: 20px;
        animation: spin 1s linear infinite;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }

    @keyframes spin {
        0% {
            transform: translate(-50%, -50%) rotate(0deg);
        }
        100% {
            transform: translate(-50%, -50%) rotate(360deg);
        }
    }

    .link-disabled {
        pointer-events: none;
        opacity: 0.6;
        border: none;
    }
</style>
