<template>
    <div class="mt-20">
        <a-alert
            :message="$t('manual_update_app.manual_upload_instructions')"
            type="info"
            show-icon
            class="mb-4"
        >
            <template #description>
                <ul class="instruction-list">
                    <li>
                        {{ $t("manual_update_app.download_latest_package") }}
                    </li>
                    <li>
                        {{ $t("manual_update_app.ensure_zip_not_corrupted") }}
                    </li>
                    <li>
                        {{ $t("manual_update_app.max_file_size_allowed") }}
                    </li>
                    <li>
                        {{ $t("manual_update_app.auto_extract_install") }}
                    </li>
                </ul>
            </template>
        </a-alert>

        <a-card class="manual-upload-card">
            <template #title>
                <div class="card-title">
                    <CloudUploadOutlined class="title-icon" />
                    <span>{{ $t("manual_update_app.manual_upload") }}</span>
                </div>
            </template>

            <a-form layout="vertical">
                <a-form-item>
                    <a-upload-dragger
                        v-model:fileList="fileList"
                        name="file"
                        :multiple="false"
                        :before-upload="beforeUpload"
                        :remove="handleRemove"
                        accept=".zip"
                        :max-count="1"
                        class="upload-dragger"
                        :disabled="uploading"
                    >
                        <p class="ant-upload-drag-icon">
                            <InboxOutlined
                                :style="{ fontSize: '48px', color: '#1890ff' }"
                            />
                        </p>
                        <p class="ant-upload-text">
                            {{ $t("manual_update_app.click_or_drag_file") }}
                        </p>
                        <p class="ant-upload-hint">
                            {{ $t("manual_update_app.support_single_zip") }}
                        </p>
                        <p
                            class="ant-upload-hint"
                            style="color: #8c8c8c; font-size: 12px"
                        >
                            {{ $t("manual_update_app.maximum_file_size") }}
                        </p>
                    </a-upload-dragger>

                    <a-alert
                        v-if="uploadMessage"
                        :message="uploadMessage"
                        :type="uploadStatus === 'success' ? 'success' : 'error'"
                        show-icon
                        closable
                        class="mt-3"
                        @close="
                            () => {
                                uploadMessage = '';
                                uploadStatus = '';
                            }
                        "
                    />
                </a-form-item>

                <a-form-item class="upload-button-wrapper">
                    <a-space>
                        <a-button
                            type="primary"
                            size="large"
                            :loading="uploading"
                            :disabled="fileList.length === 0"
                            @click="handleUpload"
                        >
                            <template #icon>
                                <CloudUploadOutlined v-if="!uploading" />
                            </template>
                            {{
                                uploading
                                    ? $t("manual_update_app.uploading_installing")
                                    : $t("manual_update_app.upload")
                            }}
                        </a-button>
                        <a-button
                            v-if="fileList.length > 0 && !uploading"
                            size="large"
                            @click="handleRemove"
                        >
                            {{ $t("manual_update_app.clear") }}
                        </a-button>
                    </a-space>
                </a-form-item>
            </a-form>
        </a-card>

        <!-- Uploaded Files Table -->
        <a-card class="uploaded-files-card" v-if="uploadedFiles.length > 0">
            <template #title>
                <div class="card-title">
                    <FileZipOutlined class="title-icon" />
                    <span>{{ $t("manual_update_app.uploaded_files") }}</span>
                </div>
            </template>

            <a-table
                :columns="columns"
                :data-source="uploadedFiles"
                :pagination="{ pageSize: 10 }"
                :loading="loadingFiles"
                row-key="name"
            >
                <template #bodyCell="{ column, record }">
                    <template v-if="column.key === 'name'">
                        <FileZipOutlined style="margin-right: 8px; color: #faad14" />
                        {{ record.name }}
                    </template>
                    <template v-else-if="column.key === 'size'">
                        {{ record.size_formatted }}
                    </template>
                    <template v-else-if="column.key === 'uploaded_at'">
                        {{ formatDate(record.uploaded_at) }}
                    </template>
                    <template v-else-if="column.key === 'action'">
                        <a-space>
                            <a-button
                                type="primary"
                                size="small"
                                @click="installFile(record)"
                                :loading="installingFile === record.name"
                            >
                                <template #icon>
                                    <CheckCircleOutlined />
                                </template>
                                {{ $t("manual_update_app.install") }}
                            </a-button>
                            <a-popconfirm
                                :title="$t('manual_update_app.delete_file_confirm')"
                                :ok-text="$t('common.yes')"
                                :cancel-text="$t('common.no')"
                                @confirm="deleteFile(record.name)"
                            >
                                <a-button type="primary" danger size="small">
                                    <template #icon>
                                        <DeleteOutlined />
                                    </template>
                                    {{ $t("manual_update_app.delete") }}
                                </a-button>
                            </a-popconfirm>
                        </a-space>
                    </template>
                </template>
            </a-table>
        </a-card>
    </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, createVNode } from "vue";
import {
    CloudUploadOutlined,
    InboxOutlined,
    FileZipOutlined,
    DeleteOutlined,
    CheckCircleOutlined,
    ExclamationCircleOutlined,
    ReloadOutlined,
} from "@ant-design/icons-vue";
import { notification, Modal } from "ant-design-vue";
import { useI18n } from "vue-i18n";
import { getUrlByAppType } from "../../../../../common/scripts/functions";
import dayjs from "dayjs";

const { t } = useI18n();

const fileList = ref([]);
const uploading = ref(false);
const uploadMessage = ref("");
const uploadStatus = ref("");
const uploadedFiles = ref([]);
const loadingFiles = ref(false);
const installingFile = ref(null);
const reloadCountdown = ref(5);
let reloadInterval = null;

const columns = [
    {
        title: t("manual_update_app.file_name"),
        dataIndex: "name",
        key: "name",
    },
    {
        title: t("manual_update_app.size"),
        dataIndex: "size",
        key: "size",
    },
    {
        title: t("manual_update_app.uploaded_at"),
        dataIndex: "uploaded_at",
        key: "uploaded_at",
    },
    {
        title: t("common.action"),
        key: "action",
        width: 200,
    },
];

const beforeUpload = (file) => {
    const isZip = file.type === "application/zip" || file.name.endsWith(".zip");
    if (!isZip) {
        notification.error({
            message: t("common.error"),
            description: t("manual_update_app.only_zip_files_allowed"),
        });
        return false;
    }

    const isLt100M = file.size / 1024 / 1024 < 100;
    if (!isLt100M) {
        notification.error({
            message: t("common.error"),
            description: t("manual_update_app.file_size_must_be_less_than_100mb"),
        });
        return false;
    }

    fileList.value = [file];
    uploadMessage.value = "";
    uploadStatus.value = "";
    return false; // Prevent auto upload
};

const handleRemove = () => {
    fileList.value = [];
    uploadMessage.value = "";
    uploadStatus.value = "";
};

const handleUpload = async () => {
    if (fileList.value.length === 0) {
        return;
    }

    const formData = new FormData();
    // Access the originFileObj from Ant Design Vue file object
    const file = fileList.value[0].originFileObj || fileList.value[0];
    formData.append("file", file);

    uploading.value = true;
    uploadMessage.value = "";
    uploadStatus.value = "";

    try {
        const response = await axiosAdmin.post(
            getUrlByAppType("update-app/manual-upload"),
            formData,
            {
                headers: {
                    "Content-Type": "multipart/form-data",
                },
            }
        );

        uploadStatus.value = "success";
        uploadMessage.value = t("manual_update_app.file_uploaded_successfully");

        notification.success({
            message: t("common.success"),
            description:
                response.data.message || t("manual_update_app.file_uploaded_successfully"),
        });

        // Clear file list after successful upload
        fileList.value = [];

        // Refresh uploaded files list
        await fetchUploadedFiles();

        // Emit event to parent component if needed
        emit("uploadComplete", response.data);
    } catch (error) {
        uploadStatus.value = "error";
        uploadMessage.value =
            error.response?.data?.message || t("manual_update_app.upload_failed");

        notification.error({
            message: t("common.error"),
            description:
                error.response?.data?.message || t("manual_update_app.upload_failed"),
        });
    } finally {
        uploading.value = false;
    }
};

const fetchUploadedFiles = async () => {
    loadingFiles.value = true;
    try {
        const response = await axiosAdmin.get(
            getUrlByAppType("update-app/uploaded-files")
        );
        uploadedFiles.value = response.data.files || [];
    } catch (error) {
    } finally {
        loadingFiles.value = false;
    }
};

const deleteFile = async (fileName) => {
    try {
        await axiosAdmin.delete(getUrlByAppType(`update-app/uploaded-files/${fileName}`));

        notification.success({
            message: t("common.success"),
            description: t("manual_update_app.file_deleted_successfully"),
        });

        await fetchUploadedFiles();
    } catch (error) {
        notification.error({
            message: t("common.error"),
            description:
                error.response?.data?.message ||
                t("manual_update_app.failed_to_delete_file"),
        });
    }
};

const installFile = async (file) => {
    const modal = Modal.confirm({
        title: createVNode("div", { style: "display: flex; align-items: center; gap: 8px;" }, [
            createVNode(ExclamationCircleOutlined, { style: "color: #faad14; font-size: 22px;" }),
            createVNode("span", { style: "font-size: 16px; font-weight: 600;" }, t("manual_update_app.install_update_confirmation")),
        ]),
        content: createVNode("div", { style: "margin-top: 16px;" }, [
            createVNode("div", { style: "margin-bottom: 16px;" }, [
                createVNode("p", { style: "margin: 0; font-size: 14px; color: rgba(0, 0, 0, 0.85);" },
                    t("manual_update_app.install_confirm_message", [file.name])
                ),
            ]),
            createVNode("div", {
                style: "background: #f5f5f5; padding: 16px; border-radius: 8px; margin-bottom: 16px;"
            }, [
                createVNode("div", { style: "font-weight: 600; margin-bottom: 12px; color: rgba(0, 0, 0, 0.85);" },
                    t("manual_update_app.this_will")
                ),
                createVNode("ul", { style: "margin: 0; padding-left: 20px; color: rgba(0, 0, 0, 0.65);" }, [
                    createVNode("li", { style: "margin-bottom: 8px;" }, t("manual_update_app.extract_to_root")),
                    createVNode("li", { style: "margin-bottom: 8px;" }, t("manual_update_app.overwrite_existing_files")),
                    createVNode("li", { style: "margin-bottom: 8px;" }, t("manual_update_app.run_database_migrations")),
                    createVNode("li", { style: "margin-bottom: 0;" }, t("manual_update_app.clear_all_caches")),
                ]),
            ]),
            createVNode("div", {
                style: "background: #fff7e6; border: 1px solid #ffd591; padding: 12px 16px; border-radius: 6px; display: flex; align-items: start; gap: 8px;"
            }, [
                createVNode(ExclamationCircleOutlined, { style: "color: #fa8c16; font-size: 16px; margin-top: 2px;" }),
                createVNode("span", { style: "color: #d46b08; font-size: 13px; font-weight: 500;" },
                    t("manual_update_app.ensure_backup")
                ),
            ]),
        ]),
        okText: t("manual_update_app.yes_install_now"),
        okType: "danger",
        cancelText: t("manual_update_app.cancel"),
        width: 560,
        icon: null,
        onOk: () => {
            return new Promise((resolve) => {
                // Disable cancel button and show loading state
                modal.update({
                    cancelButtonProps: { disabled: true },
                    okButtonProps: { loading: true },
                });

                installingFile.value = file.name;

                axiosAdmin.post(
                    getUrlByAppType("update-app/extract"),
                    {
                        file_name: file.name,
                        verified_name: "manual_upload",
                    }
                ).then((response) => {
                    // Resolve to close modal
                    resolve();

                    emit("installComplete", response.data);

                    // Show reload modal with countdown after install modal closes
                    setTimeout(() => {
                        showReloadModal();
                    }, 300);
                }).catch((error) => {
                    // Resolve to close modal (not reject, as reject keeps modal open)
                    resolve();

                    // Then show error notification after modal closes
                    setTimeout(() => {
                        notification.error({
                            message: t("manual_update_app.installation_failed"),
                            description:
                                error.response?.data?.message ||
                                t("manual_update_app.failed_to_install_update"),
                            duration: 8,
                        });
                    }, 300);
                }).finally(() => {
                    installingFile.value = null;
                });
            });
        },
    });
};

const formatDate = (dateString) => {
    return dayjs(dateString).format("YYYY-MM-DD HH:mm:ss");
};

const showReloadModal = () => {
    reloadCountdown.value = 5;

    const reloadModal = Modal.success({
        title: createVNode("div", { style: "display: flex; align-items: center; gap: 8px;" }, [
            createVNode(CheckCircleOutlined, { style: "color: #52c41a; font-size: 22px;" }),
            createVNode("span", { style: "font-size: 16px; font-weight: 600;" }, t("manual_update_app.update_complete")),
        ]),
        content: createVNode("div", { style: "margin-top: 16px;" }, [
            createVNode("p", { style: "margin: 0 0 16px 0; font-size: 14px; color: rgba(0, 0, 0, 0.85);" },
                t("manual_update_app.reloading_message")
            ),
            createVNode("div", {
                style: "background: #f6ffed; border: 1px solid #b7eb8f; padding: 12px 16px; border-radius: 6px; display: flex; align-items: center; gap: 8px;"
            }, [
                createVNode(ReloadOutlined, { style: "color: #52c41a; font-size: 16px;", spin: true }),
                createVNode("span", {
                    style: "color: #389e0d; font-size: 14px; font-weight: 500;",
                    id: "reload-countdown-text"
                }, t("manual_update_app.reloading_page", [reloadCountdown.value])),
            ]),
        ]),
        icon: null,
        okText: t("manual_update_app.reload_now"),
        okButtonProps: { type: "primary" },
        onOk: () => {
            if (reloadInterval) {
                clearInterval(reloadInterval);
            }
            window.location.reload();
        },
        closable: false,
        keyboard: false,
        maskClosable: false,
    });

    // Start countdown
    reloadInterval = setInterval(() => {
        reloadCountdown.value--;

        // Update the countdown text
        const countdownEl = document.getElementById("reload-countdown-text");
        if (countdownEl) {
            countdownEl.textContent = t("manual_update_app.reloading_page", [reloadCountdown.value]);
        }

        if (reloadCountdown.value <= 0) {
            clearInterval(reloadInterval);
            reloadModal.destroy();
            window.location.reload();
        }
    }, 1000);
};

onMounted(() => {
    fetchUploadedFiles();
});

onUnmounted(() => {
    if (reloadInterval) {
        clearInterval(reloadInterval);
    }
});

const emit = defineEmits(["uploadComplete", "installComplete"]);
</script>

<style scoped>
.manual-upload-card {
    margin-top: 20px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    border-radius: 8px;
}

.card-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 16px;
    font-weight: 600;
}

.title-icon {
    font-size: 20px;
    color: #1890ff;
}

.instruction-list {
    margin: 8px 0 0 0;
    padding-left: 20px;
}

.instruction-list li {
    margin-bottom: 6px;
    line-height: 1.6;
}

.upload-dragger {
    border-radius: 8px;
    transition: all 0.3s ease;
}

.upload-dragger:hover {
    border-color: #1890ff;
}

.ant-upload-text {
    font-size: 16px;
    font-weight: 500;
    color: rgba(0, 0, 0, 0.85);
    margin: 16px 0 8px 0 !important;
}

.ant-upload-hint {
    color: rgba(0, 0, 0, 0.45);
    font-size: 14px;
}

.upload-button-wrapper {
    margin-top: 16px;
    text-align: center;
}

.mb-4 {
    margin-bottom: 16px;
}

.mt-3 {
    margin-top: 12px;
}

.uploaded-files-card {
    margin-top: 24px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    border-radius: 8px;
}
</style>
