<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, provide, ref, watch } from 'vue';
import { onBeforeRouteLeave } from 'vue-router';
import { ElMessageBox } from 'element-plus';
import { GridItem, GridLayout } from 'grid-layout-plus';
import { useWorkbenchStore } from '@/store/modules/workbench';
import { type WorkbenchModuleKey, useWorkbenchModules } from './composables/use-workbench-modules';
import type { WorkbenchGridItem } from './composables/workbench-layout-types';
import WorkbenchBanner from './modules/workbench-banner.vue';
import WorkbenchEditOverlay from './modules/workbench-edit-overlay.vue';
import WorkbenchModuleLibrary from './modules/workbench-module-library.vue';
// 保留 6 个 + 重构 2 个（key 沿用）
import WorkbenchTodoPanel from './modules/workbench-todo-panel.vue';
import WorkbenchProjectGrid from './modules/workbench-project-grid.vue';
import WorkbenchShortcut from './modules/workbench-shortcut.vue';
import WorkbenchProjectHealth from './modules/workbench-project-health.vue';
// 新增 10 个（蓝图 2026-05-22，原 A3 myTicket、A4 mentions、A5 approval、A6 worklogReminder、B10 personalItem、F23 projectSnapshot 已废弃）
import WorkbenchMyExecution from './modules/workbench-my-execution.vue';
import WorkbenchProductSnapshot from './modules/workbench-product-snapshot.vue';
import WorkbenchTeamLoad from './modules/workbench-team-load.vue';
import WorkbenchMyWeekWorklog from './modules/workbench-my-week-worklog.vue';

defineOptions({ name: 'Workbench' });

const { registerModuleComponent, getModuleMeta } = useWorkbenchModules();
// 保留 6 个 + 重构 2 个
registerModuleComponent('myTodo', WorkbenchTodoPanel);
registerModuleComponent('myProject', WorkbenchProjectGrid);
registerModuleComponent('shortcut', WorkbenchShortcut);
registerModuleComponent('projectHealth', WorkbenchProjectHealth);
// 新增 10 个
registerModuleComponent('myExecution', WorkbenchMyExecution);
registerModuleComponent('productSnapshot', WorkbenchProductSnapshot);
registerModuleComponent('teamLoad', WorkbenchTeamLoad);
registerModuleComponent('myWeekWorklog', WorkbenchMyWeekWorklog);

const workbench = useWorkbenchStore();
const libraryOpen = ref(false);

// 暴露给 workbench-module-card 内的"编辑布局"按钮，避免每个 widget 都透传 emit
provide('workbenchEnterEditing', () => workbench.enterEditing());

onMounted(() => {
  workbench.load();
});

function onBeforeUnload(e: BeforeUnloadEvent) {
  if (workbench.mode === 'editing' && workbench.dirty) {
    e.preventDefault();
    e.returnValue = '';
  }
}
onMounted(() => window.addEventListener('beforeunload', onBeforeUnload));
onBeforeUnmount(() => window.removeEventListener('beforeunload', onBeforeUnload));

watch(
  () => workbench.error,
  err => {
    if (err) window.$message?.error(`布局保存失败：${err.message}`);
  }
);

const editing = computed(() => workbench.mode === 'editing');

function onGridUpdated(grid: WorkbenchGridItem[]) {
  workbench.updateGrid(grid);
}

async function handleReset() {
  try {
    await ElMessageBox.confirm('重置后将恢复默认布局，确认继续？', '重置默认布局', { type: 'warning' });
    await workbench.resetToDefault();
  } catch {
    /* cancelled */
  }
}

onBeforeRouteLeave(async (_to, _from, next) => {
  if (workbench.mode === 'editing' && workbench.dirty) {
    try {
      await ElMessageBox.confirm('编辑布局未保存，确认离开？', '确认离开', { type: 'warning' });
      workbench.cancelEditing();
      next();
    } catch {
      next(false);
    }
  } else {
    next();
  }
});
</script>

<template>
  <div class="workbench">
    <WorkbenchBanner />

    <WorkbenchEditOverlay
      v-if="workbench.mode === 'editing'"
      :dirty="workbench.dirty"
      :saving="workbench.saving"
      @save="workbench.saveEditing"
      @cancel="workbench.cancelEditing"
      @reset="handleReset"
      @open-library="libraryOpen = true"
    />

    <ElEmpty v-if="workbench.layout.grid.length === 0" description="还没有可见模块">
      <ElButton type="primary" @click="workbench.enterEditing">添加模块</ElButton>
    </ElEmpty>

    <div v-else class="workbench__main">
      <GridLayout
        :layout="workbench.layout.grid"
        :col-num="12"
        :row-height="10"
        :margin="[16, 16]"
        :is-draggable="editing"
        :is-resizable="editing"
        :vertical-compact="true"
        :use-css-transforms="true"
        @layout-updated="onGridUpdated"
      >
        <GridItem
          v-for="item in workbench.layout.grid"
          :key="item.i"
          :i="item.i"
          :x="item.x"
          :y="item.y"
          :w="item.w"
          :h="item.h"
          :min-w="item.minW"
          :min-h="item.minH"
          drag-allow-from=".module-card__head"
        >
          <component
            :is="getModuleMeta(item.i)?.component"
            :module-key="item.i"
            :editing="editing"
            @hide="workbench.hideModule(item.i as WorkbenchModuleKey)"
            @open-settings="() => {}"
          />
        </GridItem>
      </GridLayout>
    </div>

    <WorkbenchModuleLibrary
      v-model="libraryOpen"
      :hidden-metas="workbench.hiddenMetas"
      @add-module="
        key => {
          workbench.showModule(key);
          libraryOpen = false;
        }
      "
    />
  </div>
</template>

<style scoped>
.workbench {
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow-x: auto;
}
.workbench__main {
  min-width: 1100px;
}
</style>
