<script setup lang="ts">
import type { DashboardConfig } from './types';

import { computed, onMounted, ref, watch } from 'vue';

import { $t } from '@vben/locales';

import { ElEmpty } from 'element-plus';
import { GridItem, GridLayout } from 'grid-layout-plus';

import WidgetRenderer from './components/WidgetRenderer.vue';

const props = defineProps<{
  config: DashboardConfig | string;
}>();

const dashboardConfig = ref<DashboardConfig | null>(null);

const parseConfig = () => {
  if (!props.config) {
    dashboardConfig.value = null;
    return;
  }

  if (typeof props.config === 'string') {
    try {
      dashboardConfig.value = JSON.parse(props.config);
    } catch {
      console.error('Invalid dashboard config JSON');
      dashboardConfig.value = null;
    }
  } else {
    dashboardConfig.value = props.config;
  }
};

onMounted(parseConfig);
watch(() => props.config, parseConfig);

const layout = computed(() => {
  if (!dashboardConfig.value) return [];
  return dashboardConfig.value.widgets.map((w) => ({
    i: w.i,
    x: w.x,
    y: w.y,
    w: w.w,
    h: w.h,
  }));
});

const getWidget = (i: string) => {
  if (!dashboardConfig.value) return null;
  return dashboardConfig.value.widgets.find((w) => w.i === i);
};

const getAnimationDelay = (i: string) => {
  if (!dashboardConfig.value) return 0;
  const index = dashboardConfig.value.widgets.findIndex((w) => w.i === i);
  return index * 80;
};

const outerMarginStyle = computed(() => {
  const config = dashboardConfig.value;
  if (!config || config.showOuterMargin !== false) return {};
  const margin = config.margin || [12, 12];
  return {
    marginLeft: `-${margin[0]}px`,
    marginRight: `-${margin[0]}px`,
    marginTop: `-${margin[1]}px`,
    width: `calc(100% + ${margin[0] * 2}px)`,
  };
});
</script>

<template>
  <div
    class="dashboard-renderer h-full"
    :style="
      dashboardConfig?.backgroundColor?.includes('gradient')
        ? { background: dashboardConfig.backgroundColor }
        : { backgroundColor: dashboardConfig?.backgroundColor || '' }
    "
  >
    <div v-if="dashboardConfig && layout.length > 0">
      <GridLayout
        :layout="layout"
        :col-num="dashboardConfig.columns"
        :row-height="dashboardConfig.rowHeight"
        :margin="dashboardConfig.margin"
        :is-draggable="false"
        :is-resizable="false"
        :vertical-compact="true"
        :use-css-transforms="true"
        :style="outerMarginStyle"
      >
      <GridItem
        v-for="item in layout"
        :key="item.i"
        :i="item.i"
        :x="item.x"
        :y="item.y"
        :w="item.w"
        :h="item.h"
        class="dashboard-widget"
      >
        <WidgetRenderer
          v-if="getWidget(item.i)"
          :widget="getWidget(item.i)!"
          :is-design-mode="false"
          :animation-delay="getAnimationDelay(item.i)"
        />
      </GridItem>
      </GridLayout>
    </div>

    <ElEmpty
      v-else
      :description="$t('dashboard-design.noConfigTip')"
      class="py-20"
    />
  </div>
</template>

<style scoped>
.dashboard-renderer {
  background-color: var(--el-bg-color-page);
}

.dashboard-widget {
  overflow: hidden;
  background: var(--el-bg-color);
  border-radius: 8px;
  box-shadow: 0 1px 3px rgb(0 0 0 / 10%);
}
</style>
