<template>
  <div class="scene-page">
    <div class="scene-toolbar">
      <el-button type="primary" :icon="CirclePlus" @click="handleCreate"> 新增场景 </el-button>
      <div class="scene-search">
        <el-input v-model="filterText" placeholder="请输入场景分类" clearable />
        <el-button type="primary" @click="handleSearch"> 搜索 </el-button>
        <el-button @click="handleReset"> 重置 </el-button>
      </div>
    </div>
    <div class="scene-header">
      <span style="flex: 1">场景分类</span>
      <span style="width: 200px; text-align: center">展示图片</span>
      <span style="width: 200px; text-align: center">状态</span>
      <span style="width: 300px; text-align: center">操作</span>
    </div>
    <div class="scene-tree">
      <el-tree
        ref="treeRef"
        :data="treeData"
        node-key="id"
        :props="treeProps"
        :filter-node-method="filterNode"
        default-expand-all
      >
        <template #default="{ data }">
          <span class="scene-node">
            <span class="scene-name">{{ data.name }}</span>
            <span class="scene-img">
              <el-image
                style="width: 70px; height: 70px"
                v-if="data.imgUrl"
                :src="data.imgUrl"
                class="scene-thumb"
                :preview-src-list="[data.imgUrl]"
              />
            </span>
            <span class="scene-status">
              <el-tag size="small" :type="data.status === 1 ? 'success' : 'info'">
                {{ data.status === 1 ? "启用" : "停用" }}
              </el-tag>
            </span>
            <span class="scene-actions">
              <el-button type="primary" link size="small" :icon="CirclePlus" @click.stop="handleAddChild(data)">
                新增子场景
              </el-button>
              <el-button type="primary" link size="small" :icon="EditPen" @click.stop="handleToggleStatus(data)">
                {{ data.status === 1 ? "停用" : "启用" }}
              </el-button>
              <el-button type="primary" link size="small" :icon="EditPen" @click.stop="handleEdit(data)"> 编辑 </el-button>
              <el-button type="danger" link size="small" :icon="Delete" @click.stop="handleDelete(data)"> 删除 </el-button>
            </span>
          </span>
        </template>
      </el-tree>
    </div>
    <SceneDialog ref="sceneDialogRef" @success="loadSceneList" />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, watch, nextTick } from "vue";
import { ElMessage, ElMessageBox, ElTree } from "element-plus";
import { CirclePlus, Delete, EditPen } from "@element-plus/icons-vue";
import { getScenePage, addScene, editScene, deleteScene, setSceneStatus } from "@/api/modules/lawyer";
import SceneDialog from "./components/SceneDialog.vue";

const treeProps = { children: "children", label: "name" };
const treeRef = ref<InstanceType<typeof ElTree>>();
const sceneDialogRef = ref<InstanceType<typeof SceneDialog>>();
const treeData = ref<any[]>([]);
const filterText = ref("");

const getLevelValue = (level: string | number | null | undefined) => {
  if (typeof level === "number") return level;
  if (typeof level === "string") {
    const match = level.match(/(\d+)/);
    return match ? Number(match[1]) : 1;
  }
  return 1;
};

// 通过parentId 和 level 判断层级
const buildSceneTree = (list: any[] = []) => {
  if (!Array.isArray(list)) return [];

  const nodeMap = new Map<string | number, any>();
  const levelStore = new Map<string | number, number>();
  const groupLevelMap = new Map<string | number | symbol, Map<number, any[]>>();
  const ROOT_KEY = Symbol("scene_root_key");

  const getGroupKey = (parentId: string | number | null | undefined): string | number | symbol => {
    if (parentId === undefined || parentId === null || parentId === "") return ROOT_KEY;
    return parentId;
  };

  list.forEach(item => {
    const levelValue = getLevelValue(item.level);
    const node = { ...item, children: [] as any[] };
    nodeMap.set(item.id, node);
    levelStore.set(item.id, levelValue);

    const key = getGroupKey(item.parentId);
    if (!groupLevelMap.has(key)) {
      groupLevelMap.set(key, new Map());
    }
    const levelMap = groupLevelMap.get(key)!;
    if (!levelMap.has(levelValue)) {
      levelMap.set(levelValue, []);
    }
    levelMap.get(levelValue)!.push(node);
  });

  const findParentByGroup = (node: any) => {
    const nodeLevel = levelStore.get(node.id) || 1;
    if (nodeLevel <= 1) return undefined;
    const key = getGroupKey(node.parentId);
    const levelMap = groupLevelMap.get(key);
    if (!levelMap) return undefined;
    const candidates = levelMap.get(nodeLevel - 1);
    if (!candidates || !candidates.length) return undefined;
    // 默认选取该层级中最后一个节点作为父节点
    return candidates[candidates.length - 1];
  };

  const roots: any[] = [];
  list.forEach(item => {
    const node = nodeMap.get(item.id);
    if (!node) return;
    const nodeLevel = levelStore.get(item.id) || 1;
    let parent: any | undefined;

    if (item.parentId && nodeMap.has(item.parentId)) {
      const candidate = nodeMap.get(item.parentId);
      if (candidate) {
        const candidateLevel = levelStore.get(candidate.id) || 1;
        if (candidate !== node && candidateLevel === nodeLevel - 1) {
          parent = candidate;
        }
      }
    }

    if (!parent) {
      const groupParent = findParentByGroup(node);
      if (groupParent && groupParent !== node) {
        parent = groupParent;
      }
    }

    if (parent) {
      parent.children = parent.children || [];
      parent.children.push(node);
      node.parentName = parent.name;
    } else {
      roots.push(node);
    }
  });

  return roots;
};

const loadSceneList = async () => {
  const res: any = await getScenePage({ page: 1, size: 999 });
  const flatList = res?.records || res?.list || res?.data?.records || [];
  treeData.value = buildSceneTree(flatList);
  nextTick(() => {
    if (filterText.value && treeRef.value) {
      treeRef.value.filter(filterText.value);
    }
  });
};

const handleCreate = () => {
  sceneDialogRef.value?.open({
    title: "新增场景",
    type: "create",
    onSubmit: async payload => {
      let params = {
        name: payload.name,
        status: payload.status,
        imgUrl: payload.imgUrl,
        level: 1
      };
      await addScene(params);
      ElMessage.success("新增成功");
      loadSceneList();
    }
  });
};

const handleAddChild = (row: any) => {
  console.log("row", row);
  sceneDialogRef.value?.open({
    title: `给【${row.name}】新增子场景`,
    row,
    type: "add",
    onSubmit: async payload => {
      console.log("payload add", payload);
      let params = {
        name: payload.name,
        parentId: row.id,
        status: payload.status,
        level: payload.level ? payload.level + 1 : 1,
        parentName: payload.parentName
      };
      await addScene(params);
      ElMessage.success("新增子场景成功");
      loadSceneList();
    }
  });
};

const handleEdit = (row: any) => {
  sceneDialogRef.value?.open({
    title: "编辑场景",
    type: "edit",
    row,
    onSubmit: async payload => {
      let params = {
        name: payload.name,
        id: payload.id,
        status: payload.status,
        level: payload.level,
        imgUrl: payload.imgUrl
      };
      await editScene(params);
      ElMessage.success("编辑成功");
      loadSceneList();
    }
  });
};

const handleDelete = (row: any) => {
  const hasChildren = Array.isArray(row.children) && row.children.length > 0;
  const message = hasChildren
    ? `场景【${row.name}】包含子场景，删除后将一并删除所有子场景，是否继续？`
    : `确认删除场景【${row.name}】吗？`;
  ElMessageBox.confirm(message, "提示", {
    type: "warning"
  })
    .then(async () => {
      await deleteScene({ id: row.id });
      ElMessage.success("删除成功");
      loadSceneList();
    })
    .catch(() => {});
};

const handleToggleStatus = (row: any) => {
  const nextStatus = row.status === 1 ? 0 : 1;
  const actionText = nextStatus === 1 ? "启用" : "停用";
  ElMessageBox.confirm(`确认${actionText}场景【${row.name}】吗？`, "提示", {
    type: "warning"
  })
    .then(async () => {
      await setSceneStatus({ id: row.id, status: nextStatus });
      ElMessage.success(`${actionText}成功`);
      loadSceneList();
    })
    .catch(() => {});
};

const filterNode = (value: string, data: any) => {
  if (!value) return true;
  return data.name?.includes(value);
};

const handleSearch = () => {
  treeRef.value?.filter(filterText.value);
};

const handleReset = () => {
  filterText.value = "";
  treeRef.value?.filter("");
};

watch(filterText, val => {
  if (!val) treeRef.value?.filter("");
});

onMounted(() => {
  loadSceneList();
});
</script>

<style scoped lang="scss">
.scene-page {
  padding: 16px;
}
.scene-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}
.scene-search {
  display: flex;
  gap: 8px;
  width: 360px;
}
.scene-header {
  display: flex;
  padding: 12px 16px;
  font-weight: 600;
  background-color: var(--el-fill-color-light);
  border: 1px solid var(--el-border-color);
  border-bottom: none;
  border-radius: 4px 4px 0 0;
}
.scene-tree {
  max-height: 680px;
  overflow: auto;
  border: 1px solid var(--el-border-color);
  border-top: none;
  border-radius: 0 0 4px 4px;
}
.scene-node {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 12px 16px;
}
.scene-name {
  display: flex;
  flex: 1;
  text-align: center;
}
.scene-img {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 200px;
  text-align: center;
}
.scene-status {
  width: 200px;
  padding-left: 4px;
  text-align: center;
}
.scene-actions {
  width: 300px;
  text-align: center;
}
:deep(.el-tree-node__content) {
  height: auto;
}
</style>
