<template>
  <a-form
    :model="form"
    ref="formRef"
    label-align="left"
    :label-col="{ span: 6 }"
    :wrapper-col="{ span: 18 }"
  >
    <a-row>
      <a-col :span="24">
        <a-form-item
          label="权限名称"
          :label-col="{ span: 3 }"
          :wrapper-col="{ span: 21 }"
          name="description"
          required
          :rules="[{ required: true, message: '请输入权限名称' }]"
        >
          <a-input
            v-model:value="form.description"
            placeholder="请输入权限名称"
          />
        </a-form-item>
      </a-col>
    </a-row>
    <a-row>
      <a-col :span="24">
        <a-form-item
          label="菜单类型"
          :label-col="{ span: 3 }"
          :wrapper-col="{ span: 21 }"
          name="permType"
        >
          <a-select
            v-model:value="form.permType"
            placeholder="请选择菜单类型"
          >
            <a-select-option
              v-for="(item) in permTypeList"
              :key="item.id"
              :value="item.id"
            >{{ item.name }}</a-select-option>
          </a-select>
        </a-form-item>
      </a-col>
    </a-row>
    <a-row>
      <a-col :xs="24">
        <a-form-item
          label="父级权限"
          :label-col="{ span: 3 }"
          :wrapper-col="{ span: 21 }"
          name="parentId"
        >
          <a-cascader
            v-model:value="form.parentId"
            :options="parentOptions"
            change-on-select
            placeholder="请选择父级权限"
            @change="changeParent"
          />
        </a-form-item>
      </a-col>
    </a-row>
    <a-row>
      <a-col :span="24">
        <a-form-item
          label="权限编码"
          :label-col="{ span: 3 }"
          :wrapper-col="{ span: 21 }"
          name="code"
          required
          :rules="[{ required: true, message: '请输入权限编码' }]"
        >
          <a-input
            v-model:value="form.code"
            placeholder="请输入权限编码"
            :addon-before="form.pcode"
          />
        </a-form-item>
      </a-col>
    </a-row>
    <a-row>
      <a-col :xs="24">
        <a-form-item
          label="类型"
          :label-col="{ span: 3 }"
          :wrapper-col="{ span: 21 }"
          name="type"
          required
          :rules="[{ required: true, message: '请选择类型' }]"
        >
          <a-select
            v-model:value="form.type"
            placeholder="请选择类型"
          >
            <a-select-option
              v-for="(item) in typeList"
              :key="item.id"
              :value="item.id"
            >{{ item.name }}</a-select-option>
          </a-select>
        </a-form-item>
      </a-col>
    </a-row>
  </a-form>
</template>

<script setup>
import { ref } from 'vue'
import { callUser } from '@/apis/call.js'
import { message } from 'ant-design-vue'
import _ from 'lodash'

const formRef = ref();
const formData = () => ({
  permId: "",
  description: "",
  permCode: "",
  level: "",
  parentId: "",
  type: "",
  pcode: "",
  code: "",
  permType: null
});
const form = ref(formData());
const data = ref([]);
const parentValues = ref([])
const parentOptions = ref([])
const typeList = ref([{
  id: 0,
  name: '最高权限'
}, {
  id: 1,
  name: '页面权限'
}, {
  id: 2,
  name: '按钮权限'
}, {
  id: 3,
  name: '接口权限'
}])
const permTypeList = ref([{
  id: 0,
  name: '全系统'
}, {
  id: 1,
  name: 'PC端'
}, {
  id: 2,
  name: '小程序端'
}])

const openForm = (params = {}) => {
  form.value = {
    ...formData()
  }
  loadParentData(params);
};

const loadPermData = (permId) => {
  if (permId) {
    callUser("/permissions/getInfo/" + permId, {}, "get").then(res => {
      if (res.code == 200) {
        if (res.data) {
          form.value = {
            ...res.data
          };
          const permCode = res.data.permCode;
          if (res.data.parentId === null || res.data.parentId === undefined) {
            form.value.code = permCode;
            form.value.pcode = "";
          }
          else {
            form.value.code = permCode.substring(permCode.lastIndexOf('.') + 1);
            form.value.pcode = permCode.substring(0, permCode.lastIndexOf('.'));
          }
          if (parentOptions.value.length > 0) {
            parentValues.value = getParentValues(parentOptions.value, res.data.permId);
            form.value.parentId = parentValues.value
            console.log(parentValues.value)
          }
        }
      } else {
        message.error(res.message);
      }
    });
  }
}

function getParentValues(tree, targetId, path = []) {
  for (const node of tree) {
    if (node.permId === targetId) {
      return path;
    }
    if (node.children) {
      const result = getParentValues(node.children, targetId, [...path, node.permId]);
      if (result) return result;
    }
  }
  return null; // 未找到目标节点
}

const loadParentData = (params) => {
  parentOptions.value = [];
  callUser("/permissions/list", {}, "get").then((res) => {
    if (res.code != 200) {
      message.error(res.message)
      parentOptions.value = []
      data.value = []
      return
    }
    data.value = res.data
    data.value = data.value.map((item) => {
      return { ...item, value: item.permId, label: item.description }
    })
    parentOptions.value = buildTreeWithChildren(data.value)

    if (params['permId']) {
      loadPermData(params['permId']);
    }
  })
}

const buildTreeWithChildren = (data) => {
  const map = new Map();
  const roots = [];
  data.forEach(item => {
    map.set(item.permId, { ...item });
  });
  data.forEach(item => {
    const child = map.get(item.permId);
    if (item.parentId === null || item.parentId === undefined) {
      roots.push(child);
    } else {
      const parent = map.get(item.parentId);
      if (parent) {
        parent.children = parent.children || [];
        parent.children.push(child);
      } else {
        roots.push(child);
      }
    }
  });
  return roots;
}

const changeParent = (data) => {

  const item = findItemByValue(parentOptions.value, data[data.length - 1]);
  form.value.permCode = item.permCode
}

const findItemByValue = (options, value) => {
  for (const option of options) {
    if (option.permId == value) {
      return option;
    }
    if (option.children) {
      const found = findItemByValue(option.children, value);
      if (found) {
        return found;
      }
    }
  }
  return null;
}

const formSave = (callBack) => {
  formRef.value.validate().then((res) => {
    const data = _.cloneDeep(res);
    let params = {
      ...data,
      parentId: !Array.isArray(data['parentId']) ? data['parentId'] : data['parentId'][data['parentId'].length - 1],
      level: data['parentId'].length == 0 ? 1 : data['parentId'].length + 1,
      permCode: form.value.permCode + "." + data['code'].toLowerCase()
    }
    delete params['code']
    if (form.value.permId) {
      params['permId'] = form.value.permId;
      params['permCode'] = form.value.pcode + "." + form.value.code;
      callUser("/permissions/update", params).then(res => {
        if (res.code != 200) {
          message.error(res.message);
          if (callBack) {
            callBack(false, res);
          }
          return;
        }
        if (callBack) {
          callBack(true, res);
        }
        resetAll();
      }).catch(error => {
        if (callBack) {
          callBack(false, error);
        }
      });
    }
    else {
      callUser("/permissions/save", params).then(res => {
        if (res.code != 200) {
          message.error(res.message);
          if (callBack) {
            callBack(false, res);
          }
          return;
        }
        if (callBack) {
          callBack(true, res);
        }
        resetAll();
      }).catch(error => {
        if (callBack) {
          callBack(false, error);
        }
      });
    }
  });
};

const resetAll = (callBack) => {
  Object.assign(form.value, formData());
  data.value = [];
  parentOptions.value = [];
  formRef.value.resetFields();
  if (callBack) {
    callBack(true, form.value);
  }
}

defineExpose({ openForm, formSave, resetAll });
</script>
