<script setup lang="ts">
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
import { computed, onMounted, ref } from 'vue';
import { useNotificationsStore } from '@/utils/notification';
import { api } from '@/packages/api/src';
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
import { DocumentIcon } from '@heroicons/vue/24/solid';
import {
    ArrowDownOnSquareIcon,
    InformationCircleIcon,
} from '@heroicons/vue/24/outline';

import { getCurrentOrganizationId } from '@/utils/useUser';
import type { ImportReport, ImportType } from '@/packages/api/src';
import DialogModal from '@/packages/ui/src/DialogModal.vue';
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
import { initializeStores } from '@/utils/init';
import { CardTitle } from '@/packages/ui/src';
import Card from '@/Components/Common/Card.vue';

const importTypeOptions = ref<ImportType[]>([]);

const { addNotification } = useNotificationsStore();

const loading = ref(false);

onMounted(async () => {
    const organizationId = getCurrentOrganizationId();
    if (organizationId) {
        importTypeOptions.value = (
            await api.getImporters({
                params: {
                    organization: organizationId,
                },
            })
        ).data;
    }
});

const reportResult = ref<ImportReport | null>();
const files = ref<FileList | null>(null);

async function importData() {
    if (importType.value === null) {
        addNotification('error', 'Please select the import type');
        return;
    }
    if (files.value?.length !== 1) {
        addNotification(
            'error',
            'Please select the CSV or ZIP file that you want to import'
        );
        return;
    }
    const rawBase64String = await toBase64(files.value[0]);
    const base64String = rawBase64String
        .split(';')[1]
        .replace('base64,', '') as string;
    const organizationId = getCurrentOrganizationId();
    if (organizationId !== null) {
        const { handleApiRequestNotifications } = useNotificationsStore();
        loading.value = true;
        try {
            reportResult.value = await handleApiRequestNotifications(() => {
                if (importType.value) {
                    return api.importData(
                        {
                            type: importType.value.key,
                            data: base64String,
                        },
                        {
                            params: {
                                organization: organizationId,
                            },
                        }
                    );
                }
                return new Promise((resolve, reject) => {
                    reject('Import type is null');
                });
            });
            initializeStores();
            if (reportResult.value) {
                showResultModal.value = true;
            }
        } finally {
            loading.value = false;
        }
    }
}

const importFile = ref<HTMLInputElement | null>();

function toBase64(file: File): Promise<string> {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => {
            if (reader.result instanceof ArrayBuffer) {
                const decoder = new TextDecoder();
                const str = decoder.decode(reader.result);
                return reject(str);
            } else if (reader.result) {
                resolve(reader.result);
            }
        };
        reader.onerror = reject;
    });
}

function updateFiles() {
    files.value = importFile.value?.files ?? null;
}

const currentImporterDescription = computed(() => {
    if (importType.value === null) {
        return '';
    }
    return importType.value.description;
});

const filenames = computed(() => {
    return files.value?.item(0)?.name ?? 'Import File selected';
});

const importType = ref<ImportType | null>(null);

const showResultModal = ref(false);
</script>

<template>
    <DialogModal
        closeable
        :show="showResultModal"
        @close="showResultModal = false">
        <template #title>Import Result</template>
        <template #content>
            <div class="pb-6">
                The import was successful! Here is an overview of the imported
                data:
            </div>

            <div
                class="py-2.5 px-3 border-t border-t-card-background-separator">
                <span class="text-white font-semibold">Clients created:</span>
                {{ reportResult?.report.clients.created }}
            </div>
            <div
                class="py-2.5 px-3 border-t border-t-card-background-separator">
                <span class="text-white font-semibold">Projects created:</span>
                {{ reportResult?.report.projects.created }}
            </div>
            <div
                class="py-2.5 px-3 border-t border-t-card-background-separator">
                <span class="text-white font-semibold">Tasks created:</span>
                {{ reportResult?.report.tasks.created }}
            </div>
            <div
                class="py-2.5 px-3 border-t border-t-card-background-separator">
                <span class="text-white font-semibold"
                    >Time entries created:</span
                >
                {{ reportResult?.report.time_entries.created }}
            </div>
        </template>
        <template #footer>
            <SecondaryButton @click="showResultModal = false">
                Close
            </SecondaryButton>
        </template>
    </DialogModal>
    <div>
        <CardTitle
            title="Import Data"
            :icon="ArrowDownOnSquareIcon"></CardTitle>
        <Card class="mb-3">
            <div class="py-2 px-3 sm:px-4 text-sm flex items-center space-x-3">
                <InformationCircleIcon
                    class="h-5 min-w-0 w-5 text-bg-tertiary" />
                <p class="flex-1">
                    Import existing data from Toggl, Clockify or a different
                    solidtime instance. Please select the type of data you want
                    to import and follow the instructions.
                </p>
            </div>
        </Card>

        <Card>
            <div
                class="px-4 py-5 sm:px-5 bg-card-background shadow sm:rounded-tl-md sm:rounded-tr-md">
                <div>
                    <InputLabel for="importType" value="Import Type" />
                    <select
                        id="importType"
                        v-model="importType"
                        name="importType"
                        class="mt-1 block w-full border-input-border bg-input-background text-white focus:border-input-border-active rounded-md shadow-sm">
                        <option :value="null" selected disabled>
                            Select an import type to get instructions...
                        </option>
                        <option
                            v-for="importTypeOption in importTypeOptions"
                            :key="importTypeOption.key"
                            :value="importTypeOption">
                            {{ importTypeOption.name }}
                        </option>
                    </select>
                    <div
                        v-if="currentImporterDescription"
                        class="py-3 text-white">
                        <div class="font-semibold text-muted py-1">
                            Instructions:
                        </div>
                        <div
                            class="max-w-2xl"
                            v-html="currentImporterDescription"></div>
                    </div>
                </div>

                <div
                    class="mt-2 flex justify-center rounded-lg border border-dashed border-white/30 px-6 py-10">
                    <div class="text-center">
                        <DocumentIcon
                            class="mx-auto h-8 w-8 text-muted"
                            aria-hidden="true" />

                        <div class="mt-4 flex text-sm leading-6 text-muted">
                            <label
                                for="file-upload"
                                class="relative cursor-pointer rounded-md bg-gray-900 font-semibold text-white focus-within:outline-none focus-within:ring-2 focus-within:ring-indigo-600 focus-within:ring-offset-2 focus-within:ring-offset-gray-900 hover:text-indigo-500">
                                <span v-if="files">{{ filenames }}</span>
                                <span v-else
                                    >Upload a Toggl/Clockify Export</span
                                >
                                <input
                                    id="file-upload"
                                    ref="importFile"
                                    name="file-upload"
                                    type="file"
                                    class="sr-only"
                                    @change="updateFiles" />
                            </label>
                        </div>
                        <p class="text-xs leading-5 text-muted">
                            CSV and ZIP are supported
                        </p>
                    </div>
                </div>
            </div>

            <div
                class="flex items-center justify-end px-4 py-3 bg-card-background border-t border-card-background-separator text-end sm:px-6 shadow sm:rounded-bl-md sm:rounded-br-md">
                <PrimaryButton :loading @click="importData"
                    >Import Data
                </PrimaryButton>
            </div>
        </Card>
    </div>
</template>
