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

        <modal-component styleType="fill-in" type="passwordPrompt" @close="closeModal">
            <div class="row bg-white p-t-45 p-b-45 p-l-45 p-r-45">
                <div class="col">
                    <h4 class="m-b-20 text-center">Enter Password</h4>
                    <div class="form-group">
                        <input type="password" class="form-control" v-model="password" placeholder="Enter password" @keyup.enter="handleDownload">
                    </div>
                    <div class="text-danger m-b-10" v-if="error">{{ error }}</div>
                    <div class="row">
                        <div class="col-6">
                            <button class="btn btn-default btn-block" @click="closeModal">Cancel</button>
                        </div>
                        <div class="col-6">
                            <button class="btn btn-primary btn-block" @click="handleDownload" :disabled="isDownloading">
                                Download
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </modal-component>
    </span>
</template>

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

const props = withDefaults(defineProps<{
    url: string;
    customClass?: string;
}>(), {
    customClass: '',
});

const authStore = useAuthStore();

const isDownloading = ref(false);
const password = ref('');
const error = ref('');

const showPasswordModal = () => {
    password.value = '';
    error.value = '';
    nextTick(() => {
        (window as any).$('.modalContainer[data-type="passwordPrompt"]').modal('show');
    });
};

const closeModal = () => {
    (window as any).$('.modalContainer[data-type="passwordPrompt"]').modal('hide');
};

const handleDownload = async () => {
    if (!password.value) {
        error.value = 'Please enter a password';
        return;
    }

    isDownloading.value = true;
    error.value = '';

    try {
        const response = await fetch(props.url + '?password=' + password.value, {
            method: 'GET',
            headers: {
                'Authorization': 'Bearer ' + authStore.getAccessToken,
            },
        });

        if (response.status === 403) {
            error.value = 'Invalid password';
            isDownloading.value = false;
            return;
        }

        if (response.status === 200) {
            const contentType = response.headers.get('content-type');
            if (contentType && contentType.includes('application/json')) {
                const data = await response.json();
                if (data.src) {
                    window.location.href = data.src;
                    closeModal();
                    return;
                }
            }

            const contentDisposition = response.headers.get('Content-Disposition');
            const filename = contentDisposition ? contentDisposition.split('filename=')[1] : 'downloaded_file';

            const blob = await response.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);
            closeModal();
        } else {
            error.value = 'Download failed';
        }
    } catch (err) {
        console.error('Network error:', err);
        error.value = 'Network error occurred';
    } finally {
        isDownloading.value = false;
    }
};
</script>

<style scoped>
.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>
