<template>
    <div class="mt-20">
        <a-alert
            :message="$t('module.manual_upload_instructions')"
            type="info"
            show-icon
            class="mb-4"
        >
            <template #description>
                <ul class="instruction-list">
                    <li>
                        {{ $t("module.download_module_package") }}
                    </li>
                    <li>
                        {{ $t("module.ensure_zip_not_corrupted") }}
                    </li>
                    <li>
                        {{ $t("module.max_file_size_allowed") }}
                    </li>
                    <li>
                        {{ $t("module.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("module.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("module.click_or_drag_file") }}
                        </p>
                        <p class="ant-upload-hint">
                            {{ $t("module.support_single_zip") }}
                        </p>
                        <p
                            class="ant-upload-hint"
                            style="color: #8c8c8c; font-size: 12px"
                        >
                            {{ $t("module.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("module.uploading")
                                    : $t("module.upload")
                            }}
                        </a-button>
                        <a-button
                            v-if="fileList.length > 0 && !uploading"
                            size="large"
                            @click="handleRemove"
                        >
                            {{ $t("module.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("module.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("module.install") }}
                            </a-button>
                            <a-popconfirm
                                :title="$t('module.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("module.delete") }}
                                </a-button>
                            </a-popconfirm>
                        </a-space>
                    </template>
                </template>
            </a-table>
        </a-card>

        <!-- Installation Progress Modal -->
        <a-modal
            v-model:open="installProgressVisible"
            :title="$t('module.installing_module')"
            :maskClosable="false"
            :closable="false"
            :footer="null"
        >
            <a-row class="mb-10">
                <a-col :span="24">
                    <a-typography-text v-if="extracting == 'started'">
                        <SyncOutlined spin /> {{ $t("messages.file_extracting_message") }}
                    </a-typography-text>
                    <a-typography-text v-if="extracting == 'completed'" strong type="success">
                        <CheckCircleOutlined />
                        {{ $t("module.file_extracted") }}
                    </a-typography-text>
                    <a-typography-text v-if="extracting == ''" type="secondary">
                        <InfoOutlined /> {{ $t("module.preparing_installation") }}
                    </a-typography-text>
                </a-col>
            </a-row>
            <a-row class="mt-10 mb-10" v-if="extracting == 'completed'">
                <a-col :span="24">
                    <a-button type="primary" @click="closeInstallModal" block>
                        <CheckOutlined /> {{ $t("messages.installation_success") }}
                    </a-button>
                </a-col>
            </a-row>
        </a-modal>
    </div>
</template>

<script setup>
import { ref, onMounted, createVNode } from "vue";
import {
    CloudUploadOutlined,
    InboxOutlined,
    FileZipOutlined,
    DeleteOutlined,
    CheckCircleOutlined,
    ExclamationCircleOutlined,
    SyncOutlined,
    InfoOutlined,
    CheckOutlined,
} 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 installProgressVisible = ref(false);
const extracting = ref("");

const emit = defineEmits(["uploadComplete", "installComplete"]);

const columns = [
    {
        title: t("module.file_name"),
        dataIndex: "name",
        key: "name",
    },
    {
        title: t("module.size"),
        dataIndex: "size",
        key: "size",
    },
    {
        title: t("module.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("module.only_zip_files_allowed"),
        });
        return false;
    }

    const isLt200M = file.size / 1024 / 1024 < 200;
    if (!isLt200M) {
        notification.error({
            message: t("common.error"),
            description: t("module.file_size_must_be_less_than_200mb"),
        });
        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("modules/manual-upload"),
            formData,
            {
                headers: {
                    "Content-Type": "multipart/form-data",
                },
            }
        );

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

        notification.success({
            message: t("common.success"),
            description:
                response.data.message || t("module.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("module.upload_failed");

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

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

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

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

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

const installFile = async (file) => {
    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("module.install_module_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("module.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("module.this_will")
                ),
                createVNode("ul", { style: "margin: 0; padding-left: 20px; color: rgba(0, 0, 0, 0.65);" }, [
                    createVNode("li", { style: "margin-bottom: 8px;" }, t("module.extract_to_modules")),
                    createVNode("li", { style: "margin-bottom: 8px;" }, t("module.run_migrations")),
                    createVNode("li", { style: "margin-bottom: 8px;" }, t("module.seed_translations")),
                    createVNode("li", { style: "margin-bottom: 0;" }, t("module.enable_module")),
                ]),
            ]),
            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("module.ensure_backup")
                ),
            ]),
        ]),
        okText: t("module.yes_install_now"),
        okType: "danger",
        cancelText: t("module.cancel"),
        width: 560,
        icon: null,
        onOk: async () => {
            installingFile.value = file.name;
            installProgressVisible.value = true;
            extracting.value = "started";

            try {
                const response = await axiosAdmin.post(
                    getUrlByAppType("modules/extract"),
                    {
                        file_name: file.name,
                        verified_name: "manual_upload",
                    }
                );

                extracting.value = "completed";

                notification.success({
                    message: t("common.success"),
                    description: t("module.module_installed_successfully"),
                    duration: 5,
                });

                emit("installComplete", response.data);

                // Refresh the uploaded files list
                await fetchUploadedFiles();
            } catch (error) {
                extracting.value = "failed";
                installProgressVisible.value = false;

                // Get detailed error message
                let errorMessage = t("module.failed_to_install_module");

                if (error.response?.data?.message) {
                    errorMessage = error.response.data.message;
                } else if (error.response?.data?.error) {
                    errorMessage = error.response.data.error;
                } else if (error.message) {
                    errorMessage = error.message;
                }

                notification.error({
                    message: t("module.installation_failed"),
                    description: errorMessage,
                    duration: 10,
                });
            } finally {
                installingFile.value = null;
            }
        },
    });
};

const closeInstallModal = () => {
    installProgressVisible.value = false;
    extracting.value = "";
    window.location.reload();
};

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

onMounted(() => {
    fetchUploadedFiles();
});
</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;
}

.mb-10 {
    margin-bottom: 10px;
}

.mt-10 {
    margin-top: 10px;
}
</style>
