<script setup lang="ts">
import { useAttrs, reactive, onMounted, watch, computed, ref } from 'vue'
import { usePropBind, LABEL_KEY } from './common'
import GdFormItem from './GdFormItem.vue';
import { getGroupList,getAllDictType,getDictName } from '@/api/workflowManagement'
// import { getAllDictType } from '@/api/commom'
import { 
  getWorkFlowNewList, getAllUser, getAllUserList, 
  getAllGroup, getAllDict, getAllForm, getAllPost, 
  getPost, getAllRole, getRole, getAllDeptPost, getDeptPost } 
  from '@/api/workflowManagement'
// import { getDictName } from '@/api/commom'

const { propValue, handleChange } = usePropBind()
const attrs = <any>useAttrs()

type Option = {
  label: string,
  value: any
}

const props = withDefaults(defineProps<{
  label: string,
  rules?: [],
  options?: Option[],
  type?: string,
  dictKey?: string,
  userDict?: boolean,
  flat?: boolean,
  multiple?: boolean,
  multipleLimit?: number
}>(), { label: '' })

const emit = defineEmits<{
  (e: 'selectionChange', val: any[]): void,
  (e: 'change', val: any): void
}>();

const state = reactive(<{ list: any[], selectedList: any[], query: string, pageSize: number, pageIndex: number, total: number, selectedLabel: string }>{
  list: [],
  selectedList: [],
  query: '',
  pageSize: 20,
  pageIndex: 1,
  total: 0,
  selectedLabel: ''
})

const SELECTION_API: any = {
  // 字典值
  dict: {
    action: getAllDict,
    actionSelected: getAllDict,
    filterable: false,
    params: () => ({ i_sch_dict_type: props.dictKey, i_sch_field: 'ALL', i_enable: "Y" }),
    formatter: ({ label, value }: any) => ({ label, value: String(value) })
  },
  // 用户选择
  user: {
    action: getAllUserList,
    actionSelected: getAllUser,
    filterable: true,
    params: (query: string) => ({ i_field: query, i_enable: "Y" }),
    formatter: ({ i_sys_no, i_user_name }: any) => ({ label: i_user_name, value: String(i_sys_no) })
  },
  // 分组选择
  role: {
    action: getGroupList,
    actionSelected: getAllGroup,
    filterable: true,
    params: (query: string) => ({ i_sch_field_role: query, i_enable: "Y" }),
    formatter: ({ i_role_id, i_role_name }: any) => ({ label: i_role_name, value: String(i_role_id) })
  },
  // 业务选择
  business: {
    action: getWorkFlowNewList,
    actionSelected: getAllForm,
    filterable: true,
    params: (query: string) => ({ i_is_applicant: false, i_sch_field: query }),
    formatter: ({ i_form_id, i_form_name }: any) => ({ label: i_form_name, value: String(i_form_id) })
  },
  // 字典类型名选择
  dict_type: {
    action: getDictName,
    actionSelected: getAllDictType,
    filterable: true,
    params: (query: string) => ({ i_field: query }),
    formatter: ({ label, value }: any) => ({ label, value })
  },
  // 字典类型名选择
  dict_type_design: {
    action: getDictName,
    actionSelected: getAllDictType,
    filterable: true,
    params: (query: string) => ({ i_field: query, i_enable: "Y" }),
    formatter: ({ label, value }: any) => ({ label, value })
  },
  //岗位
  post: {
    action: getAllPost,
    actionSelected: getPost,
    filterable: true,
    params: (query: string) => ({i_sch_field: query}),
    formatter: ({ label, value }: any) => ({ label, value })
  },
  //角色
  part: {
    action: getAllRole,
    actionSelected: getRole,
    filterable: true,
    params: (query: string) => ({i_sch_field: query}),
    formatter: ({ label, value }: any) => ({ label, value })
  },
  //部门|岗位
  dept_post: {
    action: getAllDeptPost,
    actionSelected: getDeptPost,
    filterable: true,
    params: (query: string) => ({i_sch_field: props.dictKey}),
    formatter: ({ label, value }: any) => ({ label, value })
  }
}

const getPage = async (index: number, isAppend?: boolean) => {
  if (props.options) {
    return
  }
  const { action, params, formatter } = SELECTION_API[props.type || '']
  const res = await action({ i_perpage: state.pageSize, i_pageindex: index, ...params(state.query) })
  if (res.resultCode !== '0') {
    return
  }
  state.pageIndex = index
  const data = res.dataList.map(formatter)
  if (isAppend) {
    return state.list = [...state.list, ...data]
  }
  state.list = data
  state.total = Number(res.i_total)
}
const isMounted = ref(false);
onMounted(() => {
  isMounted.value = true;
  getPage(1)
})

// 维护当前选中项目
watch(propValue, async (val: any, prev: any) => {
  if (val?.includes("ALL")) return
  try {
    if (!val || val === '') {
      state.selectedList = []
    } else if (!props.type || !SELECTION_API[props.type]?.actionSelected) {
      state.selectedList = state.list.filter(({ value }) => val?.split(',').includes(value))
    } else {
      const { dataList } = await SELECTION_API[props.type].actionSelected({ i_sch_field: val, i_sch_dict_type: props.dictKey })
      state.selectedList = dataList.map((item: any) => ({ ...item, label: item.label, value: String(item.value) })) || []
    }
  } catch (e) {
    console.error(e)
    state.selectedList = []
  }
  state.selectedLabel = state.selectedList.map(item => item.label).join(',')
  emit('selectionChange', state.selectedList)
}, { immediate: true })

const dictKey = computed(() => props.dictKey ? props.dictKey : '')
watch(dictKey, (val) => {
  hanldeFilter(val)
})

const hanldeFilter = async (query: string) => {
  state.query = query
  await getPage(1)
}
const hanldeAppend = async () => {
  if (state.total <= state.list.length) {
    return
  }
  await getPage(state.pageIndex + 1, true)
}
const propValueTransfer = computed(() => {
  if (props.multiple) {
    return propValue.value ? propValue.value.split(',') : []
  }
  return propValue.value
})
const handlePropValueChange = (value: any) => {
  const propValue = props.multiple ? value?.join(',') : value

  handleChange(propValue)
  emit('change', propValue)
}
const hiddenOptions = computed(() => {
  const listKeys = state.list.map(item => item.value)
  return state.selectedList.filter(item => !listKeys.includes(item.value))
})

const handleToggleAll = async () => {
  let result = ''

  if (propValueTransfer.value.length < (state.total + 1)) {
    const { dataList }: any = await getWorkFlowNewList({ i_is_applicant: false, i_perpage: state.total, i_pageindex: 1 })
    result = dataList.map((item: any) => item.i_form_id).join(',')
  }
  handleChange(result)
  emit('change', result)
}

defineExpose({ state, hanldeFilter })
</script>


<template>
  <GdFormItem :label="props.label" :rules="props.rules">
    <div class="viewer-content" v-if="attrs.viewerMode">
      <!-- <p v-if="type === 'user'" v-for="name in state.selectedLabel.split(',')"> -->
      <p class="smarg" v-if="type === 'user'" v-for="name in state.selectedLabel.split(',')">
        <el-icon v-if="name" color="rgb(200,200,200)">
          <UserFilled />
        </el-icon>
        {{ name }}
      </p>
      <!-- <p v-else> -->
      <p class="smarg" v-else>
        {{ state.selectedLabel }}
      </p>
    </div>
    <template v-else>
      <el-select v-if="!flat && isMounted" :model-value="propValueTransfer" @update:model-value="handlePropValueChange"
        :placeholder="`${$t('placeholder_prefix_select')?.replace(LABEL_KEY, props.label)}`"
        :filterable="type !== 'dict' && !options" remote :remote-method="hanldeFilter" :multiple="multiple"
        :multipleLimit="multipleLimit" clearable collapse-tags collapse-tags-tooltip v-bind="attrs" class="gd-select">
        <el-option-group v-infinite-scroll="hanldeAppend">
          <el-option v-for="item in hiddenOptions" :key="item.value" :label="item.label" :value="item.value"
            style="height: 0px" />
          <el-option v-if="type === 'business'" key="all" :label="$t('all')" value="ALL" @click="handleToggleAll" />
          <el-option v-for="item in options || state.list" :key="item.value" :label="item.label" :value="item.value" />
        </el-option-group>
      </el-select>
      <el-checkbox-group v-else-if="multiple" :model-value="propValueTransfer" @update:model-value="handlePropValueChange"
        v-bind="attrs" :max="multipleLimit">
        <el-checkbox v-for="item in options || state.list" :key="item.value" :label="item.value">{{ item.label
        }}</el-checkbox>
      </el-checkbox-group>
      <el-radio-group v-else :model-value="propValueTransfer" @update:model-value="handlePropValueChange" v-bind="attrs">
        <el-radio v-for="item in options || state.list" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
      </el-radio-group>
    </template>
  </GdFormItem>
</template>

<style lang="scss">
.gd-form .gd-select.el-select {
  width: 100%;
}

.smarg {
  margin: 0;
}
</style>
