<template>
    <v-col cols="12" v-if="files?.length > 0" class="mb-5">
        <v-row no-gutters>
            <v-col v-if="showTitle" class="font-weight-bold">{{ title }}</v-col>
            <v-col cols="12" class="">

                <!-- Loading Skeleton -->
                <template v-if="loading && files?.length > 0">
                    <v-card v-for="(file, index) in files" :key="index" height="50px" flat border="sm black"
                        class="mb-2">
                        <v-skeleton-loader type="list-item" class="mb-2" />
                    </v-card>
                </template>

                <!-- Files Content -->
                <template v-else>

                    <!-- Videos -->
                    <template v-if="videosArray.length > 0">
                        <div v-if="showFileTypeTitle" class="text-caption text-medium-emphasis mb-1">Videos ({{
                            videosArray.length }})</div>
                        <v-list density="compact" class="pa-0 rounded-lg border mb-2">
                            <template v-for="(item, i) in videosArray" :key="item._id">
                                <v-divider v-if="i > 0" />
                                <v-list-item :prepend-icon="getFileIcon(item.mimeType)" :title="item.file.name"
                                    :subtitle="item.mimeType" class="cursor-pointer"
                                    @click="openMediaViewer(item._id, item.mimeType)">
                                    <template #prepend>
                                        <v-icon :color="getFileIconColor(item.mimeType)" class="mr-3">{{
                                            getFileIcon(item.mimeType) }}</v-icon>
                                    </template>
                                    <template #append>
                                        <v-icon size="16" color="grey-lighten-1">mdi-play-circle-outline</v-icon>
                                    </template>
                                </v-list-item>
                            </template>
                        </v-list>
                    </template>

                    <!-- Photos -->
                    <template v-if="photosArray.length > 0">
                        <div v-if="showFileTypeTitle" class="text-caption text-medium-emphasis mb-1"
                            :class="{ 'mt-3': videosArray.length > 0 }">
                            Photos ({{ photosArray.length }})</div>
                        <v-list density="compact" class="pa-0 rounded-lg border mb-2">
                            <template v-for="(item, i) in photosArray" :key="item._id">
                                <v-divider v-if="i > 0" />
                                <v-list-item class="cursor-pointer" @click="openMediaViewer(item._id, item.mimeType)">
                                    <template #prepend>
                                        <v-avatar size="36" rounded="sm" class="mr-3">
                                            <v-img :src="getFileUrl(item._id)" cover>
                                                <template #error>
                                                    <v-icon color="green" size="20">mdi-image</v-icon>
                                                </template>
                                            </v-img>
                                        </v-avatar>
                                    </template>
                                    <v-list-item-title class="text-body-2">{{ item.file.name }}</v-list-item-title>
                                    <v-list-item-subtitle class="text-caption">{{ item.mimeType
                                        }}</v-list-item-subtitle>
                                    <template #append>
                                        <v-icon size="16" color="grey-lighten-1">mdi-eye-outline</v-icon>
                                    </template>
                                </v-list-item>
                            </template>
                        </v-list>
                    </template>

                    <!-- Documents & Other Files -->
                    <template v-if="filesArray.length > 0">
                        <div v-if="showFileTypeTitle" class="text-caption text-medium-emphasis mb-1"
                            :class="{ 'mt-3': videosArray.length > 0 || photosArray.length > 0 }">Files ({{
                                filesArray.length }})</div>
                        <v-list density="compact" class="pa-0 rounded-lg border mb-2">
                            <template v-for="(item, i) in filesArray" :key="item._id">
                                <v-divider v-if="i > 0" />
                                <v-list-item class="cursor-pointer"
                                    @click="openDocumentViewer(item._id, item.file.name, item.mimeType)">
                                    <template #prepend>
                                        <v-icon :color="getFileIconColor(item.mimeType)" class="mr-3">{{
                                            getFileIcon(item.mimeType) }}</v-icon>
                                    </template>
                                    <v-list-item-title class="text-body-2">{{ item.file.name }}</v-list-item-title>
                                    <v-list-item-subtitle class="text-caption">{{ item.mimeType
                                        }}</v-list-item-subtitle>
                                    <template #append>
                                        <v-icon size="16" color="grey-lighten-1">mdi-open-in-new</v-icon>
                                    </template>
                                </v-list-item>
                            </template>
                        </v-list>
                    </template>

                </template>

            </v-col>
        </v-row>

        <!-- Media Carousel (images + videos) -->
        <ImageCarousel v-model="showCarousel" :active-file-id="activeFileId" :files="carouselFiles" />

        <!-- Document Viewer -->
        <DocumentViewer v-model="showDocumentViewer" :file-id="activeFileId" :file-name="activeFileName"
            :mime-type="activeFileMimeType" />
    </v-col>
</template>

<script setup lang="ts">
const props = defineProps({
    files: {
        type: Array as PropType<{ id: string, name: string }[]>,
        required: true,
    },
    title: {
        type: String,
        default: "Attachments",
    },
    showTitle: {
        type: Boolean,
        default: false,
    },

    showFileTypeTitle: {
        type: Boolean,
        default: false,
    }
});

const { getFileUrl, urlToFile, getFileById } = useFile();

const rawFileArray = ref<{ file: File, _id: string, preview: boolean, mimeType: string }[]>([]);
const loading = ref(true);

const photosArray = getByType('image/');
const videosArray = getByType('video/');
const filesArray = getByType('other');

/* Viewer state */
const showCarousel = ref(false);
const showDocumentViewer = ref(false);
const activeFileId = ref('');
const activeFileName = ref('');
const activeFileMimeType = ref('application/octet-stream');
const carouselFiles = ref<string[]>([]);

function openMediaViewer(id: string, mimeType: string) {
    activeFileId.value = id;
    carouselFiles.value = [
        ...photosArray.value.map(x => x._id),
        ...videosArray.value.map(x => x._id),
    ];
    showCarousel.value = true;
}

function openDocumentViewer(id: string, name: string, mimeType: string) {
    activeFileId.value = id;
    activeFileName.value = name;
    activeFileMimeType.value = mimeType;
    showDocumentViewer.value = true;
}

function getFileIcon(mimeType: string): string {
    if (mimeType.startsWith('image/')) return 'mdi-image';
    if (mimeType.startsWith('video/')) return 'mdi-video';
    if (mimeType === 'application/pdf') return 'mdi-file-pdf-box';
    if (mimeType.includes('word') || mimeType.includes('document')) return 'mdi-file-word-box';
    if (mimeType.includes('excel') || mimeType.includes('spreadsheet')) return 'mdi-file-excel-box';
    if (mimeType.includes('powerpoint') || mimeType.includes('presentation')) return 'mdi-file-powerpoint-box';
    if (mimeType === 'text/plain') return 'mdi-file-document-outline';
    if (mimeType.includes('zip') || mimeType.includes('compressed') || mimeType.includes('archive')) return 'mdi-folder-zip-outline';
    return 'mdi-file-outline';
}

function getFileIconColor(mimeType: string): string {
    if (mimeType === 'application/pdf') return 'red';
    if (mimeType.includes('word') || mimeType.includes('document')) return 'blue';
    if (mimeType.includes('excel') || mimeType.includes('spreadsheet')) return 'green';
    if (mimeType.includes('powerpoint') || mimeType.includes('presentation')) return 'orange';
    if (mimeType.startsWith('video/')) return 'purple';
    return 'grey';
}

function getByType(prefix: 'image/' | 'video/' | 'other') {
    return computed(() => {
        return rawFileArray.value.filter(x => {
            const type = x?.mimeType || x?.file?.type;
            if (typeof type !== 'string') return false;

            if (prefix === 'other') {
                return !type.startsWith('image/') && !type.startsWith('video/');
            }
            return type.startsWith(prefix);
        });
    });
}

watchEffect(async () => {
    loading.value = true;
    const processedFiles: typeof rawFileArray.value = [];

    for (const item of (props.files || [])) {
        // Handle building files format: { id, name }
        if (item.id && item.name && !item.file) {
            let file: File = new File([], item.name);
            let mimeType = 'application/octet-stream';

            try {
                // Try to get the actual file with proper MIME type detection from blob
                const fileUrl = getFileUrl(item.id);
                file = await urlToFile(fileUrl, item.name);
                mimeType = file.type || 'application/octet-stream';

                // If blob detection returned generic type, try API metadata or filename
                if (mimeType === 'application/octet-stream') {
                    try {
                        const fileMeta = await getFileById(item.id) as any;
                        const apiMimeType = fileMeta?.data?.mimeType || fileMeta?.mimeType;
                        if (apiMimeType && apiMimeType !== 'application/octet-stream') {
                            mimeType = apiMimeType;
                        } else {
                            const ext = item.name?.split('.').pop()?.toLowerCase();
                            mimeType = inferMimeType(ext);
                        }
                    } catch {
                        // Fallback to filename-based detection
                        const ext = item.name?.split('.').pop()?.toLowerCase();
                        mimeType = inferMimeType(ext);
                    }
                }
            } catch {
                // Fallback: try API metadata
                try {
                    const fileMeta = await getFileById(item.id) as any;
                    const apiMimeType = fileMeta?.data?.mimeType || fileMeta?.mimeType;
                    if (apiMimeType && apiMimeType !== 'application/octet-stream') {
                        mimeType = apiMimeType;
                    } else {
                        // Fallback to filename-based detection
                        const ext = item.name?.split('.').pop()?.toLowerCase();
                        mimeType = inferMimeType(ext);
                    }
                } catch {
                    // Final fallback: infer from filename
                    const ext = item.name?.split('.').pop()?.toLowerCase();
                    mimeType = inferMimeType(ext);
                }
            }

            processedFiles.push({
                _id: item.id,
                file,
                preview: item.preview ?? false,
                mimeType
            });
        }
        // Handle announcement files format: { file, _id, ... }
        else if (item.file && item._id) {
            processedFiles.push({
                ...item,
                preview: item.preview ?? false,
                mimeType: item.file.type || 'application/octet-stream'
            });
        }
    }

    rawFileArray.value = processedFiles;
    loading.value = false;
});

function inferMimeType(ext?: string): string {
    if (!ext) return 'application/octet-stream';
    const mimeMap: Record<string, string> = {
        'pdf': 'application/pdf',
        'doc': 'application/msword',
        'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'xls': 'application/vnd.ms-excel',
        'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'ppt': 'application/vnd.ms-powerpoint',
        'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
        'txt': 'text/plain',
        'jpg': 'image/jpeg',
        'jpeg': 'image/jpeg',
        'png': 'image/png',
        'gif': 'image/gif',
        'webp': 'image/webp',
        'mp4': 'video/mp4',
        'webm': 'video/webm',
        'ogv': 'video/ogg',
        'zip': 'application/zip',
        'rar': 'application/x-rar-compressed',
        '7z': 'application/x-7z-compressed',
    };
    return mimeMap[ext] || 'application/octet-stream';
}
</script>
