<template>
  <div class="vtj-files__wrapper">
    <ListPanel
      v-if="!outlineVisible && !historyVisible"
      class="vtj-files"
      title="文件管理器"
      :subtitle="project.name"
      :tools="tools"
      @tool-click="handleToolClick"
      v-bind="$attrs">
      <div v-if="project.files.length" class="vtj-files__list">
        <DataItem
          v-for="doc in project.files"
          :key="doc.id"
          editable
          removable
          clickable
          :active="doc === project.current"
          @click="changeDocument(doc as IFile)"
          @edit="handleEdit(doc as IFile)"
          @remove="handleRemove(doc as IFile)">
          <template #title>
            <span class="vtj-files__title">
              {{ doc.fileName }}<i :class="`is-${doc.name}`">{{ doc.name }}</i>
            </span>
          </template>
          <template #action>
            <i
              v-if="doc === project.current"
              @click="openShare"
              class="vtj-icon-share"
              title="共享"></i>
            <i
              v-if="doc === project.current"
              @click.stop="openCodeFactory(doc as IFile)"
              class="vtj-icon-setting"
              title="页面设置"></i>
            <i
              v-if="doc === project.current"
              @click.stop="openOutline(doc as IFile)"
              class="vtj-icon-outline"
              title="大纲树"></i>
            <i
              v-if="doc === project.current"
              @click.stop="openHistroy(doc as IFile)"
              class="vtj-icon-history"
              title="历史记录"></i>
            <i
              v-if="doc.name === 'Page'"
              @click.stop="setHomePage(doc as IFile)"
              class="vtj-icon-home"
              :class="{ 'is-active': project.homePageId === doc.id }"
              title="设为首页"></i>
          </template>
        </DataItem>
      </div>
      <ElEmpty v-else description="暂无数据"></ElEmpty>
      <FileForm
        v-if="fromVisible"
        v-model="fromVisible"
        :file="(currentFile as IFile)"
        @submit="handleSubmit"
        width="500px"></FileForm>
    </ListPanel>
    <CodeFactory
      v-if="codeFile"
      :key="codeFile.id"
      v-model="codeVisible"
      :file="codeFile"
      :subtitle="codeFile.fileName"></CodeFactory>
    <Outline
      v-if="outlineVisible && project.current"
      @back="outlineVisible = false"
      :subtitle="project.current.fileName"></Outline>
    <HistoryPanel
      v-if="historyVisible && project.current && history"
      :history="history"
      @back="historyVisible = false"
      :subtitle="project.current.fileName"></HistoryPanel>
    <Share
      v-if="project.current && shareVisible"
      v-model="shareVisible"
      :file="project.current"></Share>
  </div>
</template>
<script lang="ts" setup>
import { ref, onUnmounted } from 'vue';
import {
  ListPanel,
  IFile,
  DataItem,
  History,
  EVENT_NODE_CHANGE,
  EVENT_HISTORY_CHANGE,
  EVENT_RENDERER_UPDATE,
  EVENT_PROJECT_UPDATE_FILE
} from '@vtj/engine';
import FileForm from '../parts/FileForm.vue';
import CodeFactory from '../parts/CodeFactory.vue';
import { ElEmpty, ElMessageBox, ElMessage } from 'element-plus';
import useCore from '../hooks/useCore';
import Outline from './Outline.vue';
import HistoryPanel from './History.vue';
import Share from '../parts/Share.vue';

const { project, service, emitter, engine } = useCore();
const tools = [{ name: 'add', icon: 'vtj-icon-plus' }];
const fromVisible = ref(false);
const codeVisible = ref(false);
const currentFile = ref<IFile>();
const codeFile = ref<IFile>();
const outlineVisible = ref(false);
const historyVisible = ref(false);
const history = ref<History>();
const shareVisible = ref(false);

initHistory();

async function initHistory() {
  if (project.current) {
    const list = await service.getFileHistories(engine, project.current.id);
    history.value = new History(list);
  }
}

function handleToolClick(item: any) {
  if (item.name === 'add') {
    fromVisible.value = true;
    currentFile.value = undefined;
  }
}

function handleEdit(file: IFile) {
  fromVisible.value = true;
  currentFile.value = file;
}

async function handleRemove(file: IFile) {
  const ret = await ElMessageBox.confirm('是否确认删除?', '提示', {
    type: 'warning'
  });

  if (ret) {
    project.removeFile(file);
  }
}

function handleSubmit(model: any) {
  fromVisible.value = false;
  if (currentFile.value) {
    project.updateFile({
      id: currentFile.value.id,
      ...model
    });
  } else {
    project.createFile(model);
  }
}

async function changeDocument(file: IFile) {
  const schema = await service.getFile(engine, file.id);
  project.loadFile(schema);
  const list = await service.getFileHistories(engine, file.id);
  history.value = new History(list);
}

function openCodeFactory(file: IFile) {
  codeFile.value = file;
  codeVisible.value = true;
}

function openOutline(file: IFile) {
  outlineVisible.value = true;
}

function openHistroy(file: IFile) {
  historyVisible.value = true;
}

function openShare() {
  shareVisible.value = true;
}

function setHomePage(file: IFile) {
  project.update({
    homePageId: file.id
  });
  ElMessage.success({
    message: '设置首页成功'
  });
}

function historyGo() {
  history.value?.go();
}

function historyBack() {
  history.value?.back();
}

const handleNodeChange = async () => {
  console.log('handleNodeChange');
  if (project.current) {
    const list = await service.getFileHistories(engine, project.current.id);
    history.value?.refresh(list);
  }
};

const handleHistoryChange = async (id: string) => {
  console.log('handleHistoryChange');
  if (project.current) {
    const schema = await service.getHistory(
      engine,
      project.current.id,
      id as string
    );
    project.loadFile(schema);
    emitter.emit(EVENT_RENDERER_UPDATE, schema);
    emitter.emit(EVENT_PROJECT_UPDATE_FILE, project.current);
  }
};

emitter.on(EVENT_NODE_CHANGE, handleNodeChange);
emitter.on(EVENT_HISTORY_CHANGE, handleHistoryChange as any);

onUnmounted(() => {
  emitter.off(EVENT_NODE_CHANGE, handleNodeChange);
  emitter.off(EVENT_HISTORY_CHANGE, handleHistoryChange as any);
});

defineExpose({
  openCodeFactory,
  openOutline,
  historyGo,
  historyBack
});
</script>
