<script setup lang="ts">
import type { FlowKeyType } from '../flowProperties.ts';
import { computed, inject, ref, watch } from 'vue';
import { flowProperties } from '../flowProperties.ts';
import { useSelectedInfoStore } from '../stores/selectedInfo.ts';

import ApprovalMode from './components/approvalMode.vue';
import CustomConfiguration from './components/customConfiguration.vue';
import EdgeTransfer from './components/edgeTransfer.vue';
import ExecutionListener from './components/executionListener.vue';
import ExpandAttribute from './components/expandAttribute.vue';
import FlowMessageAndSignal from './components/flowMessageAndSignal.vue';
import FlowNormal from './components/flowNormal.vue';
import FormComponent from './components/formComponent.vue';
import Normal from './components/normal.vue';
import Other from './components/other.vue';
import TaskListener from './components/taskListener.vue';
import UserTask from './components/userTask.vue';

defineOptions({ name: 'RightPanel' });

const lf: any = inject('lf');
// 收起状态：true 表示缩成按钮
const collapsed = ref(true);
// 折叠前保存的 activeKey，以便展开时恢复
const savedActiveKey = ref<string[] | null>(null);
const selectedInfoStore = useSelectedInfoStore();
const activeKey = ref<string[]>(['1']);
// 控制折叠/展开的宽度
const expandedWidth = 500; // 默认展开宽度（和样式中的一致）

function toggleCollapsed() {
  if (!collapsed.value) {
    // 正在折叠，保存当前展开的面板状态并收起
    savedActiveKey.value = [...activeKey.value];
    activeKey.value = [];
    collapsed.value = true;
  }
  else {
    // 展开，恢复面板状态
    collapsed.value = false;
    activeKey.value = savedActiveKey.value && savedActiveKey.value.length ? savedActiveKey.value : ['1'];
    savedActiveKey.value = null;
  }
}

// attr key -> component 映射
const attrComponentMap: Record<string, any> = {
  normal: Normal,
  flowNormal: FlowNormal,
  formComponent: FormComponent,
  flowMessageAndSignal: FlowMessageAndSignal,
  executionListener: ExecutionListener,
  expandAttribute: ExpandAttribute,
  other: Other,
  approveMethod: ApprovalMode,
  taskListener: TaskListener,
  userTask: UserTask,
  edgeTransfer: EdgeTransfer,
  customConfiguration: CustomConfiguration,
};

// attr key -> 面板标题映射
const headerMap: Record<string, string> = {
  normal: '常规',
  flowNormal: '常规',
  formComponent: '表单',
  flowMessageAndSignal: '消息与信号',
  executionListener: '执行监听器',
  expandAttribute: '扩展属性',
  other: '其他',
  approveMethod: '多人审批方式',
  taskListener: '任务监听器',
  userTask: '用户任务',
  edgeTransfer: '流转条件',
  customConfiguration: '自定义配置',
};

// 根据当前选中类型计算要渲染的 attrs 列表
const attrs = computed(() => {
  // console.log('right panel selected type:', selectedInfoStore.selectType);
  const type = (selectedInfoStore.selectType ?? 'flow') as FlowKeyType;
  // 当是边属性时， 如果边的起始节点是开始节点，则不显示流转条件属性
  if (type === 'custom-bezier-edge') {
    const edgeModel = lf.value.getEdgeModelById(selectedInfoStore.selectId);
    // console.log('edgeModel', edgeModel);
    if (edgeModel.sourceNode.type === 'start-node') {
      return flowProperties[type]?.attrs.filter((attr: string) => attr !== 'edgeTransfer') || [];
    }
  }
  if (!type) {
    return [] as string[];
  }
  return flowProperties[type]?.attrs || [];
});

// 将 attrs 转为要在模板中渲染的面板列表
const panels = computed(() => {
  return attrs.value.map((key: string) => ({
    key,
    component: attrComponentMap[key],
    header: headerMap[key] || key,
  }));
});

// 当 panels 改变时，重置展开面板为第一个（如果存在）
watch(
  panels,
  (val) => {
    activeKey.value = val.length ? ['1'] : [];
  },
  { immediate: true },
);

// 面板样式（动态宽度、从右向左展开）
const panelStyle = computed(() => ({
  width: `${collapsed.value ? 0 : expandedWidth}px`,
  transition: 'width 600ms cubic-bezier(.2,.9,.2,1)',
  overflow: 'hidden',
}));

function openPanel() {
  // console.log('openPanel called');
  savedActiveKey.value = [];
  collapsed.value = false;
  activeKey.value = ['1'];
}

defineExpose({
  openPanel,
});
</script>

<template>
  <div class="right-panel-wrapper">
    <!-- 按钮位于面板左侧 -->
    <div class="toggle-btn" role="button" aria-label="toggle-panel" @click="toggleCollapsed">
      <span v-if="collapsed">
        <DoubleLeftOutlined />
      </span>
      <span v-else>
        <DoubleRightOutlined />
      </span>
    </div>

    <div class="right-panel" :class="{ collapsed }" :style="panelStyle">
      <div class="panel-inner" :aria-hidden="collapsed" overflow-auto>
        <a-collapse v-model:active-key="activeKey" destroy-inactive-panel>
          <a-collapse-panel v-for="(panel, index) in panels" :key="Number(index) + 1" :header="panel.header">
            <component :is="panel.component" />
          </a-collapse-panel>
        </a-collapse>
      </div>
    </div>
  </div>
</template>

<style scoped>
.right-panel {
  display: flex;
  align-items: stretch;
  height: 100%;
  /* 宽度改为通过 style 绑定 */
  padding: 6px;
  overflow: hidden;
  /* padding-bottom: 20px; */
  background: #fff;
  border-radius: 5px;
  box-shadow: 0 1px 4px #0000004d;
  /* 从右向左缓慢展开（宽度变化） */
  transition: width 600ms cubic-bezier(0.2, 0.9, 0.2, 1);
}

.right-panel .panel-inner {
  flex: 1 1 auto;
  min-width: 0;
  opacity: 1;
  /* 内容淡入淡出，配合宽度过渡更平滑 */
  transition: opacity 300ms ease, transform 300ms ease;
}

.right-panel.collapsed {
  /* 折叠时面板宽度为 0（完全隐藏），按钮单独显示在左侧 */
  width: 0px;
  padding: 6px 0;
}

.right-panel .panel-inner {
  pointer-events: auto;
  opacity: 1;
  transform: translateX(0);
}

.right-panel.collapsed .panel-inner {
  pointer-events: none;
  opacity: 0;
  transform: translateX(12px);
}

/* 包裹器：包含按钮和面板，靠右定位 */
.right-panel-wrapper {
  position: absolute;
  top: 80px;
  right: 10px;
  bottom: 10px;
  z-index: 1;
  display: flex;
  gap: 6px;
  align-items: stretch;
}

.toggle-btn {
  position: absolute;
  top: 0px;
  left: -30px;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  min-width: 24px;
  height: 80px;
  cursor: pointer;
  user-select: none;
  background: #f5f5f5;
  border-radius: 4px;
  box-shadow: 0 1px 3px #00000033;
  transition: background 200ms ease, transform 200ms ease;
}

.toggle-btn:hover {
  background: #e6e6e6;
  transform: translateX(-2px);
}

.right-panel {
  /* 右侧面板固定高度占位，由 panelStyle 控制宽度 */
  position: relative;
}
</style>
