<template>
  <div class="configurator">
    <!-- 页面设置 -->
    <Tabs v-if="projectStore.selectedElementKeys.length === 0" centered>
      <TabPane key="1" tab="页面">
        <div class="config-content">
          <PageConfig />
        </div>
      </TabPane>
    </Tabs>

    <Tabs centered v-else-if="isGroup">
      <TabPane key="1" tab="组合">
        <div class="config-content">
          <CusForm :columns="groupFormItems" @change="handleGroupChange" />
        </div>
      </TabPane>
    </Tabs>

    <!-- 组件设置 -->
    <Tabs centered v-else-if="isComponent">
      <TabPane key="1" tab="内容">
        <div class="config-content">
          <component
            :is="configComponent"
            @change="handleContentConfigChange"
            v-bind="currentElementProps"
          />
        </div>
      </TabPane>
      <TabPane key="2" tab="事件">
        <div class="config-content">事件处理</div>
      </TabPane>
      <TabPane key="3" tab="动画">
        <div class="config-content">
          <AnimateConfig />
        </div>
      </TabPane>
      <TabPane key="4" tab="组件">
        <div class="config-content">
          <CusForm :columns="formItems" @change="handleComponentConfigChange" />
        </div>
      </TabPane>
    </Tabs>
  </div>
</template>

<script setup lang="ts">
import { computed, shallowRef, watch } from "vue";
import { Tabs, TabPane } from "ant-design-vue";
import { useProjectStore } from "@/store/modules/project";
import PageConfig from "./PageConfig.vue";
import { asyncComponentAll, CusForm } from "@shalu/dashboard-ui";
import { set, defaultsDeep, cloneDeep } from "lodash";
import { useComponentConfig } from "@/hooks";
import AnimateConfig from "./AnimateConfig.vue";

const projectStore = useProjectStore();
const configComponent = shallowRef<null | string>(null);
const currentElementProps = shallowRef<any>({});
const { formItems } = useComponentConfig();

const groupFormItems = computed(() => {
  const containerProps =
    projectStore.currentSelectedElements?.[0]?.container?.props;
  return containerProps ? [
    {
      label: "宽度",
      prop: "props.width",
      type: "inputNumber",
      fieldProps: {
        min: 0,
        addonAfter: "px",
      },
      defaultValue: containerProps?.width ?? 400,
    },
    {
      label: "高度",
      prop: "props.height",
      type: "inputNumber",
      fieldProps: {
        min: 0,
        addonAfter: "px",
      },
      defaultValue: containerProps?.height ?? 260,
    },
    {
      label: "X",
      prop: "props.x",
      type: "inputNumber",
      fieldProps: {
        min: 0,
        addonAfter: "px",
      },
      defaultValue: containerProps?.x ?? 0,
    },
    {
      label: "Y",
      prop: "props.y",
      type: "inputNumber",
      fieldProps: {
        min: 0,
        addonAfter: "px",
      },
      defaultValue: containerProps?.y ?? 0,
    },
  ] : [];
});

watch(
  () => projectStore.currentSelectedElements,
  async (val) => {
    // 组件类型
    if (val.length === 1 && val[0].componentType !== "group") {
      const { Config } = await asyncComponentAll[
        val[0].componentType as keyof typeof asyncComponentAll
      ]?.();
      configComponent.value = Config;
      currentElementProps.value = val[0].props;
    } else {
      // 多选或者组暂时为空
      configComponent.value = null;
      currentElementProps.value = {};
    }
  },
  { immediate: true, deep: true }
);

const isComponent = computed(() => {
  return (
    projectStore.currentSelectedElements.length === 1 &&
    projectStore.currentSelectedElements[0].componentType !== "group"
  );
});

const isGroup = computed(() => {
  return (
    projectStore.currentSelectedElements.length === 1 &&
    projectStore.currentSelectedElements[0].componentType === "group"
  );
});

// 组件内容配置
const handleContentConfigChange = (config: any) => {
  const element = projectStore.currentSelectedElements[0];
  let prefix: string = "";
  // 判断是否存在组合并的情况 查找出更新路径
  if (element?.parentKey !== undefined) {
    const parent = projectStore.elements.find(
      (item) => item.key === element.parentKey
    );
    parent?.children?.findIndex((item, index) => {
      if (item.key === element.key) {
        prefix = `children[${index}].`;
      }
    });
  }
  projectStore.updateElement(
    element?.parentKey ?? element.key,
    prefix + "props",
    config
  );
};

// 组件配置
const handleComponentConfigChange = (config: Record<string, any>) => {
  const container: Record<string, any> = {};
  const currentContainer = cloneDeep(
    projectStore.currentSelectedElements[0].container
  );
  Object.entries(config).forEach(([key, value]) => {
    set(container, key, value);
  });
  defaultsDeep(container, currentContainer);
  const element = projectStore.currentSelectedElements[0];
  let prefix: string = "";
  if (element?.parentKey !== undefined) {
    const parent = projectStore.elements.find(
      (item) => item.key === element.parentKey
    );
    parent?.children?.findIndex((item, index) => {
      if (item.key === element.key) {
        prefix = `children[${index}].`;
      }
    });
  }
  // 判断是否存在父级情况
  projectStore.updateElement(
    element?.parentKey ?? element.key,
    prefix + "container",
    container
  );
  projectStore.updateElement(
    element?.parentKey ?? element.key,
    prefix + "name",
    container?.name
  );
};

const handleGroupChange = (config: Record<string, any>) => {
  const element = projectStore.currentSelectedElements[0];
  const container: Record<string, any> = {};
  Object.entries(config).forEach(([key, value]) => {
    set(container, key, value);
  });
  const changeWidth = container.props.width - element.container.props.width;
  const changeHeight = container.props.height - element.container.props.height;

  projectStore.updateElement(element.key, "container.props", container?.props);
  // 更新子元素的宽高
  element.children?.forEach((child, index) => {
    child.container.props.width += changeWidth;
    child.container.props.height += changeHeight;
    projectStore.updateElement(element.key, `children[${index}].container.props.width`, child.container.props.width);
    projectStore.updateElement(element.key, `children[${index}].container.props.height`, child.container.props.height);
  });
};
</script>

<style lang="less" scoped>
.configurator {
  width: 300px;
  height: 100%;
  display: flex;
  flex-direction: column;
  :deep(.ant-tabs) {
    flex: 1;
    overflow-y: scroll;
  }
  :deep(.ant-tabs-nav) {
    margin-bottom: 0;
  }
  :deep(.ant-tabs-content-holder) {
    background-color: @bg-color;
    padding-top: 12px;
  }
  :deep(.ant-tabs-content) {
    background-color: @bg-color;
  }
  .config-content {
    padding: 12px;
    padding-top: 0;
  }
}
</style>
