<template>
  <div class="h-full flex flex-col">
    <div class="box-border flex items-center justify-between w-full px-[15px] py-[10px]">
      <span class="font-bold text-base">目录</span>
      <NButton v-if="treeData.length <= 0" type="primary" ghost size="small" @click="importBook">
        <template #icon>
          <div class="i-icon-park-outline-file-pdf" />
        </template>
        导入书籍
      </NButton>
      <NButton v-else type="primary" ghost size="small" @click="setStartPage">
        <template #icon>
          <div class="i-icon-park-outline-file-pdf" />
        </template>
        重置起始页
      </NButton>
    </div>
    <div class="flex-1 overflow-hidden relative">
      <NSpin :show="pageLoading" class="h-full">
        <NScrollbar class="h-full">
          <NTree
            block-line
            :data="treeData"
            key-field="id"
            label-field="name"
            children-field="childs"
            :default-expanded-keys="[1]"
            :node-props="nodeProps"
            @update:selected-keys="handleSelectedKeysChange"
          >
            <template #label="{ option }">
              <div class="flex items-center justify-between w-full pr-2 group">
                <span class="truncate">{{ option.name }}</span>
                <div class="flex items-center">
                   <span v-if="option.type === 1 && option.verifyStatus === 1" class="text-xs text-green-500 ml-2">校验成功</span>
                   <span v-else-if="option.type === 1 && option.verifyStatus === 2" class="text-xs text-red-500 ml-2">校验失败</span>
                </div>
              </div>
            </template>
          </NTree>
        </NScrollbar>
        <div v-if="!treeData.length && !pageLoading" class="absolute inset-0 flex items-center justify-center">
          <NEmpty description="暂无数据">
            <template #extra>
              <NButton size="small" @click="getBaseDataAxios">
                重新加载
              </NButton>
            </template>
          </NEmpty>
        </div>
      </NSpin>
    </div>
    <ImportBubble ref="importBubbleRef" />
    <MenuBubble ref="menuBubbleRef" />
  </div>
</template>

<script setup lang="ts">
import { ref, shallowReactive, onMounted, useTemplateRef } from 'vue';
import { useRoute } from 'vue-router';
import { useMessage, NButton, NSpin, NScrollbar, NTree, NEmpty, type TreeOption } from 'naive-ui';
import MenuBubble from './components/menu-bubble.vue';
import ImportBubble from './components/import-bubble.vue';
import {
  type BookBaseData,
  type CatalogTree,
  getBookBaseInfoAxios,
  getBookCatalogTreeAxios,
  getBookPageDetailAxios,
  setStartPageAxios,
} from '@/service/api/book';
import type { CurrBookPageAllInfo } from '@/views/template/template-detail/types';

const emit = defineEmits<{
  (e: 'switchBookPage', data: CurrBookPageAllInfo): void;
}>();

const route = useRoute();
const message = useMessage();
const bookId = ref<number>(Number(route.query.bookId));
const menuBubbleRef = useTemplateRef('menuBubbleRef');
const importBubbleRef = useTemplateRef('importBubbleRef');
const treeData = ref<CatalogTree[]>([]);
const bookData = ref<BookBaseData>({});
const currPage = ref<number | string>(-1);
const pageLoading = ref(false);

const treeAxiosData = shallowReactive<Record<number, CurrBookPageAllInfo>>({});

onMounted(() => {
  if (bookId.value) {
    getBaseDataAxios();
  }
});

async function getBaseDataAxios() {
  try {
    pageLoading.value = true;
    const res = await getBookBaseInfoAxios({ id: bookId.value });
    if (res.data) {
        bookData.value = res.data;
    }
    await getTreeData();
  } catch (e) {
      console.error(e);
  } finally {
      pageLoading.value = false;
  }
}

async function getTreeData() {
  try {
    const res = await getBookCatalogTreeAxios({ bookId: bookId.value });
    if (res.data) {
        treeData.value = res.data;
    }
  } catch (e) {
      console.error(e);
  }
}

function nodeProps({ option }: { option: TreeOption }) {
  return {
    onClick() {
      nodeClick(option);
    },
    onContextmenu(e: MouseEvent) {
      nodeContextmenu(e, option);
    }
  };
}

async function nodeClick(option: TreeOption) {
  const data = option as unknown as CatalogTree;
  // If it has children or not type 1 (page?), maybe don't load page details?
  // Logic from original code:
  // if (data.childs?.length || data.type !== 1 || currPage.value === data.id) return;

  if (data.childs?.length || data.type !== 1) {
      // It's a folder or non-page node
      return;
  }

  if (currPage.value === data.id) return;

  currPage.value = data.id;
  if (treeAxiosData[data.id]) {
    emit('switchBookPage', treeAxiosData[data.id]!);
  } else {
    await getCurrPageData(data.id);
  }
}

function handleSelectedKeysChange(keys: Array<string | number>) {
    // Optional: sync selection state if needed
}

async function getCurrPageData(pageId: number) {
  pageLoading.value = true;
  try {
    const res = await getBookPageDetailAxios({ pageId });
    if (res.data) {
        treeAxiosData[pageId] = res.data;
        emit('switchBookPage', res.data);
    }
  } catch (e) {
      console.error(e);
      message.error('获取页面详情失败');
  } finally {
    pageLoading.value = false;
  }
}

function importBook() {
  importBubbleRef.value?.show({
      bookInfo: bookData.value,
      affirmCallBack: () => {
          getTreeData();
      }
  });
}

async function setStartPage() {
    importBubbleRef.value?.show({
      bookInfo: bookData.value,
      affirmCallBack: () => {
          getTreeData();
      }
  });
}

function nodeContextmenu(e: MouseEvent, option: TreeOption) {
  e.preventDefault();
  menuBubbleRef.value?.show({
      event: e,
      treeData: option as unknown as CatalogTree,
      bookId: bookId.value,
      renameCallBack: (name: string) => {
          option.name = name;
      }
  });
}
</script>

<style scoped>
/* UnoCSS handled styles */
</style>
