<template>
  <div class="fc-style">
    <a-layout class="fc-container">
      <a-layout-content class="fc-main">
        <a-layout>
          <a-layout-sider theme="light" :width="250">
            <div class="components">
              <ComponentGroup
                title="基础组件"
                :fields="basicComponents"
                :list="desktop.basicComponents"
                @copy="copyComponent"
              />
              <ComponentGroup
                title="图标组件"
                :fields="chartComponents"
                :list="desktop.chartComponents"
                @copy="copyComponent"
              />
              <ComponentGroup
                title="系统组件"
                :fields="systemComponents"
                :list="desktop.systemComponents"
                @copy="copyComponent"
              />

              <ComponentGroup
                title="自定义组件"
                v-if="customComponent.length"
                :fields="customComponent.map((x) => x.type)"
                :list="customComponent"
                @copy="copyComponent"
              />
            </div>
          </a-layout-sider>
          <a-layout class="center-container">
            <DesktopHeader
              @preview="() => (previewVisible = true)"
              @clearable="handleClearable"
              @get-json="handleGetJson"
            >
              <slot name="header"></slot>
            </DesktopHeader>
            <a-layout-content :class="!widgetForm ? 'widget-empty' : 'widget-full'">
              <grid-layout
                :layout="widgetForm"
                :col-num="12"
                :row-height="30"
                :is-draggable="true"
                :is-resizable="true"
                :is-mirrored="false"
                :vertical-compact="true"
                :margin="[10, 10]"
                :use-css-transforms="true"
              >
                <grid-item
                  v-for="item in widgetForm"
                  :x="item.x"
                  :y="item.y"
                  :w="item.w"
                  :h="item.h"
                  :i="item.i"
                  :key="item.i"
                  :maxH="item.maxH"
                  :minH="item.minH"
                  :maxW="item.maxW"
                  :minW="item.minW"
                  :class="{ 'active-item': item.i === currentId }"
                  @click="changeSelect(item)"
                >
                  <DefaultItem
                    v-if="defaultComponents.includes(item.type)"
                    :data="item.props"
                    :name="item.type"
                  />
                  <CustomItem
                    v-if="customComponentNames.includes(item.type)"
                    :data="item.props"
                    :name="item.type"
                  />
                  <!-- <div class="mask"></div> -->
                  <a-button
                    class="action-clone"
                    shape="circle"
                    type="primary"
                    size="small"
                    v-if="item.i === currentId"
                    @click.stop="copyComponent(item)"
                  >
                    <template #icon><i class="el-icon-copy-document"></i></template>
                  </a-button>

                  <a-button
                    class="action-delete"
                    shape="circle"
                    type="primary"
                    size="small"
                    danger
                    v-if="item.i === currentId"
                    @click.stop="removeComponent(item)"
                  >
                    <template #icon><i class="el-icon-delete"></i></template>
                  </a-button>
                </grid-item>
              </grid-layout>
            </a-layout-content>
          </a-layout>
          <a-layout-sider theme="light" class="widget-config-container" :width="300">
            <a-layout>
              <a-layout-header>
                <div class="config-tab">组件配置</div>
                <div class="config-tab">参数配置</div>
              </a-layout-header>
              <a-layout-content class="config-content">
                <DefaultConfig
                  v-if="defaultComponents.includes(currentComponent.type)"
                  v-model:select="currentComponent"
                />

                <CustomConfig
                  v-if="customComponentNames.includes(currentComponent.type)"
                  v-model:select="currentComponent"
                />
              </a-layout-content>
            </a-layout>
          </a-layout-sider>
        </a-layout>
      </a-layout-content>
    </a-layout>
    <a-modal
      v-model:visible="previewVisible"
      title="预览"
      width="100%"
      wrapClassName="full-modal"
      :footer="null"
      :forceRender="true"
    >
      <DesktopPreview :json="widgetForm" />
    </a-modal>

    <a-modal
      v-model:visible="generateJsonVisible"
      title="生成JSON"
      :okText="t('复制')"
      :cancelText="t('取消')"
      :width="800"
      :footer="null"
    >
      <CodeEditor :value="generateJsonTemplate" language="json" readonly />
    </a-modal>
  </div>
</template>

<script lang="ts">
  import { defineComponent, reactive, PropType, toRefs, computed } from 'vue';

  import { cloneDeep } from 'lodash-es';
  import ComponentGroup from './components/ComponentGroup.vue';
  import * as desktop from './types';
  import DefaultItem from './components/base/DefaultItem.vue';
  import DefaultConfig from './components/base/DefaultConfig.vue';
  import CustomItem from './components/base/CustomItem.vue';
  import CustomConfig from './components/base/CustomConfig.vue';
  import DesktopHeader from './components/DesktopHeader.vue';
  import DesktopPreview from './components/DesktopPreview.vue';
  import { CodeEditor } from '/@/components/CodeEditor';
  import { useI18n } from '/@/hooks/web/useI18n';
  const { t } = useI18n();

  export default defineComponent({
    name: 'DesktopDesignForm',
    components: {
      ComponentGroup,
      DefaultItem,
      DefaultConfig,
      CustomItem,
      CustomConfig,
      DesktopHeader,
      DesktopPreview,
      CodeEditor,
    },
    props: {
      customComponent: {
        type: Array as PropType<Array<any>>,
        default: () => [],
      },
    },
    setup(props) {
      const state = reactive({
        desktop,
        currentId: '',
        previewVisible: false,
        generateJsonVisible: false,
        generateJsonTemplate: '',
        widgetForm: [] as any[],
        currentComponent: {} as any,
      });

      const defaultComponents = computed(() => {
        return [
          ...desktop.basicComponents.map((x) => x.type),
          ...desktop.chartComponents.map((x) => x.type),
          ...desktop.systemComponents.map((x) => x.type),
        ];
      });

      const basicComponents = computed(() => {
        return desktop.basicComponents.map((x) => x.type);
      });

      const chartComponents = computed(() => {
        return desktop.chartComponents.map((x) => x.type);
      });

      const systemComponents = computed(() => {
        return desktop.systemComponents.map((x) => x.type);
      });

      const customComponentNames = computed(() => {
        return props.customComponent.map((custom) => custom.type);
      });

      // console.log(customComponentNames.value, '-------customComponentNames-----')

      const copyComponent = (element: any) => {
        const clone = cloneDeep(element);
        const x = 0;
        let y = 0;
        const i = Date.now() + '_' + Math.ceil(Math.random() * 99999);

        if (state.widgetForm.length > 0) {
          const lastItem = state.widgetForm[state.widgetForm.length - 1];
          y = lastItem.y + lastItem.h;
        }

        const row = { ...clone, i, x, y };

        state.currentComponent = row;
        state.currentId = row.i;

        state.widgetForm.push(row);

        // console.log(row, state.widgetForm, '-------copyComponent-----')
      };

      const removeComponent = (element: any) => {
        state.widgetForm.splice(
          state.widgetForm.findIndex((x) => x.i === element.i),
          1,
        );
      };

      const changeSelect = (row: any) => {
        if (state.currentId === row.i) return;
        // console.log(state.widgetForm, state.currentComponent)

        state.currentId = row.i;
        state.currentComponent = row;
      };

      const handleClearable = () => {
        state.widgetForm = [];
      };

      const handleGetJson = () =>
        (state.generateJsonTemplate = JSON.stringify(state.widgetForm, null, 2)) &&
        (state.generateJsonVisible = true);

      const get = () => {
        console.log(state.widgetForm);
      };

      const set = (importJson: any[]) => {
        state.widgetForm = importJson;
      };

      return {
        ...toRefs(state),
        copyComponent,
        changeSelect,
        handleClearable,
        removeComponent,
        handleGetJson,
        customComponentNames,
        defaultComponents,
        basicComponents,
        chartComponents,
        systemComponents,
        get,
        set,
        t,
      };
    },
  });
</script>
<style scoped>
  @import '/@/assets/style/designer/index.css';

  .center-container {
    height: 100%;
  }

  .vue-grid-layout {
    background: #eee;
    height: 100%;
  }

  .vue-grid-item:not(.vue-grid-placeholder) {
    background: #ccc;
    border: 1px solid black;
  }

  .vue-grid-item .resizing {
    opacity: 0.9;
  }

  .vue-grid-item .static {
    background: #cce;
  }

  .vue-grid-item .text {
    font-size: 24px;
    text-align: center;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    height: 100%;
    width: 100%;
  }

  .vue-grid-item .no-drag {
    height: 100%;
    width: 100%;
  }

  .vue-grid-item .minMax {
    font-size: 12px;
  }

  .vue-grid-item .add {
    cursor: pointer;
  }

  .vue-draggable-handle {
    position: absolute;
    width: 20px;
    height: 20px;
    top: 0;
    left: 0;
    background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><circle cx='5' cy='5' r='5' fill='#999999'/></svg>")
      no-repeat;
    background-position: bottom right;
    padding: 0 8px 8px 0;
    background-repeat: no-repeat;
    background-origin: content-box;
    box-sizing: border-box;
    cursor: pointer;
  }

  .widget-empty {
    background: url('../../assets/widget-empty.png');
    background-color: #dcdfe6;
  }

  .mask {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 10;
  }

  .vue-grid-item {
    touch-action: none;
    box-sizing: border-box;
    border: 1px solid #fff;
  }

  .vue-grid-item.active-item {
    border: 1px solid #409eff;
  }

  .vue-grid-item > .vue-resizable-handle {
    z-index: 11;
  }

  .action-clone,
  .action-delete {
    position: absolute;
    top: -10px;
    padding: 4px;
    z-index: 20;
  }

  .action-clone {
    right: 48px;
  }

  .action-delete {
    right: 16px;
  }
</style>
