<template>
  <div class="main">
    <m-title area="title" @touch="showLayoutModal = true">
      静安智慧房管
    </m-title>
    <m-grid
      v-if="layout.boxNum > 0"
      :template="layout.template"
      columns="1fr 1.5fr 1fr"
      :rows="`${layout.rows}`"
    >
      <!-- 为了保持和view-page一样的页面结构，使settings能找到对应元素进行数据替换 -->
      <Map v-show="false" />
      <div
        v-for="(_, index) in new Array(layout.boxNum)"
        :key="index"
        class="box"
        :area="`box${index + 1}`"
        :class="{ done: !!components[index] }"
      >
        <component
          :is="componentList[components[index]]"
          v-if="!!components[index]"
        />
        <img
          v-else
          class="add-btn"
          src="@/assets/images/add.png"
          @click.prevent.stop="openComponentModal(index, layout.template)"
        />
        <n-icon
          v-show="!!components[index]"
          class="btn del"
          size=".16rem"
          @click="onCancelComponent(index)"
        >
          <TrashBin />
        </n-icon>
        <!-- <n-icon
          v-show="!!components[index]"
          class="btn config"
          size=".16rem"
          @click="onSetComponent(componentList[components[index]])"
        >
          <SettingsOutline />
        </n-icon> -->
      </div>
    </m-grid>
  </div>
  <LayoutModal v-model="showLayoutModal" @select="onChangeLayout" />
  <ComponentModal
    v-model="showComponentModal"
    :rows="isTake2rows ? 2 : 1"
    @select="onSelectComponent"
  />
  <n-drawer id="setting-drawer" v-model:show="showSettingDrawer" :width="400">
    <n-drawer-content title="组件设置">
      <n-form
        ref="formRef"
        :model="model"
        label-placement="left"
        :label-width="80"
        size="small"
      >
        <n-form-item label="标题" path="title">
          <n-input v-model:value="model.title" />
        </n-form-item>
        <n-form-item label="请求地址" path="baseUrl">
          <n-input v-model:value="model.baseUrl" />
        </n-form-item>
      </n-form>
      <n-collapse accordion>
        <n-collapse-item
          v-for="(item, i) in apiList"
          :key="item.key"
          :title="`接口${i + 1}`"
          :name="item.key"
        >
          <div>
            <n-space align="center" justify="space-between">
              <n-input v-model:value="item.value" size="small" />
              <n-button size="small" @click="testFetchData(item.value, i)">
                请求
              </n-button>
            </n-space>
            <json-viewer
              v-if="resList[i]"
              :value="resList[i]"
              :expand-depth="2"
              sort
              :copyable="{ copyText: '复制', copiedText: '已复制' }"
            />
          </div>
        </n-collapse-item>
      </n-collapse>
      <n-space justify="end">
        <n-button type="primary" size="small" @click="saveConfig">
          保存
        </n-button>
      </n-space>
    </n-drawer-content>
  </n-drawer>
  <!-- <ConfigPopover :settings="settings" @save="onSaveSettings" /> -->
</template>

<script lang="ts" setup>
import LayoutModal from './components/layout-modal.vue'
import ComponentModal from './components/component-modal.vue'
import ConfigPopover from './components/config-popover.vue'
import Map from './components/map.vue'
import useLayout from '@/hooks/useLayout'
import useComponent from '@/hooks/useComponent'
import { Settings } from '@/hooks/useSettings'
import { TrashBin, SettingsOutline } from '@vicons/ionicons5'
import { bus } from '@/utils/component-list'
import axios from 'axios'
import {
  NDrawer,
  NDrawerContent,
  NForm,
  NFormItem,
  NInput,
  NButton,
  NCollapse,
  NCollapseItem,
} from 'naive-ui'
import { onBeforeUnmount, ref } from 'vue'
import { ajax, api } from '@/ajax'

const settings = ref<Settings>([])
const onSaveSettings = (data: Settings) => {
  settings.value = data
}
const { showLayoutModal, layout, onChangeLayout } = useLayout()
const {
  components,
  componentList,
  showComponentModal,
  openComponentModal,
  onCancelComponent,
  onSelectComponent,
  isTake2rows,
} = useComponent()

const handleMessage = (e) => {
  const { type, data } = e.data
  switch (type) {
    case 'save':
      window.parent.postMessage(
        {
          type: 'config',
          data: JSON.stringify({
            layout: layout.value,
            components: components.value,
            settings: settings.value,
          }),
        },
        '*',
      )
      break
    case 'init':
      ajax
        .get({
          url: api.CONFIGS,
          params: {
            id: data,
          },
          showLoading: true,
        })
        .then((res) => {
          const { configJson } = res?.data?.content?.[0] || {}
          if (!configJson) return
          const config = JSON.parse(configJson)
          config?.layout && (layout.value = config.layout)
          config?.components && (components.value = config.components)
          config?.settings && (settings.value = config.settings)
        })
      break
    case 'layout':
      showLayoutModal.value = true
      break
    default:
      break
  }
}
window.addEventListener('message', handleMessage)
onBeforeUnmount(() => {
  window.removeEventListener('message', handleMessage)
})

bus.on('map', (e: any) => {
  console.log('emit by : ', e)
})

const showSettingDrawer = ref(false)
const model = ref<any>({})
const curComponentName = ref('')
const apiList = ref<{ key: string; value: string }[]>([])
function onSetComponent({ name, title, baseUrl, apis }) {
  showSettingDrawer.value = true
  model.value = {
    title,
    baseUrl,
  }
  curComponentName.value = name
  // apiList.value = apis
  apiList.value = [
    { key: 'summary', value: '/api1' },
    { key: 'list', value: '/api2' },
  ]
}
const resList = ref<any[]>([])
async function testFetchData(api, i) {
  resList.value[i] =
    (
      await axios.get(
        'http://yapi.omniview.pro/mock/377/service-special-nandong/forOld/statistics',
      )
    )?.data?.data?.content || null
}
function saveConfig() {
  const config = { ...model.value }
  bus.emit(`config-${curComponentName.value}`, config)
}
</script>

<style lang="stylus" scoped>
@import '../components/MyComponent/main.styl'
.main
  width 100%
  height 100%
  display flex
  flex-direction column
.box
  border-radius .02rem
  border .01rem dashed #4270B3
  background rgba(54,65,77,.5)
  $blur(0.01rem)
  position relative
  overflow hidden
  &:hover
    >.btn
      opacity 0.7
  &.done
    border none
    background transparent
    $blur(0)
  >.add-btn
    width .2rem
    height @width
    position absolute
    top 50%
    left 50%
    transform translate(-50%,-50%)
    opacity .8
    cursor pointer
    transition all .2s ease-in-out
    &:hover
      opacity 1
      width .24rem
      height @width
  >.btn
    position absolute
    top .05rem
    cursor pointer
    opacity 0
    transition opacity .2s ease-in-out
    &.del
      right .05rem
      color red
    &.config
      right .25rem
      color $blue
    &:hover
      opacity 1
.main
  background url('/src/assets/images/map.png') center/100% 100% no-repeat
</style>
<style lang="stylus">
@import '../components/MyComponent/main.styl'

#setting-drawer
  font-size .1rem
  background $primary-bg
  $blur()
  .jv-container
    margin .1rem 0
    .jv-code
      padding .05rem .1rem
</style>
