<script setup>
import Menu from "~/navigation/index.js";

definePageMeta({
  title: "Menu Editor",
  middleware: ["auth"],
  requiresAuth: true,
});
const nuxtApp = useNuxtApp();

const sideMenuList = ref(Menu);

const router = useRouter();
const getRoutes = router.getRoutes();
const getNavigation = Menu ? ref(Menu) : ref([]);

const allMenus = [];

const showCode = ref(false);
let i = 1;

const searchInput = ref("");

const showModal = ref(false);
const showModalEl = ref(null);
const dropdownMenu = ref([]);
const dropdownMenuValue = ref(null);

const showModalEdit = ref(false);
const showModalEditPath = ref(null);
const showModalEditForm = ref({
  title: "",
  name: "",
  path: "",
  guardType: "",
});
// const showModalEditEl = ref(null);

const showModalAdd = ref(false);
const showModalAddForm = ref({
  title: "",
  name: "",
  path: "",
});

const kebabtoTitle = (str) => {
  if (!str) return str;
  return str
    .split("-")
    .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
    .join(" ");
};

// Sort the routes into menus
getRoutes.sort((a, b) => {
  return a.path.localeCompare(b.path);
});

//----------------------------------------------------------------------------
//-------------------------FIRST CHILD TAB ITEM (END)-------------------------
//----------------------------------------------------------------------------

// Loop through the routes and add them to the menus
getRoutes.map((menu) => {
  let visibleMenu = false;

  // Check if the menu is visible
  for (let i = 0; i < getNavigation.value.length; i++) {
    if (getNavigation.value[i].child) {
      for (let j = 0; j < getNavigation.value[i].child.length; j++) {
        if (getNavigation.value[i].child[j].path === menu.path)
          visibleMenu = true;
        else if (getNavigation.value[i].child[j].child) {
          for (
            let k = 0;
            k < getNavigation.value[i].child[j].child.length;
            k++
          ) {
            if (getNavigation.value[i].child[j].child[k].path === menu.path)
              visibleMenu = true;
          }
        }
      }
    }
  }

  if (menu.name)
    allMenus.push({
      id: i++,
      title:
        menu.meta && menu.meta.title
          ? menu.meta.title
          : kebabtoTitle(menu.name),
      parentMenu: menu.path.split("/")[1],
      name: menu.name,
      path: menu.path,
      visible: visibleMenu,
      action: "",
    });
});

const openModalEdit = (menu) => {
  showModalEditForm.value.title = menu.title;
  showModalEditForm.value.name = menu.name;

  // If there is a slash in the beggining of the path, remove it
  if (menu.path.charAt(0) === "/") {
    showModalEditForm.value.path = menu.path.slice(1);
  } else {
    showModalEditForm.value.path = menu.path;
  }

  showModalEditPath.value = menu.path;

  showModalEdit.value = true;
};

const saveEditMenu = async () => {
  const res = await useFetch("/api/devtool/menu/edit", {
    method: "POST",
    initialCache: false,
    body: JSON.stringify({
      filePath: showModalEditPath.value,
      formData: {
        title: showModalEditForm.value.title || "",
        name: showModalEditForm.value.name || "",
        path: "/" + showModalEditForm.value.path || "",
      },
      // formData: showModalEditForm.value,
    }),
  });

  const data = res.data.value;

  if (data.statusCode === 200) {
    nuxtApp.$swal.fire({
      title: "Success",
      text: data.message,
      icon: "success",
      timer: 2000,
      showConfirmButton: false,
    });
    // refresh the page
    nuxtApp.$router.go();
  }
};

const openModalAdd = () => {
  showModalAddForm.value.title = "";
  showModalAddForm.value.name = "";
  showModalAddForm.value.path = "";

  showModalAdd.value = true;
};

const saveAddMenu = async () => {
  const res = await useFetch("/api/devtool/menu/add", {
    method: "POST",
    initialCache: false,
    body: JSON.stringify({
      formData: {
        title: showModalAddForm.value.title || "",
        name: showModalAddForm.value.name || "",
        path: "/" + showModalAddForm.value.path || "",
      },
      // formData: showModalAddForm.value
    }),
  });

  const data = res.data.value;

  if (data.statusCode === 200) {
    nuxtApp.$swal.fire({
      title: "Success",
      text: data.message,
      icon: "success",
      timer: 2000,
      showConfirmButton: false,
    });
    // refresh the page
    nuxtApp.$router.go();
  } else {
    nuxtApp.$swal.fire({
      title: "Error",
      text: data.message,
      icon: "error",
      timer: 2000,
      showConfirmButton: false,
    });
  }
};

const deleteMenu = async (menu) => {
  nuxtApp.$swal
    .fire({
      title: "Are you sure?",
      text: "You won't be able to revert this!",
      icon: "warning",
      showCancelButton: true,
      confirmButtonColor: "#3085d6",
      cancelButtonColor: "#d33",
      confirmButtonText: "Yes, delete it!",
    })
    .then(async (result) => {
      if (result.isConfirmed) {
        const res = await useFetch("/api/devtool/menu/delete", {
          method: "POST",
          initialCache: false,
          body: JSON.stringify({
            filePath: menu.path,
          }),
        });

        const data = res.data.value;

        if (data.statusCode === 200) {
          nuxtApp.$swal.fire({
            title: "Deleted!",
            text: data.message,
            icon: "success",
            timer: 2000,
            showConfirmButton: false,
          });

          // refresh the page
          nuxtApp.$router.go();
        }
      }
    });
};

//----------------------------------------------------------------------------
//-------------------------FIRST CHILD TAB ITEM (END)-------------------------
//----------------------------------------------------------------------------

//-----------------------------------------------------------------------
//-------------------------SECOND CHILD TAB ITEM-------------------------
//-----------------------------------------------------------------------

const checkExistSideMenuList = (path) => {
  let exist = false;
  sideMenuList.value.map((menu) => {
    // Search child path
    if (menu.child) {
      menu.child.map((child) => {
        if (child.path == path) {
          exist = true;
        }

        if (child.child) {
          child.child.map((child2) => {
            if (child2.path == path) {
              exist = true;
            }
          });
        }
      });
    }
  });
  return exist;
};

const menuList = computed(() => {
  // If the search input is empty, return all menus
  if (searchInput.value === "") {
    return allMenus;
  } else {
    // If the search input is not empty, filter the menus
    return allMenus.filter((menu) => {
      return menu.name.toLowerCase().includes(searchInput.value.toLowerCase());
    });
  }
});

// Clone draggable item
const clone = (obj) => {
  return JSON.parse(
    JSON.stringify({
      title: obj.title,
      path: obj.path,
      icon: obj.icon ? obj.icon : "",
      child: [],
    })
  );
};

// Add Header
const addNewHeader = () => {
  // Push index = 1
  sideMenuList.value.splice(1, 0, {
    header: "New Header",
    description: "New Description",
    child: [],
  });
};

// changeSideMenuList
const changeSideMenuList = (menus) => {
  sideMenuList.value = menus;
};

// Save the menu
const overwriteJsonFileLocal = async (menus) => {
  const res = await useFetch("/api/devtool/menu/overwrite-navigation", {
    method: "POST",
    initialCache: false,
    body: JSON.stringify({
      menuData: menus,
    }),
  });

  const data = res.data.value;

  if (data.statusCode === 200) {
    nuxtApp.$swal.fire({
      title: "Success",
      text: data.message,
      icon: "success",
      timer: 2000,
      showConfirmButton: false,
    });

    // refresh the page
    nuxtApp.$router.go();
  }
};

// open modal
const openModal = (menu) => {
  showModalEl.value = menu;

  // Get All Menu includes child and assign to dropdownMenu in one array
  let i = 0;
  dropdownMenu.value = [
    {
      label: "Choose Menu",
      value: null,
      attrs: {
        disabled: true,
      },
    },
  ];

  sideMenuList.value.map((menu) => {
    if (menu.header || menu.description) {
      dropdownMenu.value.push({
        label: `${menu.header} (Header)`,
        value: `header|${i}`,
      });
    } else if (menu.hasOwnProperty("header")) {
      dropdownMenu.value.push({
        label: `<No Header Name> (Header)`,
        value: `header|${i}`,
      });
    }

    if (menu.child) {
      menu.child.map((child) => {
        dropdownMenu.value.push({
          label: `${child.title} (Menu)`,
          value: `menu|${child.path}`,
        });
      });
    }

    i++;
  });

  showModal.value = true;
};

// Add new menu from list
const addMenuFromList = () => {
  if (dropdownMenuValue.value) {
    const menuType = dropdownMenuValue.value.split("|")[0];
    const menuValue = dropdownMenuValue.value.split("|")[1];

    if (menuType === "header") {
      // Add Header
      sideMenuList.value[menuValue].child.push(clone(showModalEl.value));
    } else if (menuType === "menu") {
      // Add Menu
      sideMenuList.value.map((menu) => {
        if (menu.child) {
          menu.child.map((child) => {
            if (child.path == menuValue) {
              child.child.push(clone(showModalEl.value));
            }
          });
        }
      });
    }

    showModal.value = false;
  }
};

//-----------------------------------------------------------------------------
//-------------------------SECOND CHILD TAB ITEM (END)-------------------------
//-----------------------------------------------------------------------------
</script>

<template>
  <div>
    <LayoutsBreadcrumb />

    <rs-card>
      <template #header>
        <div class="flex">
          <Icon class="mr-2 flex justify-center" name="ic:outline-info"></Icon
          >Info
        </div>
      </template>
      <template #body>
        <p class="mb-4">
          This page is used to edit the menu of the website. You can add, edit,
          and delete menu items. You can also change the order of the menu items
          by dragging and dropping them.
        </p>
      </template>
    </rs-card>

    <rs-card>
      <div class="pt-2">
        <rs-tab fill>
          <rs-tab-item title="All Menu">
            <div class="flex justify-end items-center mb-4">
              <rs-button @click="openModalAdd">
                <Icon name="material-symbols:add" class="mr-1"></Icon>
                Add Menu
              </rs-button>
            </div>
            <!-- Table All Menu -->
            <rs-table
              :data="allMenus"
              :options="{
                variant: 'default',
                striped: true,
                borderless: true,
              }"
              :options-advanced="{
                sortable: true,
                filterable: false,
                responsive: false,
              }"
              advanced
            >
              <template v-slot:name="data">
                <NuxtLink
                  class="text-primary hover:underline"
                  :to="data.value.path"
                  target="_blank"
                  >{{ data.text }}</NuxtLink
                >
              </template>
              <template v-slot:visible="data">
                <div class="flex items-center">
                  <Icon
                    name="mdi:eye-outline"
                    class="text-primary"
                    size="22"
                    v-if="data.value.visible"
                  />
                  <Icon
                    name="mdi:eye-off-outline"
                    class="text-primary/20"
                    size="22"
                    v-else
                  />
                </div>
              </template>
              <template v-slot:action="data">
                <div
                  class="flex items-center"
                  v-if="data.value.parentMenu != 'admin'"
                >
                  <Icon
                    name="material-symbols:edit-outline-rounded"
                    class="text-primary hover:text-primary/90 cursor-pointer mr-1"
                    size="22"
                    @click="openModalEdit(data.value)"
                  ></Icon>
                  <Icon
                    name="material-symbols:close-rounded"
                    class="text-primary hover:text-primary/90 cursor-pointer"
                    size="22"
                    @click="deleteMenu(data.value)"
                  ></Icon>
                </div>
                <div class="flex items-center" v-else>-</div>
              </template>
            </rs-table>
          </rs-tab-item>
          <rs-tab-item title="Manage Side Menu">
            <div class="flex justify-end items-center mb-4">
              <rs-button
                class="mr-2"
                @click="showCode ? (showCode = false) : (showCode = true)"
              >
                <Icon name="ic:baseline-code" class="mr-2"></Icon>
                {{ showCode ? "Hide" : "Show" }} JSON Code
              </rs-button>
              <rs-button @click="overwriteJsonFileLocal(sideMenuList)">
                <Icon name="mdi:content-save-outline" class="mr-2"></Icon>
                Save Menu
              </rs-button>
            </div>

            <div class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 gap-5">
              <div>
                <FormKit
                  type="search"
                  placeholder="Search Menu..."
                  outer-class="mb-5"
                  v-model="searchInput"
                />
                <NuxtScrollbar
                  style="height: 735px"
                  class="px-5 pt-5 border border-[rgb(var(--border-color))] bg-[rgb(var(--bg-1))] rounded-md"
                >
                  <draggable
                    item-key="id"
                    v-model="menuList"
                    :group="{ name: 'menu', pull: 'clone', put: false }"
                    :clone="clone"
                    :sort="false"
                  >
                    <template #item="{ element }">
                      <rs-card class="p-4 mb-4 border-2 border-[rgb(var(--border-color))] !shadow-none">
                        <div class="flex justify-between items-center">
                          <p>
                            {{ kebabtoTitle(element.name) }} (
                            <NuxtLink
                              class="text-primary hover:underline"
                              :to="element.path"
                              target="_blank"
                            >
                              {{ element.path }}
                            </NuxtLink>
                            )
                          </p>
                          <Icon
                            v-if="checkExistSideMenuList(element.path) == false"
                            name="ic:baseline-arrow-circle-right"
                            class="text-primary cursor-pointer transition-all duration-150 hover:scale-110"
                            @click="openModal(element)"
                          ></Icon>
                        </div>
                      </rs-card>
                    </template>
                  </draggable>
                </NuxtScrollbar>
              </div>
              <NuxtScrollbar v-if="!showCode" style="height: 825px">
                <rs-card
                  class="p-4 border border-[rgb(var(--border-color))] bg-[rgb(var(--bg-1))] rounded-md"
                >
                  <div class="flex justify-end items-center">
                    <rs-button
                      class="!p-2 mt-3 justify-center items-center"
                      @click="addNewHeader"
                    >
                      <Icon
                        class="mr-1"
                        name="material-symbols:docs-add-on"
                        size="18"
                      ></Icon>
                      Add Header
                    </rs-button>
                  </div>
                  <DraggableSideMenuNested
                    :menus="sideMenuList"
                    @changeSideMenu="changeSideMenuList"
                  />
                </rs-card>
              </NuxtScrollbar>
              <pre v-else v-html="JSON.stringify(sideMenuList, null, 2)"></pre>
            </div>
          </rs-tab-item>
        </rs-tab>
      </div>
    </rs-card>

    <rs-modal
      title="Select Menu"
      v-model="showModal"
      ok-title="Confirm"
      :ok-callback="addMenuFromList"
    >
      <FormKit
        label="Please Select Menu or Header"
        help="Select menu or header to add as their child menu"
        type="select"
        v-model="dropdownMenuValue"
        :options="dropdownMenu"
      ></FormKit>
    </rs-modal>

    <rs-modal
      title="Edit Menu"
      v-model="showModalEdit"
      ok-title="Save"
      :ok-callback="saveEditMenu"
    >
      <FormKit
        type="text"
        label="Title"
        v-model="showModalEditForm.title"
      ></FormKit>
      <FormKit
        type="text"
        label="Name"
        v-model="showModalEditForm.name"
      ></FormKit>
      <FormKit
        type="text"
        label="Path"
        help="If the last path name is '/', the name of the file will be from its name property. While if the last path name is not '/', the name of the file will be from its path property."
        v-model="showModalEditForm.path"
      >
        <template #prefix>
          <div class="bg-slate-100 h-full rounded-l-md p-3">/</div>
        </template>
      </FormKit>
    </rs-modal>

    <rs-modal
      title="Add Menu"
      v-model="showModalAdd"
      ok-title="Save"
      :ok-callback="saveAddMenu"
    >
      <FormKit
        type="text"
        label="Title"
        v-model="showModalAddForm.title"
      ></FormKit>
      <FormKit
        type="text"
        label="Name"
        v-model="showModalAddForm.name"
      ></FormKit>
      <FormKit
        type="text"
        label="Path"
        help="If the last path name is '/', the name of the file will be from its name property. While if the last path name is not '/', the name of the file will be from its path property."
        v-model="showModalAddForm.path"
      >
        <template #prefix>
          <div class="bg-slate-100 dark:bg-slate-700 h-full rounded-l-md p-3">
            /
          </div>
        </template>
      </FormKit>
    </rs-modal>
  </div>
</template>
