<script setup>
import Collapse from "@/components/customUI/FileSystemCollapse.vue";
import GraphSidebarDropdown from "./GraphSidebarDropdown.vue";
import {
  getSideBar,
  updateSideBarTreeName,
  removeSideBarTreeName,
  addSideBarTreeName,
} from "@/apis/graph";
import { ref, onMounted, onUnmounted, provide, computed, inject } from "vue";
import useSearchParams from "@/hooks/useSearchParam";

const { openToast, cancelToastOpen } = inject("app_toast");
const { changeParams, searchParams } = useSearchParams();

let raw_data = ref([]);

const { updateCurrentDir } = inject("current_dir");

// 處理data資料
const graphData = computed(() => {
  let data = raw_data.value.map((d) => ({ ...d, children: [] }));
  let formatD = [];
  data
    .sort((a, b) => b.parent_id - a.parent_id)
    .forEach((d) => {
      if (d.parent_id === 0) {
        formatD.push({ ...d, key: d.id, title: d.name });
      } else {
        let parent = data.find(({ id }) => id === d.parent_id);
        if (parent) {
          parent.children = [
            ...(parent?.children || []),
            { ...d, key: d.id, title: d.name },
          ];
        }
      }
    });
  changeParams({ id: searchParams.value.id || formatD[0]?.id });
  updateCurrentDir(
    data.find((d) => d.id === parseInt(searchParams.value.id)) || formatD[0]
  );
  return formatD;
});

const getData = async (id = "") => {
  const res = await getSideBar();
  raw_data.value = res.data;
  if (id) {
    const currentDir = raw_data.value.find((d) => parseInt(id) === d.id);
    updateCurrentDir(currentDir);
  }
  cancelDropdownAndInput();
};

const dropdownOpen = ref(false);
const selectedItem = ref(null);

const cancelOpen = () => {
  dropdownOpen.value = false;
};

const cancelDropdownAndInput = () => {
  dropdownOpen.value = false;
  filenameInputIsOpen.value = false;
};

const dropdownPosition = ref({
  x: 0,
  y: 0,
});

const sidebar = ref(null);
const onAddRightClick = (e) => {
  console.log(e);
  if (e.target.nodeName === "LI") {
    const targetPos = e.target.getBoundingClientRect();
    const sidebarPos = e.target.closest(".sidebar").getBoundingClientRect();

    dropdownPosition.value = {
      left: e.offsetX + 30,
      top: e.clientY - sidebarPos.y + targetPos.height,
    };
  } else {
    dropdownPosition.value = {
      left: e.offsetX + 30,
      top: e.offsetY + 30,
    };
  }

  selectedItem.value = null;
  dropdownOpen.value = true;
};

const onRightClick = (e, d) => {
  cancelDropdownAndInput();
  const targetPos = e.target.closest("li").getBoundingClientRect();
  const sidebarPos = e.target.closest(".sidebar").getBoundingClientRect();
  console.log("onRightClick", sidebarPos, targetPos);
  dropdownPosition.value = {
    left: targetPos.x - sidebarPos.x + targetPos.width / 2 - 50,
    top: targetPos.y - sidebarPos.y + 2 * targetPos.height + 5,
  };
  selectedItem.value = d;
  dropdownOpen.value = true;
};

const onLeftClick = (id, data) => {
  // if (data.children.length === 0) {
  updateCurrentDir(data);
  changeParams({ id });
  // } else {
  //   changeParams({});
  // }
};

const filenameInputIsOpen = ref(false);
const getNewFilename = async (e) => {
  if (selectedItem.value?.isNewDir) {
    // 新增
    const res = await addSideBarTreeName({
      parent_id: selectedItem.value?.parent_id,
      name: e?.target?.value || selectedItem.value?.title,
    });
    getData(res);
  } else if (
    e &&
    e?.target.value !== "" &&
    e?.target.value !== selectedItem.value?.title
  ) {
    // 編輯
    const res = await updateSideBarTreeName({
      id: selectedItem.value?.id,
      name: e.target.value,
    });
    getData();
  } else if (selectedItem.value) {
    // 以防資料被刪掉
    selectedItem.value.title = selectedItem.value?.name;
  }
};
// 編輯filename
const editFilename = () => {
  filenameInputIsOpen.value = true;
  cancelOpen();
};
// 新增filename
const openItem = ref([]);
const addFilename = (root = false) => {
  const newItem = {
    id: raw_data.value?.[raw_data.value.length - 1].id + 1,
    key: raw_data.value?.[raw_data.value.length - 1].id + 1,
    title: "新類別",
    name: "新類別",
    parent_id: selectedItem.value?.id || 0,
    isNewDir: true,
  };
  raw_data.value = [...raw_data.value, newItem];

  // 第二層之後
  if (!root) {
    let parent = raw_data.value.find(
      ({ id }) => id === selectedItem.value.parent_id
    );
    let ids = [selectedItem.value.id];
    while (Boolean(parent?.id)) {
      ids = [...ids, parent.id];
      parent = raw_data.value.find(({ id }) => id === parent.parent_id);
    }
    openItem.value = ids;
  }

  selectedItem.value = newItem;
  // editFilename();
};

// 刪除filename
const deleteFilename = async () => {
  openToast("warning", "是否確認刪除該項目?", "body", async () => {
    await cancelToastOpen();
    const filterData = raw_data.value.filter(({ id }) => id !== selectedItem.value.id)
    const res = await removeSideBarTreeName(selectedItem.value.id);
    if (res.isSuccess) {
      raw_data.value = filterData;
      cancelOpen();
      openToast("success", "刪除成功");
    } else {
      openToast("error", res.msg);
    }
  });
};

const onClickout = (e) => {
  e.stopPropagation();
  cancelOpen();
  getNewFilename();
  selectedItem.value = null;
  filenameInputIsOpen.value = false;
};

onMounted(() => {
  getData();
  document.querySelector("body").addEventListener("click", onClickout);
});

onUnmounted(() => {
  document.querySelector("body").removeEventListener("click", onClickout);
});
</script>

<template>
  <div
    ref="sidebar"
    class="border-2 border-info rounded-md py-2 px-4 sidebar"
    @contextmenu.prevent.stop="onAddRightClick"
  >
    <Collapse
      :open="true"
      :data="graphData"
      :onRightClick="onRightClick"
      :onClick="onLeftClick"
      :filenameInputIsOpen="filenameInputIsOpen"
      :selected="selectedItem"
      :edit="getNewFilename"
      :openItem="openItem"
    >
    </Collapse>
    <GraphSidebarDropdown
      :position="dropdownPosition"
      :open="dropdownOpen"
      :selectedItem="selectedItem"
      :edit="editFilename"
      :add="addFilename"
      :remove="deleteFilename"
    />
  </div>
</template>

<style lang="scss" scoped></style>
