import { reactive, ref, createVNode, watch, computed } from "vue";
import { Modal, notification } from "ant-design-vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import { useI18n } from "vue-i18n";
import { useAuthStore } from "../../main/store/authStore";
import datatable from "./datatable";
import { includes, has, get, forEach } from "lodash-es";

const crud = () => {
    const {
        table,
        tableUrl,
        hashable,
        currentPage,
        handleTableChange,
        fetch,
        onTableSearch,
        onRowSelectChange,
        exportDetails,
    } = datatable();
    const detailsVisible = ref(false);
    const viewData = ref({});
    const crudUrl = ref("");
    const langKey = ref("");
    const initData = ref({});
    const hashableColumns = ref([]);
    const multiDimensalObjectColumns = ref({});

    const addEditVisible = ref(false);
    const addEditType = ref("add");
    const addEditUrl = ref("");

    const formData = ref({});
    const { t } = useI18n();
    const authStore = useAuthStore();

    const viewItem = (item) => {
        detailsVisible.value = true;
        viewData.value = item;
    };

    const addItem = () => {
        addEditUrl.value = crudUrl.value;
        addEditType.value = "add";
        addEditVisible.value = true;
        viewData.value = {};
    };

    const onCloseAddEdit = () => {
        restFormData();
        addEditVisible.value = false;
    };

    const onCloseDetails = () => {
        detailsVisible.value = false;
        viewData.value = {};
    };

    const editItem = (item) => {
        const itemDetails = {};
        var multiDimension = multiDimensalObjectColumns.value;

        Object.keys(initData.value).forEach((key) => {
            if (has(multiDimension, key)) {
                const multiDimensalObjectColumnValue = multiDimension[key];
                itemDetails[key] = get(item, multiDimensalObjectColumnValue);
            } else if (includes(hashableColumns.value, key)) {
                itemDetails[key] = item[`x_${key}`];
            } else {
                itemDetails[key] = item[key];
            }
        });

        itemDetails["_method"] = "PUT";
        formData.value = itemDetails;

        viewData.value = item;
        addEditUrl.value = `${crudUrl.value}/${item.xid}`;
        addEditType.value = "edit";
        addEditVisible.value = true;
    };

    const reSetFormData = (obj) => {
        const type = obj.type.trim();
        if (formData.value && formData.value[type] === undefined) {
            formData.value[type] = obj.id;
        }
    };

    // Update Visible Subscription Modules
    const updateSubscriptionModules = () => {
        authStore.updateVisibleSubscriptionModulesAction();
    };

    const addEditSuccess = (id) => {
        // If add action is performed then move page to first
        if (addEditType.value == "add") {
            const pagination = { ...table.pagination };
            pagination.current = 1;
            currentPage.value = 1;
            table.pagination = pagination;
        }

        // Update Visible Subscription Modules
        updateSubscriptionModules();

        restFormData();

        fetch({
            page: addEditType.value == "add" ? 1 : currentPage.value,
            limit: 10,
        });
        addEditVisible.value = false;
    };

    const showDeleteConfirm = (id) => {
        Modal.confirm({
            title: t("common.delete") + "?",
            icon: createVNode(ExclamationCircleOutlined),
            content: t(`${langKey.value}.delete_message`),
            centered: true,
            okText: t("common.yes"),
            okType: "danger",
            cancelText: t("common.no"),
            onOk() {
                return axiosAdmin
                    .delete(`${crudUrl.value}/${id}`)
                    .then((successResponse) => {
                        // Update Visible Subscription Modules
                        updateSubscriptionModules();

                        fetch({
                            page: currentPage.value,
                        });

                        notification.success({
                            message: t("common.success"),
                            description: t(`${langKey.value}.deleted`),
                            placement: "bottomRight",
                        });
                    })
                    .catch(() => { });
            },
            onCancel() { },
        });
    };

    const showSelectedDeleteConfirm = () => {
        Modal.confirm({
            title: t("common.delete") + "?",
            icon: createVNode(ExclamationCircleOutlined),
            content: t(`${langKey.value}.selected_delete_message`),
            centered: true,
            okText: t("common.yes"),
            okType: "danger",
            cancelText: t("common.no"),
            onOk() {
                const allDeletePromise = [];
                forEach(table.selectedRowKeys, (selectedRow) => {
                    allDeletePromise.push(
                        axiosAdmin.delete(`${crudUrl.value}/${selectedRow}`)
                    );
                });

                Promise.all(allDeletePromise).then((successResponse) => {
                    // Update Visible Subscription Modules
                    updateSubscriptionModules();

                    fetch({
                        page: currentPage.value,
                    });

                    notification.success({
                        message: t("common.success"),
                        description: t(`${langKey.value}.deleted`),
                        placement: "bottomRight",
                    });
                });
            },
            onCancel() { },
        });
    };

    const restFormData = () => {
        formData.value = { ...initData.value };
    };

    const assignNewFormData = (newObject) => {
        formData.value = {
            ...formData.value,
            ...newObject,
        };
    };

    const pageTitle = computed(() => {
        if (langKey.value != "") {
            return addEditType.value == "add"
                ? t(`${langKey.value}.add`)
                : t(`${langKey.value}.edit`);
        } else {
            return "";
        }
    });

    const successMessage = computed(() => {
        if (langKey.value != "") {
            return addEditType.value == "add"
                ? t(`${langKey.value}.created`)
                : t(`${langKey.value}.updated`);
        } else {
            return "";
        }
    });

    watch(hashableColumns, (newVal, oldVal) => {
        hashable.value = newVal;
    });

    return {
        detailsVisible,
        viewData,
        onCloseDetails,
        addEditVisible,
        addEditType,
        addEditUrl,
        currentPage,
        formData,
        initData,
        crudUrl,
        langKey,
        hashableColumns,
        multiDimensalObjectColumns,
        pageTitle,
        successMessage,

        viewItem,
        addItem,
        editItem,
        onCloseAddEdit,
        showDeleteConfirm,
        addEditSuccess,
        restFormData,
        assignNewFormData,
        showSelectedDeleteConfirm,

        table,
        tableUrl,
        handleTableChange,
        fetch,
        onTableSearch,
        onRowSelectChange,
        exportDetails,
        reSetFormData,
    };
};

export default crud;
