<template>
  <a-modal
    v-model:visible="visible"
    :title="`${role?.roleId ? $t('sys.update') : $t('sys.add')}${$t(
      'role.name'
    )}`"
    width="480px"
    :after-close="onCancel"
    @ok="saveHandler"
  >
    <template #footer>
      <a-button class="action-bottom" size="middle" @click="visible = false">
        {{ $t('sys.cancel') }}
      </a-button>
      <a-button
        class="action-bottom"
        type="primary"
        size="middle"
        @click="saveHandler"
      >
        {{ $t('sys.save') }}
      </a-button>
    </template>

    <a-form
      ref="fromRef"
      :model="editRole"
      class="form"
      label-align="right"
      :label-col="{ span: 5 }"
    >
      <a-form-item
        name="roleName"
        :label="$t('role.roleNameLabel')"
        :rules="[{ required: true, message: $t('role.roleNameRule') }]"
      >
        <a-input
          v-model:value="editRole.roleName"
          :maxlength="30"
          show-count
          :placeholder="$t('role.roleNameRule')"
        />
      </a-form-item>
      <a-form-item
        name="remark"
        :label="$t('role.remarkLabel')"
        :rules="[{ required: false, max: 50, message: $t('role.remarkRule') }]"
      >
        <a-textarea
          v-model:value.trim="editRole.remark"
          :resize="false"
          style="height: 104px; resize: none"
          :placeholder="$t('role.remarkRule')"
        />
      </a-form-item>
      <a-form-item name="roleMenus" :label="$t('role.roleMenusLabel')">
        <div class="menu-layer ant-input">
          <a-tree
            v-if="menuTree.length"
            :disable-checkbox="defaultRoles"
            :checked-keys="
              Array.from(new Set([...editRole.menuIds, ...defaultRoles]))
            "
            default-expand-all
            checkable
            :tree-data="menuTree"
            @update:checked-keys="(ids: any) => (editRole.menuIds = ids)"
          />
        </div>
      </a-form-item>
    </a-form>
  </a-modal>
</template>

<script lang="ts" setup>
import { ref, defineProps, toRaw, onMounted } from 'vue'
import { RoutesName } from '@/router'
import { useRoleStore, useProject, MenuTree } from '@/store'
import { ui18n } from '@/lang'
import { message } from 'ant-design-vue'

import { Role } from '@/api'
import type { FormInstance } from 'ant-design-vue'

export type EditRole = PartialPart<Role, 'roleId' | 'createTime'>

defineOptions({ name: 'EditMember' })

const props = defineProps<{
  role?: EditRole
  onSave: (data: EditRole) => void
  onCancel: () => void
}>()
const roleStore = useRoleStore()
const projectStore = useProject()
const defaultRoles = ref<Role['roleId'][]>([])
const menuTree = ref<MenuTree[]>([])

const editRole = ref<EditRole>(
  props.role
    ? { ...props.role }
    : {
        projectName: projectStore.current?.projectName || '',
        remark: '',
        roleName: '',
        menuIds: []
      }
)
const fromRef = ref<FormInstance>()
const visible = ref(true)

const saveHandler = async () => {
  if (!editRole.value.roleName.trim()) {
    message.error(ui18n.t('role.roleNameRule'))
    return
  }
  await fromRef.value?.validate()
  await props.onSave({
    ...toRaw(editRole.value),
    remark: editRole.value.remark || '',
    menuIds: Array.from(
      new Set([...editRole.value.menuIds, ...defaultRoles.value])
    )
  })
  visible.value = false
}

onMounted(async () => {
  await roleStore.fetch()
  defaultRoles.value = roleStore.getRoleIds([
    RoutesName.projectScenes,
    RoutesName.personal
  ])
  menuTree.value = roleStore.getMenuTree(defaultRoles.value)
})
</script>

<style lang="scss" scoped>
.footer {
  display: flex;
  justify-content: space-between;
  align-items: center;

  p {
    margin-bottom: 0;
    color: #646566;
    font-size: 14px;
  }
}
</style>
