<script setup lang="ts">
import type { FormInstance } from 'antdv-next'
import apiSysMenu from '@/api/modules/sysMenu'

export interface Props { id?: number | string; parent_id?: number }
const props = withDefaults(defineProps<Props>(), { id: '', parent_id: undefined })

const loading = ref(false)
const formRef = useTemplateRef<FormInstance>('formRef')
const form = ref({
  id: props.id as number | string, menu_name: '', parent_id: props.parent_id as number | undefined,
  order_num: 0, path: '', component: '', menu_type: 'M', visible: '0', status: '0',
  perms: '', icon: '', remark: '',
})

const rules = { menu_name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }] }

// Parent menu options
const parentOptions = ref<{ value: number; label: string }[]>([])

onMounted(() => {
  apiSysMenu.tree().then((res: any) => {
    const flatten = (list: any[]): any[] => {
      let result: any[] = []
      for (const item of list) {
        result.push({ value: item.id, label: item.menu_name })
        if (item.children) result = result.concat(flatten(item.children))
      }
      return result
    }
    parentOptions.value = flatten(res.data || [])
  })
  if (form.value.id !== '') getInfo()
})

function getInfo() {
  loading.value = true
  // For menu, we use tree and find by id, or use the item directly
  apiSysMenu.tree().then((res: any) => {
    loading.value = false
    const findById = (list: any[], id: number): any => {
      for (const item of list) {
        if (item.id === id) return item
        if (item.children) {
          const found = findById(item.children, id)
          if (found) return found
        }
      }
      return null
    }
    const d = findById(res.data || [], form.value.id as number)
    if (d) {
      Object.assign(form.value, {
        menu_name: d.menu_name, parent_id: d.parent_id, order_num: d.order_num,
        path: d.path, component: d.component || '', menu_type: d.menu_type,
        visible: d.visible, status: d.status, perms: d.perms || '',
        icon: d.icon || '', remark: d.remark || '',
      })
    }
  })
}

defineExpose({
  submit() {
    return new Promise<void>((resolve) => {
      formRef.value?.validate().then(() => {
        apiSysMenu.save(form.value).then(() => { faToast.success(form.value.id ? '编辑成功' : '新增成功'); resolve() })
      }).catch(() => {})
    })
  },
})
</script>

<template>
  <div v-if="loading" class="flex-center py-12"><ASpin /></div>
  <AForm v-else ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }">
    <AFormItem label="上级菜单" name="parent_id">
      <ASelect v-model:value="form.parent_id" placeholder="无（根菜单）" allow-clear :options="parentOptions" />
    </AFormItem>
    <AFormItem label="菜单名称" name="menu_name"><AInput v-model:value="form.menu_name" placeholder="请输入菜单名称" /></AFormItem>
    <AFormItem label="菜单类型" name="menu_type">
      <ASelect v-model:value="form.menu_type" :options="[{ value: 'M', label: '目录' }, { value: 'C', label: '菜单' }, { value: 'F', label: '按钮' }]" />
    </AFormItem>
    <AFormItem v-if="form.menu_type !== 'F'" label="路由地址" name="path">
      <AInput v-model:value="form.path" placeholder="请输入路由地址" />
    </AFormItem>
    <AFormItem v-if="form.menu_type === 'C'" label="组件路径" name="component">
      <AInput v-model:value="form.component" placeholder="请输入组件路径" />
    </AFormItem>
    <AFormItem label="权限标识" name="perms"><AInput v-model:value="form.perms" placeholder="请输入权限标识" /></AFormItem>
    <AFormItem label="图标" name="icon"><AInput v-model:value="form.icon" placeholder="请输入图标" /></AFormItem>
    <AFormItem label="排序" name="order_num"><AInputNumber v-model:value="form.order_num" class="w-full" /></AFormItem>
    <AFormItem label="显示状态" name="visible">
      <ASelect v-model:value="form.visible" :options="[{ value: '0', label: '显示' }, { value: '1', label: '隐藏' }]" />
    </AFormItem>
    <AFormItem label="状态" name="status"><ASelect v-model:value="form.status" :options="[{ value: '0', label: '正常' }, { value: '1', label: '停用' }]" /></AFormItem>
    <AFormItem label="备注" name="remark"><ATextarea v-model:value="form.remark" placeholder="请输入备注" :rows="2" /></AFormItem>
  </AForm>
</template>
