<script lang="ts" setup>
import { computed, ref, watch } from 'vue';

import {
  getTemplateById,
  updateTemplate,
} from '#/api/legacy/system';

import ActivityTemplateAttrEditor from './activity-template-attr-editor.vue';
import {
  buildTemplateNodeForm,
  cloneTemplateValue,
  findTemplateNode,
  getFirstTemplateNodeId,
  giftRankingTreeIndexs,
  normalizeTemplateTree,
} from './activity-template-shared';

import {
  Button,
  Descriptions,
  DescriptionsItem,
  Drawer,
  Empty,
  Modal,
  Space,
  Spin,
  Tree,
  message,
} from 'antdv-next';

defineOptions({ name: 'OperateActivityTemplateEditorModal' });

const props = defineProps<{
  open: boolean;
  templateId: number | string;
}>();

const emit = defineEmits<{
  close: [];
  success: [];
}>();

const loading = ref(false);
const saving = ref(false);
const template = ref<Record<string, any> | null>(null);
const indexTree = ref<Array<Record<string, any>>>([]);
const selectedNodeId = ref('');

const title = computed(() => {
  if (!props.templateId) {
    return '编辑模版';
  }
  return `编辑模版 #${props.templateId}`;
});

const treeData = computed(() => {
  const convert = (list: Array<Record<string, any>>): Array<Record<string, any>> =>
    list.map((item) => ({
      children: convert(item.children || []),
      key: item.id,
      title: `${item.label || item.id} (${item.id})`,
    }));
  return convert(indexTree.value);
});

const selectedNode = computed(() => findTemplateNode(indexTree.value, selectedNodeId.value));

const selectedNodeForm = computed(() => buildTemplateNodeForm(selectedNode.value));

watch(
  () => (props.open ? props.templateId : ''),
  async (templateId) => {
    if (!templateId) {
      return;
    }
    loading.value = true;
    try {
      const result = await getTemplateById(templateId);
      const nextTree = normalizeTemplateTree(
        Array.isArray(result?.indexTree) && result.indexTree.length > 0
          ? result.indexTree
          : giftRankingTreeIndexs,
      );
      template.value = {
        ...(result || {}),
        indexTree: nextTree,
      };
      indexTree.value = nextTree;
      selectedNodeId.value = getFirstTemplateNodeId(nextTree);
    } finally {
      loading.value = false;
    }
  },
  { immediate: true },
);

async function handleSave() {
  if (!template.value) {
    return;
  }

  saving.value = true;
  try {
    const nextTree = cloneTemplateValue(indexTree.value || []);
    await updateTemplate({
      ...template.value,
      indexTree: nextTree,
    });
    template.value = {
      ...template.value,
      indexTree: nextTree,
    };
    message.success('保存成功');
    emit('success');
  } finally {
    saving.value = false;
  }
}

function handleSelect(keys: Array<string | number>) {
  selectedNodeId.value = String(keys?.[0] || '');
}

function handleEditorChange(form: Record<string, any>) {
  const node = selectedNode.value;
  if (!node) {
    return;
  }
  node.editor = cloneTemplateValue(form);
}

function handleResetDefault() {
  Modal.confirm({
    title: '确认恢复默认模板树吗？',
    content: '会覆盖当前抽屉里未保存的模板结构。',
    onOk() {
      const nextTree = normalizeTemplateTree(giftRankingTreeIndexs);
      indexTree.value = nextTree;
      selectedNodeId.value = getFirstTemplateNodeId(nextTree);
    },
  });
}
</script>

<template>
  <Drawer
    :open="open"
    :title="title"
    destroy-on-close
    width="1080"
    @close="emit('close')"
  >
    <Spin :spinning="loading">
      <div v-if="template" class="editor">
        <Descriptions bordered size="small">
          <DescriptionsItem label="模版ID">
            {{ template.id || '-' }}
          </DescriptionsItem>
          <DescriptionsItem label="模版名称">
            {{ template.name || '-' }}
          </DescriptionsItem>
          <DescriptionsItem label="修改时间">
            {{ template.updateTime || '-' }}
          </DescriptionsItem>
        </Descriptions>

        <div class="tips">
          <div>新后台已恢复为树形模板编辑。</div>
          <div>左侧选择节点，右侧编辑属性和样式，保存时仍然写回同一份 `indexTree` 结构。</div>
        </div>

        <div class="toolbar">
          <Button @click="handleResetDefault">恢复默认模板树</Button>
        </div>

        <div class="workspace">
          <div class="tree-panel">
            <div class="panel-title">模板树</div>
            <Tree
              :selected-keys="selectedNodeId ? [selectedNodeId] : []"
              :tree-data="treeData"
              block-node
              default-expand-all
              @select="handleSelect"
            />
          </div>

          <div class="form-panel">
            <div class="panel-title">
              {{ selectedNode ? `${selectedNode.label || '-'} (${selectedNode.id || '-'})` : '节点属性' }}
            </div>
            <ActivityTemplateAttrEditor :form="selectedNodeForm" @change="handleEditorChange" />
          </div>
        </div>
      </div>
      <Empty v-else description="未获取到模版数据" />
    </Spin>

    <template #footer>
      <Space>
        <Button @click="emit('close')">关闭</Button>
        <Button
          :disabled="!template"
          :loading="saving"
          type="primary"
          @click="handleSave"
        >
          保存
        </Button>
      </Space>
    </template>
  </Drawer>
</template>

<style scoped>
.editor {
  display: grid;
  gap: 16px;
}

.toolbar {
  display: flex;
  justify-content: flex-end;
}

.tips {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  color: #475569;
  line-height: 1.7;
  padding: 12px 14px;
}

.workspace {
  display: grid;
  gap: 16px;
  grid-template-columns: 320px minmax(0, 1fr);
  min-height: 560px;
}

.tree-panel,
.form-panel {
  border: 1px solid #e2e8f0;
  border-radius: 14px;
  padding: 16px;
}

.tree-panel {
  overflow: auto;
}

.panel-title {
  color: #0f172a;
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 12px;
}
</style>
