<template>
  <BasicModal
    v-bind="$attrs"
    @register="registerModal"
    showFooter
    :title="getTitle"
    width="50%"
    @ok="handleSubmit"
  >
    <div class="modal-padding-box">
      <BasicForm @register="registerForm" />

      <BasicTable @register="registerTable" v-if="isCustom == 1" class="dataAuthDrag !mb-5 !px-4">
        <template #toolbar>
          <a-button type="primary" @click="handleCreate"> {{ t('添加过滤条件') }} </a-button>
        </template>
        <template #bodyCell="{ column, text, record }">
          <template
            v-if="
              ['drag', 'fieldName', 'fieldType', 'fieldValue', 'conditionType'].includes(
                column.dataIndex,
              )
            "
          >
            <div>
              <Icon
                class="mover"
                icon="ant-design:drag-outlined"
                v-if="column.dataIndex == 'drag'"
              />

              <a-select
                class="w-full"
                :placeholder="t('请选择')"
                v-else-if="column.dataIndex == 'conditionType'"
                v-model:value="record[column.dataIndex]"
              >
                <a-select-option :value="0">{{ t('等于') }}</a-select-option>
                <a-select-option :value="1">{{ t('大于') }}</a-select-option>
                <a-select-option :value="2">{{ t('大于等于') }}</a-select-option>
                <a-select-option :value="3">{{ t('小于') }}</a-select-option>
                <a-select-option :value="4">{{ t('小于等于') }}</a-select-option>
                <a-select-option :value="5">{{ t('包含') }}</a-select-option>
                <a-select-option :value="6">{{ t('包含于') }}</a-select-option>
                <a-select-option :value="7">{{ t('不等于') }}</a-select-option>
                <a-select-option :value="8">{{ t('不包含') }}</a-select-option>
                <a-select-option :value="9">{{ t('不包含于') }}</a-select-option>
              </a-select>
              <a-input
                v-if="column.dataIndex == 'fieldName'"
                v-model:value="record[column.dataIndex]"
                :placeholder="t('请填写字段名')"
              />
              <a-select
                class="w-full"
                :placeholder="t('请选择字段类型')"
                v-else-if="column.dataIndex == 'fieldType'"
                v-model:value="record[column.dataIndex]"
                @change="(_, option) => changeFieldType(record, option)"
              >
                <a-select-option v-for="item in typeOptions" :value="item.value" :key="item.value">
                  <a-tooltip>
                    <template #title>
                      <span>{{ t(item.label) }}</span>
                    </template>
                    {{ t(item.label) }}
                  </a-tooltip>
                </a-select-option>
              </a-select>
              <a-input
                v-else-if="column.dataIndex == 'fieldValue'"
                v-model:value="record[column.dataIndex]"
                :placeholder="
                  record['fieldType'] === undefined ? t('请先选择字段类型') : t('请填写字段值')
                "
                :disabled="record['fieldType'] > 1"
                :readonly="record['fieldType'] === undefined"
              />
            </div>
          </template>
          <template v-else-if="column.dataIndex == 'action'">
            <TableAction
              :actions="[
                {
                  color: 'error',
                  label: t('删除'),
                  popConfirm: {
                    title: t('是否确认删除'),
                    confirm: handleDelete.bind(null, record),
                  },
                },
              ]"
            />
          </template>
          <template v-else> {{ text }} </template>
        </template>
      </BasicTable>

      <a-form
        :model="formState"
        name="basic"
        autocomplete="off"
        :label-col="{ style: { width: '100px' } }"
        layout="vertical"
        class="!px-4"
      >
        <a-form-item name="authFormula" v-if="isCustom == 1">
          <template #label>
            {{ t('组合公式') }}
            <Tooltip color="rgba(0,0,0,0.9)" :overlayStyle="{ maxWidth: '448px' }">
              <template #title>
                <div class="tipdiv">
                  <p>{{ t('请按如下规则编辑条件组合') }}</p>
                  <p
                    >{{ t('正确示例: (1 and 2) or (3 and 4)') }}
                    <Icon icon="ant-design:check-circle-outlined" color="green"
                  /></p>
                  <p>{{ t('1.有and和or必须加括号') }}</p>
                  <p class="text-[pink]"
                    >{{ t('错误示例:1 and 2 or 3 and 4') }}
                    <Icon icon="ant-design:close-circle-outlined" color="pink"
                  /></p>
                  <p>{{ t('2.一个括号里不能同时出现and和or') }}</p>
                  <p class="text-[pink]"
                    >{{ t('错误示例: (1 and 2 or 3 )and 4') }}
                    <Icon icon="ant-design:close-circle-outlined" color="pink" />
                  </p>
                  <p>{{ t('3.不允许出现不存在的编号') }}</p>
                  <p class="text-[pink]"
                    >{{ t('错误示例: 1 and 2 and 3 and 4 and 5') }}
                    <Icon icon="ant-design:close-circle-outlined" color="pink"
                  /></p>
                  <p>{{ t('4.括号都是成对出现的') }}</p>
                  <p class="text-[pink]"
                    >{{ t('错误示例: (1 and 2 and 3 and 4') }}
                    <Icon icon="ant-design:close-circle-outlined" color="pink"
                  /></p>
                </div>
              </template>
              <Icon icon="ant-design:question-circle-outlined" color="#999" />
            </Tooltip>
          </template>
          <a-textarea
            v-model:value="formState.authFormula"
            :placeholder="
              t(
                '请填写组合公式,组合公式非必填，如果不填写，则按照已有条件并列执行，例如：1 and 2 and 3 and 4,填写后，按照填写的公式进行执行',
              )
            "
          />
        </a-form-item>

        <a-form-item :label="t('备注')" name="remark">
          <a-textarea v-model:value="formState.remark" :placeholder="t('请输入备注')" />
        </a-form-item>
      </a-form>
    </div>
  </BasicModal>
</template>
<script lang="ts">
  import { defineComponent, ref, computed, unref, reactive, h, watch, nextTick } from 'vue';
  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
  import { BasicTable, useTable, TableAction, BasicColumn } from '/@/components/Table';
  import { BasicModal, useModalInner } from '/@/components/Modal';

  import { Tooltip } from 'ant-design-vue';

  import { useMessage } from '/@/hooks/web/useMessage';
  // import { useI18n } from 'vue-i18n';

  import Sortable from 'sortablejs';
  import { getRoleAllList } from '/@/api/system/role';
  import SelectUser from '/@/components/Form/src/components/SelectUser.vue';
  import { Icon } from '/@/components/Icon';
  import { isNullAndUnDef } from '/@/utils/is';

  import { addAuth, updateAuth } from '/@/api/system/authorize';
  import { useI18n } from '/@/hooks/web/useI18n';
  const { t } = useI18n();
  const typeOptions = [
    {
      value: 0,
      label: '文本(String)',
    },
    {
      value: 1,
      label: '文本(Int)',
    },
    {
      value: 2,
      label: '登录人ID',
    },
    {
      value: 3,
      label: '登录人组织架构ID',
    },
    {
      value: 4,
      label: '登录人所属组织架构ID及下属组织架构ID',
    },
    {
      value: 5,
      label: '登录人账号',
    },
    {
      value: 6,
      label: '登录人岗位ID',
    },
    {
      value: 7,
      label: '登录人角色ID',
    },
  ];
  export const columns: BasicColumn[] = [
    {
      title: '',
      dataIndex: 'drag',
      width: 40,
    },
    {
      title: t('序号'),
      dataIndex: 'orderNumber',
      width: 50,
    },
    {
      title: t('字段名'),
      dataIndex: 'fieldName',
      width: 160,
    },
    {
      title: t('条件'),
      dataIndex: 'conditionType',
    },
    {
      title: t('字段类型'),
      dataIndex: 'fieldType',
      width: 160,
    },
    {
      title: t('字段值'),
      dataIndex: 'fieldValue',
      width: 160,
    },
  ];
  interface FormState {
    authFormula: string;
    remark: string;
  }
  interface DataItem {
    key?: string;
    orderNumber: number;
    fieldName: string;
    conditionType: number;
    fieldType?: number;
    fieldValue: string;
  }
  const isCustom = ref<number>(0);
  const editableData = ref<DataItem[]>([]);
  const selectUser = ref<boolean>(false);
  export default defineComponent({
    name: 'MenuDrawer',
    components: {
      BasicModal,
      BasicForm,
      TableAction,
      BasicTable,
      Tooltip,
      Icon,
    },
    emits: ['success', 'register'],
    setup(_, { emit }) {
      const isValidDate = ref(false);
      const formSchema: FormSchema[] = [
        {
          field: 'code',
          label: t('权限编码'),
          component: 'Input',
          required: true,
          colProps: { lg: 12, md: 12 },
        },
        {
          field: 'name',
          label: t('名称'),
          component: 'Input',
          required: true,
          colProps: { lg: 12, md: 12 },
        },
        {
          field: 'authType',
          label: t('对象类型'),
          component: 'Select',
          required: true,
          defaultValue: 0,
          colProps: { lg: 12, md: 12 },
          componentProps: {
            options: [
              {
                label: t('角色'),
                value: 0,
              },
              {
                label: t('用户'),
                value: 1,
              },
              {
                label: t('所有用户'),
                value: 2,
              },
            ],
            onChange: (v) => {
              if (v == 2) {
                clearValidate(['objectIdList']);
              } else if (isValidDate.value) {
                validate();
              }
            },
          },
        },
        {
          field: 'objectIdList',
          label: t('授权对象'),
          component: 'Input',
          required: true,
          colProps: { lg: 12, md: 12 },
          render: ({ model, field }) => {
            return h(SelectUser, {
              placeholder: t('请选择授权对象'),
              value: model[field],
              suffix: 'ant-design:ellipsis-outlined',
              disabled: model.authType == 2 ? true : false,
              onSelectedId: (v) => {
                model[field] = v;
              },
            });
          },
          dynamicRules: ({ values }) => {
            return values.authType == 2 ? [] : [{ required: true, message: t('请选择授权对象') }];
          },
          ifShow: ({ values }) => {
            return values.authType == 1 || values.authType == 2;
          },
        },
        {
          field: 'objectId',
          label: t('授权对象'),
          component: 'Select',
          required: true,
          colProps: { lg: 12, md: 12 },
          componentProps: {
            options: [],
            'filter-option': null,
            mode: 'multiple',
            'show-search': true,
            fieldNames: {
              label: 'name',
              value: 'id',
            },
          },
          ifShow: ({ values }) => {
            return values.authType === 0;
          },
        },
        {
          field: 'authMethod',
          label: t('授权方式'),
          component: 'Select',
          defaultValue: 0,
          required: true,
          componentProps: {
            options: [
              {
                label: t('简易模式'),
                value: 0,
              },
              {
                label: t('自定义配置'),
                value: 1,
              },
            ],
            onChange: (v) => {
              isCustom.value = v;
            },
          },
          colProps: { lg: 12, md: 12 },
        },

        {
          field: 'authScope',
          label: t('实现范围'),
          component: 'Select',
          required: true,
          componentProps: {
            options: [
              {
                label: t('仅查看登录人数据'),
                value: 0,
              },
              {
                label: t('仅查看登录人同岗位数据'),
                value: 1,
              },
              {
                label: t('仅查看登录人及所有下属岗位数据'),
                value: 2,
              },
              {
                label: t('仅查看登录人同岗位及所有下属岗位数据'),
                value: 3,
              },
              {
                label: t('仅查看登录人同组织架构人员数据'),
                value: 4,
              },
              {
                label: t('仅查看登录人及所有下属组织架构人员数据'),
                value: 5,
              },
              {
                label: t('仅查看登录人同组织架构人员及所有下属组织架构人员数据'),
                value: 6,
              },
              {
                label: t('仅查看登录人同角色数据'),
                value: 7,
              },
            ],
          },
          colProps: { lg: 12, md: 12 },
          ifShow: ({ values }) => {
            return values.authMethod === 0;
          },
        },
      ];
      const isUpdate = ref(true);
      const { notification } = useMessage();
      const rowId = ref('');
      const formState = reactive<FormState>({
        authFormula: '',
        remark: '',
      });

      watch(
        () => editableData.value,
        (val) => {
          if (val && val.length) {
            nextTick(() => {
              const tbody: any = document.querySelector('.dataAuthDrag .ant-table-tbody');
              const tr: any = tbody.querySelector('tr.ant-table-row[draggable="false"]');
              if (tr) tr.remove();
              Sortable.create(tbody, {
                handle: '.mover',

                onEnd: (evt) => {
                  const { oldIndex, newIndex } = evt;
                  if (
                    isNullAndUnDef(oldIndex) ||
                    isNullAndUnDef(newIndex) ||
                    oldIndex === newIndex
                  ) {
                    return;
                  }

                  let columns: DataItem[] = getDataSource();

                  setTableData([]);

                  editableData.value = [];
                  nextTick(() => {
                    let old = columns[oldIndex - 1];
                    columns.splice(oldIndex - 1, 1);
                    columns.splice(newIndex - 1, 0, old);
                    columns.forEach((o, i) => {
                      o.orderNumber = i + 1;
                    });
                    editableData.value = columns;
                    setTableData(editableData.value);
                  });
                },
              });
            });
          }
        },
        {
          deep: true,
        },
      );

      watch(isCustom, (val) => {
        if (val === 1) {
          //首次进入清除自定义表格内容
          nextTick(() => {
            setTableData(editableData.value);
          });
        }
      });

      const [registerForm, { resetFields, setFieldsValue, updateSchema, validate, clearValidate }] =
        useForm({
          layout: 'vertical',
          schemas: formSchema,
          showActionButtonGroup: false,
          rowProps: { gutter: 32 },
        });

      const [registerTable, { getDataSource, setTableData }] = useTable({
        title: '',
        dataSource: editableData.value,
        columns,
        pagination: false,
        striped: false,
        useSearchForm: false,
        showIndexColumn: false,
        canResize: false,
        rowKey: 'id',
        actionColumn: {
          width: 70,
          title: t('操作'),
          dataIndex: 'action',
          slots: { customRender: 'action' },
          fixed: undefined,
        },
      });
      const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
        resetFields();
        setModalProps({ confirmLoading: false, fixedHeight: true });
        isUpdate.value = !!data?.isUpdate;
        editableData.value = [];
        const treeData = await getRoleAllList();
        const filterOption = (input: string, option: any) => {
          return option.name.indexOf(input) >= 0;
        };
        updateSchema({
          field: 'objectId',
          componentProps: { options: treeData, 'filter-option': filterOption },
        });
        if (unref(isUpdate)) {
          rowId.value = data.record.id;
          let arrData: string[] = [];
          data.record.authObjectList.forEach((o) => {
            arrData.push(o.objectId);
          });
          if (data.record.authType == 1) {
            data.record.objectIdList = arrData.join(',');
          } else {
            data.record.objectId = arrData;
          }
          setFieldsValue({
            ...data.record,
          });
          isCustom.value = data.record.authMethod;
          formState.remark = data.record.remark;
          if (isCustom.value == 1) {
            formState.authFormula = data.record.authFormula;
            editableData.value = data.record.authConfigList;
            nextTick(() => {
              setTableData(editableData.value);
            });
          }
        } else {
          isCustom.value = 0;
        }
      });

      function handleCreate() {
        let dataSource: DataItem[] = getDataSource();
        let obj = {
          orderNumber: dataSource.length + 1,
          fieldName: '',
          conditionType: 0,
          fieldValue: '',
        };
        dataSource.push(obj);
        editableData.value = dataSource;
        setTableData(dataSource);
      }

      function changeFieldType(record: Recordable, option) {
        record.fieldValue = record.fieldType > 1 ? option.label : '';
      }

      function handleDelete(record: Recordable) {
        const dataSource: DataItem[] = getDataSource();
        editableData.value = [];
        dataSource.forEach((o) => {
          if (o.orderNumber < record.orderNumber) {
            editableData.value.push(o);
          } else if (o.orderNumber > record.orderNumber) {
            o.orderNumber -= 1;
            editableData.value.push(o);
          }
        });
        setTableData(editableData.value);
      }

      const getTitle = computed(() => (!unref(isUpdate) ? t('新增数据权限') : t('编辑数据权限')));

      async function handleSubmit() {
        try {
          isValidDate.value = true;
          const values = await validate();
          if (values.authType == 1) {
            values.objectIdList = values.objectIdList.split(',');
          } else {
            values.objectIdList = values.objectId;
          }
          if (values.authMethod == 1) {
            values.authConfigList = getDataSource();
            Object.assign(values, formState);
          } else {
            values.remark = formState.remark;
          }

          setModalProps({ confirmLoading: true });
          // TODO custom api
          if (!unref(isUpdate)) {
            //false 新增
            await addAuth(values);
            notification.success({
              message: t('提示'),
              description: t('新增成功'),
            }); //提示消息
          } else {
            values.id = rowId.value;
            await updateAuth(values);
            notification.success({
              message: t('提示'),
              description: t('编辑成功'),
            }); //提示消息
          }
          closeModal();
          emit('success');
        } catch (error) {
          setModalProps({ confirmLoading: false });
        }
      }

      return {
        registerModal,
        registerForm,
        editableData,
        formState,
        getTitle,
        isCustom,
        selectUser,
        handleSubmit,
        registerTable,
        handleCreate,
        changeFieldType,
        handleDelete,
        t,
        typeOptions,
      };
    },
  });
</script>
<style scoped>
  .tipdiv p {
    margin: 0;
  }

  :deep(.vben-basic-table) {
    height: auto;
  }

  .modal-padding-box {
    height: 100%;
    padding: 16px 0;
  }
</style>
