<script lang="ts" setup>
import Sortable from 'sortablejs'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
// import api from '@/api'

const props = withDefaults(
  defineProps<{
    id?: string | number
    parentId?: string | number
  }>(),
  {
    id: '',
    parentId: '',
  },
)

const emits = defineEmits(['onSubmit'])

const loading = ref(false)
const formRef = ref<FormInstance>()
const form = ref({
  id: props.id,
  parentId: props.parentId,
  path: '',
  redirect: '',
  name: '',
  component: '',
  meta: {
    title: '',
    icon: '',
    activeIcon: '',
    defaultOpened: false,
    permanent: false,
    auth: [] as string[],
    sidebar: true,
    breadcrumb: true,
    activeMenu: '',
    cache: [] as string[] | boolean,
    noCache: [] as string[],
    badge: '',
    link: '',
    iframe: '',
    copyright: false,
    paddingBottom: '0px',
  },
  auths: [] as {
    name: string
    value: string
  }[],
})
const formRules = ref<FormRules>({
  'path': [
    { required: true, message: '请输入路由地址', trigger: 'blur' },
  ],
  'meta.title': [
    { required: true, message: '请输入显示名称', trigger: 'blur' },
  ],
})

onMounted(() => {
  if (form.value.id !== '') {
    getInfo()
  }
})

function getInfo() {
  loading.value = true
}

// 鉴权标识
const inputAuth = ref('')
const inputAuthVisible = ref(false)
const InputAuthRef = ref()
const onInputAuthClose = (tag: string) => {
  form.value.meta.auth.splice(form.value.meta.auth.indexOf(tag), 1)
}

const onInputAuthShow = () => {
  inputAuthVisible.value = true
  nextTick(() => {
    InputAuthRef.value!.input!.focus()
  })
}

const onInputAuthConfirm = () => {
  if (inputAuth.value) {
    if (!form.value.meta.auth.includes(inputAuth.value)) {
      form.value.meta.auth.push(inputAuth.value)
    }
    else {
      ElMessage.warning('标识已存在')
    }
  }
  inputAuthVisible.value = false
  inputAuth.value = ''
}

// 缓存规则
const inputCache = ref('')
const inputCacheVisible = ref(false)
const InputCacheRef = ref()
const onInputCacheClose = (tag: string) => {
  typeof form.value.meta.cache === 'object' && form.value.meta.cache.splice(form.value.meta.cache.indexOf(tag), 1)
}
const onInputCacheShow = () => {
  inputCacheVisible.value = true
  nextTick(() => {
    InputCacheRef.value!.input!.focus()
  })
}
const onInputCacheConfirm = () => {
  if (inputCache.value && typeof form.value.meta.cache === 'object') {
    if (!form.value.meta.cache.includes(inputCache.value)) {
      form.value.meta.cache.push(inputCache.value)
    }
    else {
      ElMessage.warning('规则已存在')
    }
  }
  inputCacheVisible.value = false
  inputCache.value = ''
}

// 不缓存规则
const inputNoCache = ref('')
const inputNoCacheVisible = ref(false)
const InputNoCacheRef = ref()
const onInputNoCacheClose = (tag: string) => {
  form.value.meta.noCache.splice(form.value.meta.noCache.indexOf(tag), 1)
}
const onInputNoCacheShow = () => {
  inputNoCacheVisible.value = true
  nextTick(() => {
    InputNoCacheRef.value!.input!.focus()
  })
}
const onInputNoCacheConfirm = () => {
  if (inputNoCache.value) {
    if (!form.value.meta.noCache.includes(inputNoCache.value)) {
      form.value.meta.noCache.push(inputNoCache.value)
    }
    else {
      ElMessage.warning('规则已存在')
    }
  }
  inputNoCacheVisible.value = false
  inputNoCache.value = ''
}

const authsTableRef = ref()
const authsTableKey = ref(0)
onMounted(() => {
  onAuthDarg()
})
function onAuthAdd() {
  form.value.auths.push({
    name: '',
    value: '',
  })
  nextTick(() => {
    authsTableRef.value.setScrollTop(form.value.auths.length * 50)
  })
}
function onAuthDelete(index: number) {
  form.value.auths.splice(index, 1)
}
function onAuthDarg() {
  const tbody = authsTableRef.value.$el.querySelector('.el-table__body-wrapper tbody')
  Sortable.create(tbody, {
    handle: '.sortable',
    animation: 300,
    ghostClass: 'ghost',
    onEnd: ({ newIndex, oldIndex }) => {
      if (newIndex === undefined || oldIndex === undefined) {
        return
      }
      const currRow = form.value.auths.splice(oldIndex, 1)[0]
      form.value.auths.splice(newIndex, 0, currRow)
      authsTableKey.value += 1
      nextTick(() => onAuthDarg())
    },
  })
}

function onSubmit() {
  if (form.value.id === '') {
    formRef.value && formRef.value.validate((valid) => {
      if (valid) { /* empty */ }
    })
  }
  else {
    formRef.value && formRef.value.validate((valid) => {
      if (valid) { /* empty */ }
    })
  }
}
</script>

<template>
  <div v-loading="loading" class="form">
    <div class="top-side">
      <el-form ref="formRef" :model="form" :rules="formRules" label-position="top">
        <div class="form-left-side">
          <el-scrollbar>
            <page-header v-if="!!form.parentId" title="基础配置" content="标准路由配置，包含 path/redirect/name/component" />
            <el-row v-if="!!form.parentId" :gutter="30" style="padding: 20px;">
              <el-col :xl="12" :lg="24">
                <el-form-item label="路由地址" prop="path">
                  <el-input v-model="form.path" clearable placeholder="请输入路由地址" />
                </el-form-item>
              </el-col>
              <el-col :xl="12" :lg="24">
                <el-form-item label="重定向" prop="redirect">
                  <el-input v-model="form.redirect" clearable placeholder="请输入重定向地址" />
                </el-form-item>
              </el-col>
              <el-col :xl="12" :lg="24">
                <el-form-item prop="name">
                  <template #label>
                    路由命名
                    <span class="label-tip">即 name ，系统唯一</span>
                  </template>
                  <el-input v-model="form.name" clearable placeholder="请输入路由命名" />
                </el-form-item>
              </el-col>
              <el-col :xl="12" :lg="24">
                <el-form-item prop="component">
                  <template #label>
                    组件路径
                    <span class="label-tip">
                      顶级路由请设置“<el-link type="primary" :underline="false" @click.prevent="form.component = 'Layout'">Layout</el-link>”，中间层级路由无需设置
                    </span>
                  </template>
                  <el-input v-model="form.component" clearable placeholder="请输入完整组件路径">
                    <template v-if="form.component !== 'Layout'" #prepend>
                      /src/views/
                    </template>
                  </el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <page-header title="扩展配置">
              <template #content>
                <div style="display: flex;">
                  框架扩展配置，详细配置介绍请查看<el-link type="primary" href="https://hooray.gitee.io/fantastic-admin/guide/router.html#%E5%AF%BC%E8%88%AA%E9%85%8D%E7%BD%AE" target="_blank">
                    框架文档
                  </el-link>
                </div>
              </template>
            </page-header>
            <el-row :gutter="30" style="padding: 20px;">
              <el-col :xl="12" :lg="24">
                <el-form-item label="显示名称" prop="meta.title">
                  <el-input v-model="form.meta.title" clearable placeholder="请输入显示名称" />
                </el-form-item>
              </el-col>
              <el-col :xl="12" :lg="24">
                <el-form-item prop="meta.auth">
                  <template #label>
                    鉴权标识
                    <el-tooltip content="当设置多个标识时，只要命中其中一个则鉴权通过" placement="top">
                      <el-icon>
                        <svg-icon name="i-ri:question-line" />
                      </el-icon>
                    </el-tooltip>
                  </template>
                  <el-space>
                    <el-tag v-for="item in (form.meta.auth as string[])" :key="item" size="large" closable :disable-transitions="false" @close="onInputAuthClose(item)">
                      {{ item }}
                    </el-tag>
                    <el-input v-if="inputAuthVisible" ref="InputAuthRef" v-model="inputAuth" style="width: 200px;" @keyup.enter="onInputAuthConfirm" @blur="onInputAuthConfirm" />
                    <el-button v-else @click="onInputAuthShow">
                      新增
                    </el-button>
                  </el-space>
                </el-form-item>
              </el-col>
              <el-col :xl="12" :lg="24">
                <el-form-item label="默认图标" prop="meta.icon">
                  <icon-picker v-model="form.meta.icon" />
                </el-form-item>
              </el-col>
              <el-col :xl="12" :lg="24">
                <el-form-item label="激活图标" prop="meta.activeIcon">
                  <icon-picker v-model="form.meta.activeIcon" />
                </el-form-item>
              </el-col>
              <el-col v-if="!!form.parentId" :xl="12" :lg="24">
                <el-form-item label="默认展开" prop="meta.defaultOpened">
                  <el-switch v-model="form.meta.defaultOpened" inline-prompt active-text="是" inactive-text="否" />
                </el-form-item>
              </el-col>
              <el-col v-if="!!form.parentId" :xl="12" :lg="24">
                <el-form-item prop="meta.permanent">
                  <template #label>
                    常驻标签页
                    <span class="label-tip">请勿在带有参数的路由地址上开启该设置</span>
                  </template>
                  <el-switch v-model="form.meta.permanent" inline-prompt active-text="是" inactive-text="否" />
                </el-form-item>
              </el-col>
              <el-col v-if="!!form.parentId" :xl="12" :lg="24">
                <el-form-item label="在导航显示" prop="meta.sidebar">
                  <el-switch v-model="form.meta.sidebar" inline-prompt active-text="显示" inactive-text="隐藏" />
                </el-form-item>
              </el-col>
              <el-col v-if="!!form.parentId" :xl="12" :lg="24">
                <el-form-item label="在面包屑显示" prop="meta.breadcrumb">
                  <el-switch v-model="form.meta.breadcrumb" inline-prompt active-text="显示" inactive-text="隐藏" />
                </el-form-item>
              </el-col>
              <el-col v-if="!!form.parentId" :xl="12" :lg="24">
                <el-form-item prop="meta.cache">
                  <template #label>
                    缓存规则
                    <el-tooltip content="当跳转到设置的路由时，则会对当前路由进行缓存" placement="top">
                      <el-icon>
                        <svg-icon name="i-ri:question-line" />
                      </el-icon>
                    </el-tooltip>
                    <span v-show="typeof form.meta.cache === 'object'" class="label-tip">切换为<el-link type="primary" :underline="false" @click.prevent="form.meta.cache = true">始终缓存</el-link></span>
                    <span v-show="typeof form.meta.cache === 'boolean'" class="label-tip">切换为<el-link type="primary" :underline="false" @click.prevent="form.meta.cache = []">规则模式</el-link></span>
                  </template>
                  <el-space v-show="typeof form.meta.cache === 'object'">
                    <el-tag v-for="item in (form.meta.cache as string[])" :key="item" size="large" closable :disable-transitions="false" @close="onInputCacheClose(item)">
                      {{ item }}
                    </el-tag>
                    <el-input v-if="inputCacheVisible" ref="InputCacheRef" v-model="inputCache" style="width: 200px;" @keyup.enter="onInputCacheConfirm" @blur="onInputCacheConfirm" />
                    <el-button v-else @click="onInputCacheShow">
                      新增
                    </el-button>
                  </el-space>
                  <div v-show="typeof form.meta.cache === 'boolean'">
                    始终缓存
                  </div>
                </el-form-item>
              </el-col>
              <el-col v-if="!!form.parentId" :xl="12" :lg="24">
                <el-form-item prop="meta.noCache">
                  <template #label>
                    不缓存规则
                    <el-tooltip content="当跳转到设置的路由时，则会对当前路由取消缓存" placement="top">
                      <el-icon>
                        <svg-icon name="i-ri:question-line" />
                      </el-icon>
                    </el-tooltip>
                    <span class="label-tip">当缓存规则为“始终缓存”时生效</span>
                  </template>
                  <el-space>
                    <el-tag v-for="item in (form.meta.noCache as string[])" :key="item" size="large" closable :disable-transitions="false" @close="onInputNoCacheClose(item)">
                      {{ item }}
                    </el-tag>
                    <el-input v-if="inputNoCacheVisible" ref="InputNoCacheRef" v-model="inputNoCache" style="width: 200px;" @keyup.enter="onInputNoCacheConfirm" @blur="onInputNoCacheConfirm" />
                    <el-button v-else @click="onInputNoCacheShow">
                      新增
                    </el-button>
                  </el-space>
                </el-form-item>
              </el-col>
              <el-col v-if="!!form.parentId" :xl="12" :lg="24">
                <el-form-item prop="meta.activeMenu">
                  <template #label>
                    高亮导航
                    <span class="label-tip">如果子路由不在导航显示，则需要设置高亮的上级路由地址</span>
                  </template>
                  <el-input v-model="form.meta.activeMenu" clearable placeholder="请输入高亮导航的完整路由地址" />
                </el-form-item>
              </el-col>
              <el-col v-if="!!form.parentId" :xl="12" :lg="24">
                <el-form-item prop="meta.badge">
                  <template #label>
                    徽标
                    <span class="label-tip">不宜设置太长，建议控制在4个字符内</span>
                  </template>
                  <el-input v-model="form.meta.badge" clearable placeholder="请输入徽标显示内容" />
                </el-form-item>
              </el-col>
              <el-col v-if="!!form.parentId" :xl="12" :lg="24">
                <el-form-item prop="meta.link">
                  <template #label>
                    访问外链
                    <span class="label-tip">请设置 http/https 开头的完整外链地址</span>
                  </template>
                  <el-input v-model="form.meta.link" clearable placeholder="请输入网址" />
                </el-form-item>
              </el-col>
              <el-col v-if="!!form.parentId" :xl="12" :lg="24">
                <el-form-item prop="meta.iframe">
                  <template #label>
                    内嵌网页
                    <span class="label-tip">请勿与外链同时设置，同时设置时，本设置会失效</span>
                  </template>
                  <el-input v-model="form.meta.iframe" clearable placeholder="请输入网址" />
                </el-form-item>
              </el-col>
              <el-col v-if="!!form.parentId" :xl="12" :lg="24">
                <el-form-item label="底部版权" prop="meta.copyright">
                  <el-switch v-model="form.meta.copyright" inline-prompt active-text="显示" inactive-text="隐藏" />
                </el-form-item>
              </el-col>
              <el-col v-if="!!form.parentId" :xl="12" :lg="24">
                <el-form-item prop="meta.paddingBottom">
                  <template #label>
                    底部填充高度
                    <span class="label-tip">请设置有效的长度单位，例如：px/em/rem等</span>
                  </template>
                  <el-input v-model="form.meta.paddingBottom" clearable placeholder="请输入显示名称" />
                </el-form-item>
              </el-col>
            </el-row>
          </el-scrollbar>
        </div>
        <div class="form-right-side">
          <page-header title="权限池">
            <template #content>
              <p>设置导航所具备的所有权限，权限池内的权限会用于角色管理</p>
              <p style="margin-bottom: 0;">
                通常只在最子级导航上进行设置
              </p>
            </template>
          </page-header>
          <el-table ref="authsTableRef" :key="authsTableKey" :data="form.auths" border stripe highlight-current-row>
            <el-table-column width="60" align="center" fixed>
              <template #header>
                <el-button type="primary" size="small" plain circle @click="onAuthAdd">
                  <template #icon>
                    <el-icon>
                      <svg-icon name="i-ep:plus" />
                    </el-icon>
                  </template>
                </el-button>
              </template>
              <template #default="scope">
                <span class="index">{{ scope.$index + 1 }}</span>
                <el-button type="danger" size="small" plain circle class="delete" @click="onAuthDelete(scope.$index)">
                  <template #icon>
                    <el-icon>
                      <svg-icon name="i-ep:delete" />
                    </el-icon>
                  </template>
                </el-button>
              </template>
            </el-table-column>
            <el-table-column width="80" align="center" fixed>
              <template #header>
                排序
              </template>
              <template #default>
                <el-tag type="info" class="sortable">
                  <el-icon>
                    <svg-icon name="i-ep:d-caret" />
                  </el-icon>
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="名称">
              <template #default="scope">
                <el-input v-model="scope.row.name" />
              </template>
            </el-table-column>
            <el-table-column label="标识">
              <template #default="scope">
                <el-input v-model="scope.row.value" />
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-form>
    </div>
    <div class="bottom-side">
      <el-button type="primary" @click="onSubmit">
        提交
      </el-button>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.form {
  flex: 1;
  position: relative;
  width: 100%;
  overflow: auto;
  display: flex;
  flex-direction: column;

  .top-side {
    flex: 1;
    height: 0;
    display: flex;

    .el-form {
      flex: 1;
      display: flex;
    }

    .page-header {
      background-color: var(--el-disabled-bg-color);
      margin-bottom: 0;
    }

    .form-left-side {
      flex: 1;
      padding: var(--container-padding);
      background-color: var(--g-app-bg);
      transition: background-color 0.3s;
      overflow: auto;

      .label-tip {
        display: inline-flex;
        margin-left: 10px;
        color: var(--el-text-color-disabled);
      }

      :deep(.el-scrollbar__view) {
        overflow-x: hidden;
      }
    }

    .form-right-side {
      display: flex;
      flex-direction: column;
      width: 500px;
      padding: var(--container-padding);
      border-left: 1px dashed var(--el-disabled-border-color);
      background-color: var(--g-app-bg);
      transition: background-color 0.3s;

      :deep(.el-table) {
        height: 100%;
        margin-top: 15px;

        .el-table__row {
          .index {
            display: inline-block;
          }

          .delete {
            display: none;
          }

          &:hover {
            .index {
              display: none;
            }

            .delete {
              display: inline-block;
            }
          }

          .el-tag.sortable,
          .el-tag.sortable .el-icon {
            cursor: s-resize;
          }
        }
      }
    }
  }

  .bottom-side {
    padding: var(--container-padding);
    border-top: 1px dashed var(--el-disabled-border-color);
    background-color: var(--g-app-bg);
    transition: background-color 0.3s;
    display: flex;
    justify-content: center;
  }
}
</style>
