<template>
  <div class="page-view-wrapp">
    <div v-if="!isInQiankun" class="project">
      <span>项目: </span>
      <a-select
        style="min-width: 160px"
        placeholder="请选择项目"
        v-model:value="projectVal"
        :options="projectOptions"
        @change="handleProjectChange"
      ></a-select>
    </div>
    <div>
      <grid-layout
        v-if="isDraggable"
        :layout.sync="layoutList"
        :col-num="2"
        :is-draggable="true"
        :is-resizable="false"
        :is-mirrored="false"
        :vertical-compact="true"
        :use-css-transforms="true"
      >
        <grid-item
          v-for="(item, index) in layoutList"
          :x="item.x"
          :y="item.y"
          :w="item.w"
          :h="item.h"
          :i="item.i"
          :key="item.i"
          drag-allow-from=".vue-draggable-handle"
          drag-ignore-from=".no-drag"
        >
          <div class="view-box view-draggable">
            <div class="vue-draggable-handle"><BarsOutlined /></div>
            <div class="content no-drag">
              <a-spin :spinning="ids[index].loading">
                <div class="card-content">
                  <y-table
                    v-if="item.data.type === VIEW_TYPE.TABLE"
                    :preview-id="item.id"
                    :filter-config="item.data.filter"
                    :data-list="item.data.data"
                    :column-config="item.data.header"
                    :total="item.data.count"
                    :title="item.data.preview_name"
                    :is-export="item.data.is_export"
                    @toFilt="
                      (params?:object) => {
                        handleSingle(ids[index], params);
                      }
                    "
                  ></y-table>
                  <y-chart
                    v-if="item.data.type === VIEW_TYPE.CHART"
                    :chartCfg="item.data.config"
                    :title="item.data.preview_name"
                    :filter-config="item.data.filter"
                    @toFilt="
                    (params?:object) => {
                      handleSingle(ids[index], params);
                      }
                    "
                  ></y-chart>
                </div>
              </a-spin>
            </div>
          </div>
        </grid-item>
      </grid-layout>

      <a-row v-else :gutter="[16, 16]">
        <a-col v-for="(item, index) in layoutList" :span="24">
          <a-spin :spinning="item.loading">
            <div>
              <div class="view-box">
                <div class="content">
                  <div class="card-content">
                    <y-table
                      v-if="item.data.type === VIEW_TYPE.TABLE"
                      :preview-id="item.id"
                      :filter-config="item.data.filter"
                      :data-list="item.data.data"
                      :column-config="item.data.header"
                      :total="item.data.count"
                      :title="item.data.preview_name"
                      :is-export="item.data.is_export"
                      @toFilt="
                        (params?:object) => {
                          handleSingle(ids[index], params,);
                        }
                      "
                    ></y-table>
                    <y-chart
                      v-if="item.data.type === VIEW_TYPE.CHART"
                      :chartCfg="item.data.config"
                      :title="item.data.preview_name"
                      :filter-config="item.data.filter"
                      @toFilt="
                        (params?:object) => {
                          handleSingle(ids[index], params);
                        }
                      "
                    ></y-chart>
                  </div>
                </div>
              </div>
            </div>
          </a-spin>
        </a-col>
      </a-row>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, shallowRef, computed, onMounted, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { BarsOutlined } from "@ant-design/icons-vue";
// utils
import PLimit from "p-limit";
// api
import { searchInfo } from "@/api/preview/index";
import { getProjectDrop } from "@/api/common";
import { getPageInfo } from "./service";
import type { SelectProps } from "ant-design-vue";
import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper'

interface ItemDetail {
  id: number | string;
  data: any;
  loading: boolean;
}

interface Item {
  id: number | string;
  data: any;
  loading: boolean;
}

interface Option extends SelectProps {
  mark: string;
}

const VIEW_TYPE = {
  TABLE: "table",
  CHART: "chart",
};

const SEARCH_TYPE = {
  SEARCH: "search",
  INIT: "init",
};

// hooks
const route = useRoute();
const router = useRouter();
const projectTag = shallowRef();
const projectVal = shallowRef();
const pageId = shallowRef(route.query.pageId);
const projectOptions = shallowRef<Option[]>();
const isDraggable = false;

const isInQiankun = computed(() => {
  return qiankunWindow.__POWERED_BY_QIANKUN__ || window.proxy?.__POWERED_BY_QIANKUN__
})

const layoutList = computed(() => {
  return ids.value.map((item, index) => {
    // 当前是第几行
    const row = Math.floor(index / 2);
    // 当前是第几列ji
    const col = index % 2;
    return {
      i: item?.id,
      x: col,
      y: row,
      w: 1,
      h: 3,
      minH: 3,
      ...item,
    };
  });
});
const ids = ref<Item[]>([]);

const pLimit = PLimit(2);

watch(() => route.query.viewId, () => {
  getPageInfoData()
})

onMounted(() => {
  getProjectList();
});

const handleSingle = (info: ItemDetail, otherParams?: object) => {
  getSinglePreview({ info, otherParams, type: SEARCH_TYPE.SEARCH });
};

const handleProjectChange = (value: string | number, option: Option) => {
  projectTag.value = option.mark;
  router.replace({
    path: route.path,
    query: {
      ...route.query,
      projectTag: projectTag.value,
    },
  });
  getPageInfoData();
};

// 请求

// 获取项目下拉
const getProjectList = () => {
  getProjectDrop()
    .then((res) => {
      if (res.code === 200) {
        projectOptions.value = res.data;
        projectTag.value = route.query.projectTag || res.data[0].mark;
        projectVal.value =
          projectOptions.value?.find((item) => {
            return item.mark === route.query.projectTag;
          })?.value || res.data[0].value;
        getPageInfoData();
      }
    })
    .catch(() => {
      projectOptions.value = [];
    })
    .finally(() => {});
};

// 单个视图请求
const getSinglePreview = (data: {
  info: ItemDetail;
  otherParams?: object;
  type?: string;
}) => {
  const { info, otherParams, type } = data;
  info.loading = true;
  const params = { previewId: info.id, page: 1, perPage: 20, ...otherParams };
  searchInfo(params)
    .then((res) => {
      if (res.code === 200) {
        info.data = res.data;
      }
    })
    .finally(() => {
      info.loading = false;
    });
};

// 获取页面信息所有的id
const getPageInfoData = () => {
  getPageInfo({ mark:projectTag.value, page_id: pageId.value ?? "-1" })
    .then((res) => {
      if (res.code === 200) {
        if (route.query.viewId) {
          ids.value = res.data?.filter((item: any) => {
            return item.preview_id === Number(route.query.viewId);
          }).map((item: any) => {
            return {
              id: item.preview_id,
              data: item,
              loading: false,
            }
          })
        } else {
          ids.value = res.data?.map((item: any) => {
            return {
              id: item.preview_id,
              data: item,
              loading: false,
            };
          });
        }

        getAllCardsData();
      }
    })
    .finally(() => {});
};

const fetchFn = (delay: number, info: ItemDetail) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(info);
      getSinglePreview({ info, type: SEARCH_TYPE.INIT });
    }, delay);
  });
};

const getAllCardsData = async () => {
  let listDB = [];
  for (let i in ids.value) {
    listDB.push(pLimit(() => fetchFn(i === "0" ? 200 : 1000, ids.value[i])));
  }
  await Promise.all(listDB);
  //此处的listDB就是最后整合的数据
};
</script>
<style lang="less" scoped>

.view-box {
  height: 100%;
  width: 100%;
  min-height: 350px;
  background-color: #fff;
  border: 1px solid #fff;
  border-radius: 4px;
  transition: all 0.3s;
  &:hover {
    box-shadow: 0 0 20px 0 #0a103205, 0 14px 40px 0 #0a103208,
      0 20px 60px 0 #0a10320d;
  }

  .content {
    padding: 10px;
  }
}

.project {
  margin-bottom: 10px;
}

.view-draggable {
  height: auto;
  min-height: 450px;
}

.vue-draggable-handle {
  padding: 0 8px 8px 0;
  border-radius: 10px;
  cursor: pointer;
}

.vue-grid-item {
  height: auto;
}
</style>
