<script type="module">
import ManageSidebar from '@/views/manage/sidebar.vue';
import ManageFooter from '@/views/manage/footer.vue';
import axios from 'axios';
import Swal from 'sweetalert2';
import VueEasyLightbox from 'vue-easy-lightbox';
import { mapGetters, mapActions } from 'vuex';

export default {
    name: 'PhotoListManager',
    components: { ManageSidebar, ManageFooter, VueEasyLightbox },
    data() {
        return {
            photoFiles: [], // Array of photo file names
            subjects: [], // Array of subjects for labeling
            selectedSubject: null, // Selected subject in modal
            selectedFile: null, // Selected file to label
            loading: false, // Loading state
            isSaving: false, // Saving state for labeling
            currentPage: 1, // Current page for pagination
            pageSize: 48, // Default number of photos per page
            totalPhotos: 0, // Total number of photos
            isVisible: false, // Lightbox visibility state
            currentImageIndex: 0, // Current image index for lightbox
        };
    },
    computed: {
        ...mapGetters(['user', 'authToken', 'refreshToken']),

        // Paginated photos
        paginatedPhotos() {
            const start = (this.currentPage - 1) * this.pageSize;
            const end = start + this.pageSize;
            return this.photoFiles.slice(start, end);
        },
        // Total pages
        totalPages() {
            return Math.ceil(this.totalPhotos / this.pageSize);
        },
        // Page range for pagination
        pageRange() {
            const start = Math.max(1, this.currentPage - 2);
            const end = Math.min(this.totalPages, start + 4);
            return Array.from({ length: end - start + 1 }, (_, i) => start + i);
        },
        // Image URLs for lightbox
        images() {
            return this.paginatedPhotos.map(file => `https://unknownface.bantungoding.com/photos/${file}`);
        }
    },
    methods: {
        ...mapActions(['logout', 'setAuthToken', 'setRefreshToken']),

        handleFileUpload(event) {
            this.selectedFile = event.target.files[0];
        },
        async fetchPhotoList() {
            this.loading = true; // Set loading state
            try {
                const response = await axios.get('/api/photos'); // Fetch photo list from API
                const parser = new DOMParser();
                const htmlDocument = parser.parseFromString(response.data, "text/html");
                const links = htmlDocument.querySelectorAll('a');

                // Extract filenames and sort by datetime
                this.photoFiles = Array.from(links)
                    .map(link => link.getAttribute('href'))
                    .filter(href => href && (href.endsWith('.jpg') || href.endsWith('.png')))
                    .sort((a, b) => {
                        const dateA = this.extractDateFromFileName(a);
                        const dateB = this.extractDateFromFileName(b);
                        return dateB - dateA; // Sort in descending order
                    });

                this.totalPhotos = this.photoFiles.length; // Set total photos count
            } catch (error) {
                console.error('Error fetching photo list:', error);
                Swal.fire({
                    icon: 'error',
                    title: 'Failed to fetch photos',
                    text: 'Could not load the photo list.',
                    timer: 3000
                });
            } finally {
                this.loading = false; // Reset loading state
            }
        },
        async fetchSubjects() {
            try {
                const response = await axios.get('/api/api-cpf/subjects'); // Fetch subject list from API
                this.subjects = response.data.subjects || [];
            } catch (error) {
                console.error('Error fetching subjects:', error);
                Swal.fire({
                    icon: 'error',
                    title: 'Failed to fetch subjects',
                    text: 'Could not load the subject list.',
                    timer: 3000
                });
            }
        },
        extractDateFromFileName(fileName) {
            const decodedFileName = decodeURIComponent(fileName);
            const datePart = decodedFileName.match(/(\d{4}-\d{2}-\d{2}-\d{2}:\d{2}:\d{2})/);
            return datePart ? new Date(datePart[0].replace(/-/g, '/').replace(' ', 'T')) : new Date(0);
        },
        openLightbox(index) {
            this.currentImageIndex = index;
            this.isVisible = true;
        },
        // Close lightbox
        closeLightbox() {
            this.isVisible = false;
        },
        // Change page
        changePage(page) {
            if (page > 0 && page <= this.totalPages) {
                this.currentPage = page;
            }
        },
        // Change page size
        changePageSize(size) {
            this.pageSize = size;
            this.currentPage = 1; // Reset to first page
        },
        openLabelModal(file) {
            this.selectedFile = file; // Set selected file
            this.selectedSubject = null; // Reset selected subject
            this.fetchSubjects(); // Fetch available subjects

            // Initialize modal instance
            const modalElement = document.getElementById('labelModal');
            this.labelModalInstance = new bootstrap.Modal(modalElement);
            this.labelModalInstance.show();
        },
        async submitLabel() {
            if (!this.selectedSubject || !this.selectedFile) {
                Swal.fire('Error', 'Please select a subject and file.', 'error');
                return;
            }

            this.isSaving = true;
            try {
                // Download file through proxy
                const fileUrl = `https://unknownface.bantungoding.com/photos/${this.selectedFile}`;
                const proxyResponse = await axios.get('/proxy/download', {
                    params: { url: fileUrl },
                    responseType: 'blob', // Ensures binary data
                });

                // Create FormData
                const formData = new FormData();
                formData.append('file', proxyResponse.data, this.selectedFile); // Append binary file
                formData.append('subject', this.selectedSubject); // Append subject

                // Send request to API
                const uploadResponse = await axios.post('/api/api-cpf/faces', formData, {
                    headers: {
                        'Content-Type': 'multipart/form-data',
                    },
                });

                if (uploadResponse.data.message) {
                    if (uploadResponse.data.code == 28) {
                        Swal.fire('Error', uploadResponse.data.message, 'error');
                    } else {
                        Swal.fire('Success', uploadResponse.data.message, 'success');
                    }
                } else {
                    Swal.fire('Success', 'Label added successfully!', 'success');
                }
                this.selectedSubject = null;
                this.selectedFile = null;

                // Close modal using Bootstrap instance
                if (this.labelModalInstance) {
                    this.labelModalInstance.hide();
                }
            } catch (error) {
                console.error('Error submitting label:', error.response?.data || error);
                Swal.fire('Error', 'Failed to add label.', 'error');
            } finally {
                this.isSaving = false;
            }
        },
        async handleTokenRefresh() {
            try {
                const refreshToken = this.refreshToken; // Refresh token dari Vuex atau localStorage
                if (!refreshToken) throw new Error("No refresh token available");

                const response = await axios.post("/api/refresh-token", {
                    refresh_token: refreshToken,
                });

                const { token, refresh_token: newRefreshToken } = response.data;

                // Perbarui token di Vuex dan Axios
                this.setAuthToken(token);
                this.setRefreshToken(newRefreshToken);
                this.setAxiosDefaults(token);

                console.log("Token refreshed successfully.");
                return token;
            } catch (error) {
                console.error("Error refreshing token:", error);
                Swal.fire("Error", "Session expired. Please log in again.", "error");
                this.logout();
            }
        },
        setupAxiosInterceptors() {
            axios.interceptors.response.use(
                (response) => response,
                async (error) => {
                    const { config, response } = error;
                    if (response && response.status === 401 && !config._retry) {
                        config._retry = true;
                        const newToken = await this.handleTokenRefresh();
                        if (newToken) {
                            config.headers["Authorization"] = `Bearer ${newToken}`;
                            return axios(config);
                        }
                    }
                    return Promise.reject(error);
                }
            );
        },
        logout() {
            this.$store.dispatch("logout");
            this.clearSession();
        },
        clearSession() {
            sessionStorage.removeItem("authToken");
            sessionStorage.removeItem("refreshToken");
            sessionStorage.removeItem("user");
            localStorage.removeItem("authToken");
            localStorage.removeItem("refreshToken");
            localStorage.removeItem("user");
        },
        setAxiosDefaults(token) {
            axios.defaults.headers.common["Authorization"] = `Bearer ${token}`;
        },
        showErrorAlert(message) {
            Swal.fire({
                icon: 'error',
                title: message,
                toast: true,
                position: 'top-end',
                showConfirmButton: false,
                timer: 3000,
            });
        },
    },
    mounted() {
        if (!this.user || !this.authToken) {
            Swal.fire({
                icon: 'error',
                title: 'Error',
                text: 'You do not have access. Please log in first.',
                toast: true,
                position: 'top-end',
                showConfirmButton: false,
                timer: 3000,
            }).then(() => {
                this.clearSession();
                this.logout();
            });
        } else {
            this.fetchPhotoList();
        }
        this.setupAxiosInterceptors();
    },
};
</script>


<template>
    <div>
        <manage-sidebar />
        <div class="page-wrapper">
            <div class="page-header d-print-none">
                <div class="container-fluid">
                    <div class="row g-2 align-items-center">
                        <div class="col">
                            <div class="page-pretitle">Manage</div>
                            <h2 class="page-title">List of Unknown People</h2>
                        </div>
                    </div>
                </div>
            </div>
            <div class="page-body" style="min-height: 79vh">
                <div class="container-fluid">
                    <div class="row">
                        <div class="col-12">
                            <div class="card">
                                <div class="card-body">
                                    <div class="row justify-content-between">
                                        <div class="col-auto d-flex align-items-center">
                                            <label for="pageSize" class="form-label me-2 pt-2">Show :</label>
                                            <select id="pageSize" class="form-select d-inline-block w-auto"
                                                v-model="pageSize" @change="changePageSize(pageSize)">
                                                <option value="24">24</option>
                                                <option value="36">36</option>
                                                <option value="48">48</option>
                                                <option value="100">100</option>
                                                <option value="300">300</option>
                                                <option value="500">500</option>
                                                <option value="1000">1000</option>
                                            </select>
                                            <p class="pt-3 ms-5">
                                                Results: <strong>{{ totalPhotos }}</strong> photos
                                            </p>
                                        </div>
                                        <div class="col-auto mt-2">
                                            <button class="btn btn-primary" @click="fetchPhotoList">
                                                <i class="fa fa-refresh me-1"></i> Refresh
                                            </button>
                                        </div>
                                    </div>
                                    <div v-if="loading" class="text-center my-5">
                                        <i class="fa fa-spinner fa-spin fa-3x"></i>
                                        <p class="mt-4">Loading data, please wait...</p>
                                    </div>
                                    <div v-else>
                                        <hr>
                                        <div class="row mt-2">
                                            <div class="col-xl-1 col-lg-2 col-sm-4 col-4 mb-3"
                                                v-for="(file, index) in paginatedPhotos" :key="file">
                                                <div class="card">
                                                    <div class="card-body p-1">
                                                        <img style="width: 100%; cursor: pointer; object-fit: cover; height: 100px;"
                                                            :src="`https://unknownface.bantungoding.com/photos/${file}`"
                                                            :alt="file" class="img-fluid" @click="openLightbox(index)">
                                                        <button class="btn btn-sm btn-primary mt-2 w-100"
                                                            @click="openLabelModal(file)">
                                                            Add Label
                                                        </button>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <vue-easy-lightbox :visible="isVisible" :imgs="images" :index="currentImageIndex"
                                        @hide="closeLightbox"></vue-easy-lightbox>
                                    <nav aria-label="Page navigation" class="mt-3">
                                        <ul class="pagination justify-content-center">
                                            <li class="page-item" :class="{ disabled: currentPage === 1 }">
                                                <button class="page-link" @click="changePage(1)">First</button>
                                            </li>
                                            <li class="page-item" :class="{ disabled: currentPage === 1 }">
                                                <button class="page-link"
                                                    @click="changePage(currentPage - 1)">Previous</button>
                                            </li>
                                            <li class="page-item" v-for="page in pageRange" :key="page"
                                                :class="{ active: currentPage === page }">
                                                <button class="page-link" @click="changePage(page)">{{ page }}</button>
                                            </li>
                                            <li class="page-item" :class="{ disabled: currentPage === totalPages }">
                                                <button class="page-link"
                                                    @click="changePage(currentPage + 1)">Next</button>
                                            </li>
                                            <li class="page-item" :class="{ disabled: currentPage === totalPages }">
                                                <button class="page-link" @click="changePage(totalPages)">Last</button>
                                            </li>
                                        </ul>
                                    </nav>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <manage-footer />
        </div>

        <div id="labelModal" class="modal fade" tabindex="-1" aria-hidden="true">
            <div class="modal-dialog modal-dialog-centered">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">Add Label</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div class="modal-body">
                        <form @submit.prevent="submitLabel">
                            <div class="mb-3">
                                <label for="subject" class="form-label">Select Subject</label>
                                <select id="subject" v-model="selectedSubject" class="form-select" required>
                                    <option value="" disabled>Select a subject</option>
                                    <option v-for="subject in subjects" :key="subject" :value="subject">
                                        {{ subject }}
                                    </option>
                                </select>
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                                <button type="submit" class="btn btn-primary" :disabled="isSaving">
                                    <span v-if="isSaving" class="spinner-border spinner-border-sm me-2" role="status"
                                        aria-hidden="true"></span>
                                    Submit
                                </button>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>

    </div>
</template>
