<template>
  <ElDialog v-model="showDialog"
    :close-on-click-modal="false"
    destroy-on-close width="25vw" @close="dialogCloseHandler">
    <ElForm :model="menuForm" class="menu-form" label-width="auto">
      <ElFormItem label="上级">
        <ElTreeSelect v-model="menuForm.pid" :data="menuTreeDataSource" :default-expanded-keys="['0']" :render-after-expand="false" check-strictly placeholder="选择上级菜单"/>
      </ElFormItem>
      <ElFormItem label="客户端" prop="clients">
        <ElCheckboxGroup v-model="menuForm.clients">
          <ElCheckbox v-for="client in  ClientUtil.clients" :key="client.val" :label="client.txt" :value="client.val"/>
        </ElCheckboxGroup>
      </ElFormItem>
      <ElFormItem label="类型">
        <ElSelect v-model="menuForm.menuCategory" :data="menuCategoryData" placeholder="选择类型">
          <ElOption v-for="menuCategory in menuCategoryData" :key="menuCategory.key" :label="menuCategory.label" :value="menuCategory.key"/>
        </ElSelect>
      </ElFormItem>

      <ElFormItem label="名称">
        <ElInput v-model="menuForm.title" placeholder="名称"/>
      </ElFormItem>

      <ElFormItem v-if="menuForm.menuCategory === MenuCategory.Page || menuForm.menuCategory === MenuCategory.SubPage" label="路由名称">
        <ElInput v-model="menuForm.routeName" :min="0" placeholder="路由名称"/>
      </ElFormItem>
      <ElFormItem v-if="menuForm.menuCategory === MenuCategory.Page || menuForm.menuCategory === MenuCategory.SubPage" label="路由地址">
        <ElInput v-model="menuForm.routePath" :min="0" placeholder="路由地址"/>
      </ElFormItem>
      <ElFormItem label="编码">
        <ElInput v-model="menuForm.sn" :min="0" placeholder="编码"/>
      </ElFormItem>
      <ElFormItem label="图标">
        <ElDropdown closable header="图标列表" placement="bottom" style="width: 100%" trigger="click">
          <ElInput v-model="menuForm.iconName" placeholder="选择图标" readonly>
            <template #suffix>
              <AIcon :name="menuForm.icon!"/>
            </template>
          </ElInput>
          <template #dropdown>
            <div class="dropdown-table-wrapper">
              <ElTable
                ref="dropdownTable"
                :data="iconTableDataSource"
                cell-class-name="table-cell"
                class="table-list"
                empty-text="暂无数据"
                header-row-class-name="table-header"
                row-key="id"
                width="324"
                @current-change="currentChangeHandler">
                <ElTableColumn label="#" type="index"/>
                <ElTableColumn label="图标" prop="font_class">
                  <template #default="scope">
                    <AIcon :name="scope?.row?.font_class"/>
                  </template>
                </ElTableColumn>
                <ElTableColumn label="名称" prop="name"/>
              </ElTable>
              <ElPagination :page-size="pagination.size" :total="pagination.total" layout="total, prev, pager, next" @change="pageChangeHandler"/>
            </div>
          </template>
        </ElDropdown>
      </ElFormItem>
      <ElFormItem label="排序">
        <ElInputNumber v-model="menuForm.sort" :min="0" placeholder="排序" style="width: 100%"/>
      </ElFormItem>
    </ElForm>
    <template #footer>
      <ElButton @click="showDialog = false">{{ status === 'view' ? '关闭' : '取消' }}</ElButton>
      <ElButton v-if="status !== 'view'" :loading="submiting" type="primary" @click="submitHandler">提交</ElButton>
    </template>
  </ElDialog>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import {
  MenuCategory,
  MenuCategoryDict,
} from '@/common/app/constants.ts'
import MenuApi from '@/pages/sys/menus/menu-api.ts'
import Colls from '@/common/utils/colls.ts'
import Strings from '@/common/utils/strings.ts'
import {
  ElMessage,
  type TableInstance,
} from 'element-plus'
import {
  type IconGlyphs,
  icons,
} from '@/components/a-icon/iconfont.ts'
import AIcon from '@/components/a-icon/AIcon.vue'
import ClientUtil from '@/common/utils/client-util.ts'
import Utils from '@/common/utils'

const emits = defineEmits([ 'editSucc' ])

const pagination = reactive<G.Pagination>({
  total: icons.glyphs.length,
  pages: Math.ceil(icons.glyphs.length / 5),
  current: 1,
  size: 5,
})

function dialogCloseHandler() {
  menuForm.value = {
    icon: 'dianzixiaopiao',
  }
}

function pageChangeHandler(currentPage: number, pageSize: number) {
  pagination.current = currentPage
  pagination.size = pageSize
  iconTableDataSource.value = icons.glyphs.filter((_, i) => {
    return i >= (currentPage - 1) * pageSize && i < currentPage * pageSize
  })
}

const dropdownTableIns = useTemplateRef<TableInstance>('dropdownTable')

let menuForm = ref<MenuTypes.MenuForm>({
  icon: 'dianzixiaopiao',
})

const iconTableDataSource = ref<IconGlyphs[]>(
  icons.glyphs.filter((_, i) => {
    return i >= 0 && i < 5
  }),
)

function currentChangeHandler(val?: IconGlyphs) {
  if (val == null) return
  menuForm.value.icon = val.font_class
  menuForm.value.iconName = val.name
}

const showDialog = ref(false)
const submiting = ref(false)
const status = ref<'add' | 'view' | 'modify'>('add')

const menuCategoryData = computed(() => {
  const data: { key: string; label: string }[] = []
  for (const key in MenuCategoryDict) {
    data.push({
      key,
      label: MenuCategoryDict[key as keyof typeof MenuCategoryDict],
    })
  }
  return data
})

const menuTreeDataSource = ref<MenuTypes.SysMenu[]>()


function submitHandler() {
  if (status.value === 'view') return
  submiting.value = true

  menuForm.value.clientCode = ClientUtil.getClientCode(menuForm.value.clients!)
  if (menuForm.value.id != null) {
    MenuApi.modify(menuForm.value)
      .then(() => {
        ElMessage.success('修改成功')
        showDialog.value = false
        emits(('editSucc'))
      })
      .finally(() => {
        submiting.value = false
      })
  } else {
    MenuApi.add(menuForm.value)
      .then(() => {
        ElMessage.success('添加成功')
        showDialog.value = false
        emits(('editSucc'))
      })
      .finally(() => {
        submiting.value = false
      })
  }
}

defineExpose({
  open(data: MenuTypes.MenuForm = {
    icon: 'dianzixiaopiao',
  }) {
    if (!Strings.isBlank(data.id)) {
      status.value = 'modify'
      data = Utils.clone(data)
      data.clients = ClientUtil.getClients(data.clientCode!).map(it => it.val)
      menuForm.value = data
    } else {
      menuForm.value = {
        icon: 'dianzixiaopiao',
      }
    }
    showDialog.value = true
    dropdownTableIns.value?.setCurrentRow(icons.glyphs.find((it) => it.font_class === data.icon))
  },
})

onMounted(() => {
  MenuApi.list().then(({data}) => {
    const nodes = Colls.toTree(data.map((it) => ({value: it.id, label: it.title, ...it})))
    menuTreeDataSource.value = [ {value: '0', label: '顶级菜单', id: '0', pid: '0', children: nodes} ]
  })
})
</script>

<style lang="stylus" scoped>
.menu-form {
  padding 20px
}

.dropdown-table-wrapper {
  padding 10px
  display flex
  flex-direction column
  align-items end
  justify-content space-between
  gap 10px
}
</style>
