<template>
  <div class="sidebar-tools">
    <el-collapse :modelValue="activePanel"
      @update:model-value="(panelName: any) => emit('update:activePanel', panelName)">
      <el-collapse-item name="formInfo">
        <template #title>
          <h3 class="title">{{ $t('form_info') }}</h3>
        </template>
        <el-form ref="mainForm" class="gd-form" :model="props.formConfig" label-position="top" style="padding: 10px;"
          inline-message :disabled="disabled" scroll-to-error>
          <GdInput :label="$t('form_title')" prop="title" required :maxlength="50" />
          <!-- <GdInput :label="$t('table_name')" prop="tableName" pattern="key" required :disabled="formConfig.activated" /> -->
          <GdInput :label="$t('prefix')" prop="prefix" pattern="prefix" :maxlength="5" />
          <GdInput :label="$t('desc')" prop="desc" type="textarea" required />
          <GdDatePicker :label="$t('start_date')" prop="startDate" :disabled-date="disabledStart" />
          <GdDatePicker :label="$t('end_date')" prop="endDate" :disabled-date="disabledEnd" />
          <GdSelect :label="$t('option_type')" prop="optionType" type="dict" dict-key="30_005"
            @change="() => props.formConfig.optionValue = ''" :clearable="false" />
          <GdTableSelect v-if="props.formConfig.optionType === PromoterOptionType.USER" :label="$t('user')"
            prop="optionValue" type="user" multiple required />
          <GdTreeSelect v-if="props.formConfig.optionType === PromoterOptionType.DEPARTMENT" :label="$t('organization')"
            prop="optionValue" type="organize" multiple required cascader />
          <GdSelect v-if="props.formConfig.optionType === PromoterOptionType.ROLE" :label="$t('role')" prop="optionValue"
            type="role" multiple required />
          <GdSelect v-if="props.formConfig.optionType === PromoterOptionType.POST" :label="$t('post')" prop="optionValue"
            type="post" multiple required />
          <GdSelect v-if="props.formConfig.optionType === PromoterOptionType.PART" :label="$t('part')" prop="optionValue"
            type="part" multiple required />
          <GdSwitch :label="$t('need_audit')" prop="needAudit" />
          <GdSwitch :label="$t('multilingual')" prop="multilingual" />
        </el-form>
      </el-collapse-item>
    </el-collapse>

    <el-tabs :modelValue="activeTab" @tab-change="(tabName: any) => emit('update:activeTab', tabName)">
      <el-tab-pane :label="$t('column_config')" :name="FormConfigType.COLUMN">
        <el-form ref="subForm" v-if="props.columnData.prop" :model="props.columnData" class="form gd-form" inline-message
          :disabled="disabled" scroll-to-error label-position="top">
          <template v-if="formItem">
            <h3>{{ $t('basic_prop') }}</h3>
            <GdInput v-if="props.formConfig.multilingual || lang === 'ch'" :label="$t('labelch')" prop="labelch" required
              :rules="uniqueRules('labelch')" :maxlength="50" />
            <GdInput v-if="props.formConfig.multilingual || lang === 'en'" :label="$t('labelen')" prop="labelen" required
              :rules="uniqueRules('labelen')" :maxlength="50" />
            <GdInput v-if="props.formConfig.multilingual || lang === 'jp'" :label="$t('labeljp')" prop="labeljp" required
              :rules="uniqueRules('labeljp')" :maxlength="50" />
            <!-- <GdInput :label="$t('prop')" prop="propAlias" pattern="key" required :rules="uniqueRules('propAlias', 'prop')"
              :disabled="formConfig.activated && columnData.saved" :maxlength="50" /> -->
            <GdSwitch v-if="formConfig.activated && columnData.saved" :label="$t('Deactivate')" prop="stopped"
              activeColor="red" />
          </template>
          <h3>{{ $t('control_prop') }}</h3>
          <!-- -----------------------输入框---------------- -->
          <template v-if="control === 'input' && type !== 'textarea'">
            <GdInputNumber :label="$t('maxlength')" prop="maxlength" :min="1" required @change="clearDefault" />
          </template>
          <!-- -----------------------多行输入框---------------- -->
          <template v-else-if="control === 'input' && type === 'textarea'">
            <GdInputNumber :label="$t('maxlength')" prop="maxlength" :min="1" required @change="clearDefault" />
            <GdInputNumber :label="$t('rows')" prop="rows" :min="1" :max="10" />
          </template>
          <!-- -----------------------数值输入框---------------- -->
          <template v-else-if="control === 'input-number'">
            <GdInputNumber :label="$t('min')" prop="min" :max="props.columnData.max" required @change="clearDefault" />
            <GdInputNumber :label="$t('max')" prop="max" :min="props.columnData.min" required @change="clearDefault" />
            <GdInputNumber :label="$t('precision')" prop="precision" :max="6" required @change="clearDefault" />

          </template>
          <!-- -----------------------字典选择器---------------- -->
          <template v-else-if="control === 'select' && type === 'dict'">
            <GdSelect :label="$t('dict_key')" prop="dictKey" type="dict_type_design" required @change="clearDefault" />
            <GdSwitch :label="$t('flat')" prop="flat" />
            <GdSwitch :label="$t('multiple')" prop="multiple" @change="clearDefault" />
            <GdInputNumber v-if="props.columnData.multiple" :label="$t('multiple_limit')" prop="multipleLimit" :min="1"
              :max="20" required @change="clearDefault" />
          </template>
          <!-- -----------------------日期选择器---------------- -->
          <template v-else-if="control === 'date-picker'">
            <GdSelect :label="$t('date_picker_type')" prop="type" type="dict" dict-key="30_006" required
              @change="clearDefault" />
          </template>
          <!-- -----------------------员工选择器---------------- -->
          <template v-else-if="control === 'table-select' && type === 'user'">
            <GdSwitch :label="$t('multiple')" prop="multiple" @change="clearDefault" />
            <!-- <GdInputNumber v-if="props.columnData.multiple" :label="$t('multiple_limit')" prop="multipleLimit" :min="1"
              required @change="clearDefault" /> -->
          </template>
          <!-- -----------------------分割线---------------- -->
          <template v-else-if="control === 'divider'">
            <GdInput :label="$t('divider_text')" prop="title" :maxlength="50" />
          </template>

          <!-- -----------------------表单项通用属性---------------- -->
          <template v-if="formItem">
            <GdSwitch :label="$t('required')" prop="required" />
            <GdSwitch v-if="control === 'date-picker'" :label="$t('default_date')" prop="systemDate"
              @change="clearDefault" />
            <FormItem v-if="control !== 'date-picker' || !props.columnData.systemDate"
              :key="`defaultPropValue_${controlValue.label}`"
              :element="{ ...props.columnData, [`label${lang}`]: $t('default_prop_value'), prop: 'defaultPropValue', required: false, defaultPropValue: undefined }" />
          </template>

          <h3>{{ $t('relation_prop') }}</h3>
          <GdSelect :key="props.columnData.prop" :label="$t('visible_prop')" prop="visibleProp" :options="controlOptions"
            @change="props.columnData.visibleValue = undefined" />
          <FormItem :key="`visibleValue_${controlValue.label}`"
            :element="{ ...controlValue, [`label${lang}`]: $t('visible_value'), prop: 'visibleValue', defaultPropValue: undefined }" />

        </el-form>
        <div class="placeholder_config" v-else>
          {{ $t('placeholder_column_config') }}
        </div>
      </el-tab-pane>
      <el-tab-pane :label="$t('audit_config')" :name="FormConfigType.AUDIT" v-if="props.formConfig.needAudit">
        <el-form ref="auditSubForm" class="form gd-form" :model="props.auditData" label-width="100px" inline-message
          :disabled="disabled" scroll-to-error label-position="top">
          <template v-if="props.auditData.type === 1">
            <GdInput :label="$t('flow_nodename')" prop="nodeName" required />
            <GdSelect :label="$t('option_type_audit')" prop="optionType" type="dict" dictKey="30_002"
              @change="onChangeAuditData" :clearable="false" required/>
            <GdSelect v-if="['3'].includes(props.auditData.optionType)" :label="$t('node_property')" prop="nodeProperty"
              type="dict" dictKey="30_003" :clearable="false" required/>
            <GdSelect v-if="['2'].includes(props.auditData.optionType)" :label="$t('node_property')" prop="nodeProperty"
              type="dict" dictKey="30_008" :clearable="false" required/>
            <GdSelect v-if="['5'].includes(props.auditData.optionType)" :label="$t('node_property')" prop="nodeProperty"
              type="dict" dictKey="30_009" :clearable="false" required/>
            <GdSelect v-if="['4','6'].includes(props.auditData.optionType)" :label="$t('node_property')" prop="nodeProperty"
              type="dict" dictKey="30_009" :clearable="false" required :disabled="true"/>
            <GdTableSelect v-if="props.auditData.optionType === AuditOptionType.USER" :label="$t('user')"
              prop="optionValue" type="user" multiple required />
            <GdTreeSelect v-if="props.auditData.optionType === AuditOptionType.DEPARTMENT" :label="$t('organization')"
              prop="optionValue" type="organize" multiple required onlyDept cascader/>
            <GdSelect v-if="props.auditData.optionType === AuditOptionType.ROLE" :label="$t('role')" prop="optionValue"
              type="role" multiple required />
            <GdSelect v-if="props.auditData.optionType === AuditOptionType.POST" :label="$t('post')" prop="optionValue"
              type="post" multiple required />
            <GdTreeSelect v-if="props.auditData.optionType === AuditOptionType.DEPTPOST" :label="$t('organization')" 
              prop="dept_post" type="organize" required onlyDept cascader @change="props.auditData.optionValue = ''"/>
            <GdSelect v-if="props.auditData.optionType === AuditOptionType.DEPTPOST && props.auditData.dept_post !== ''" 
              :label="$t('dept_post')" prop="optionValue" type="dept_post" :dictKey="props.auditData.dept_post" 
              multiple required />
            <GdSelect v-if="props.auditData.optionType === AuditOptionType.PART" :label="$t('part')" prop="optionValue"
              type="part" multiple required />
            <GdSelect v-if="props.auditData.optionValue?.split(',').length > 1" :label="$t('sign_type')" prop="signType"
              type="dict" dictKey="30_004" :clearable="false" required/>
          </template>
          <template v-else-if="props.auditData.type === 3">
            <GdInput :label="$t('flow_nodename')" prop="nodeName" required />
            <GdSelect :label="$t('business_column')" prop="businessColumn" :options="numberOptions" required />
            <GdSelect :label="$t('compare')" prop="compare" type="dict" dictKey="30_007" required />
            <GdInputNumber :label="$t('value')" prop="value" :min="optionControlValue.min" :max="optionControlValue.max"
              :precision="optionControlValue.precision" required />
          </template>
          <div class="placeholder_config" v-else>
            {{ $t('placeholder_audit_config') }}
          </div>
        </el-form>
      </el-tab-pane>
    </el-tabs>


  </div>
</template>

<script lang="ts" setup>
import { watch, ref, computed, getCurrentInstance, nextTick } from 'vue'
import { replace } from '@/utils/index';
import { FormInstance } from 'element-plus';
import FormItem from './formItem.vue';
import { PromoterOptionType, FormConfigType, AuditOptionType } from '@/model/enums'
import { useGlobalPinia } from '@/pinia/global'
import { LABEL_KEY } from '@/components/GdElement/common'
import moment from 'moment'
const $t: any = getCurrentInstance()?.appContext.config.globalProperties.$t
const { lang } = useGlobalPinia()

const props = defineProps<{
  formConfig: any,
  columnData: any,
  auditData: any,
  activePanel: string,
  activeTab: string,
  disabled?: boolean
}>()
const emit = defineEmits<{
  (e: 'update:formConfig', val: any): void
  (e: 'update:columnData', val: any): void
  (e: 'update:auditData', val: any): void
  (e: 'update:activePanel', val: string): void
  (e: 'update:activeTab', val: string): void
}>();
// 表单修改自动同步
const formItem = ref(true)
const control = ref('')
const type = ref('')
watch(props.columnData, (data) => {
  console.log({ ...data });

  const exist = props.formConfig.columnConfig.filter((item: any) => item.prop === data.prop)[0]
  replace(exist, data)
  control.value = data.control
  type.value = data.type
  formItem.value = !data.notFormItem
})
const clearDefault = () => {
  props.columnData.defaultPropValue = undefined
}

const modifyNode: any = (node: any) => {
  const { auditData } = props

  if (node.type === auditData.type && node.nodeId === auditData.nodeId) {
    if (auditData.type === 3) {
      const { businessColumn, compare, value } = auditData
      const isValid = businessColumn && compare && value
      auditData.expression = isValid ? `data['${businessColumn}'] ${compare} ${value}` : ''
    }
    replace(node, auditData)
    return true
  }

  if (node.childNode) {
    return modifyNode(node.childNode)
  }
  if (node.conditionNodes) {
    for (const item of node.conditionNodes) {
      if (modifyNode(item)) {
        return true
      }
    }
  }
}
watch(props.auditData, () => {
  modifyNode(props.formConfig.auditConfig);
})


const disabledStart = (date: any) => moment(date).isBefore(moment(moment().format("YYYY-MM-DD"))) || (props.formConfig.endDate && moment(date).isAfter(moment(props.formConfig.endDate)));
const disabledEnd = (date: any) => moment(date).isBefore(moment(props.formConfig.startDate || moment()))

// 关联显示属性
const controlOptions = computed(() => {
  return props.formConfig.columnConfig
    .filter((item: any) => !item.notFormItem && item.prop !== props.columnData.prop)
    .filter((item: any) => item.prop)
    .map((item: any) => ({ ...item, value: item.prop, label: item[`label${lang}`], defaultPropValue: undefined }))
})
const controlValue = computed(() => {
  return props.formConfig.columnConfig.filter((item: any) => item.prop === props.columnData.visibleProp)[0] || {}
})
const numberOptions = computed(() => {
  return props.formConfig.columnConfig
    .filter((item: any) => item.control === 'input-number' && item.propAlias)
    .map((item: any) => ({ ...item, value: item.propAlias, label: item[`label${lang}`] }))
})
const optionControlValue = computed(() => {
  return numberOptions.value.filter((item: any) => item.propAlias === props.auditData.businessColumn)[0] || {}
})

/** 表单循环校验 */
const mainForm = ref<FormInstance>()
const subForm = ref<FormInstance>()
const auditSubForm = ref<FormInstance>()
const validateNode: any = async (node: any) => {
  if ([1, 3].includes(node.type) && node.priorityLevel !== 999 && node) {
    replace(props.auditData, node)
    await nextTick(async () => await auditSubForm.value?.validate())
  }
  if (node.childNode) {
    await validateNode(node.childNode)
  }
  if (node.conditionNodes) {
    for (const item of node.conditionNodes) {
      await validateNode(item)
    }
  }
}
const validate = async () => {
  await mainForm.value?.validate()
  for (const data of props.formConfig.columnConfig) {
    replace(props.columnData, data)
    await nextTick(async () => await subForm.value?.validate())
  }
  if (props.formConfig.needAudit) {
    emit('update:activeTab', FormConfigType.AUDIT)
    await validateNode(props.formConfig.auditConfig)
  }
}
const uniqueRules = (prop: string, labelProp?: string) => ([
  {
    validator(rule: any, value: any, callback: any) {
      if (props.formConfig.columnConfig.filter((item: any) => !item.notFormItem && item[prop] === value && item.prop !== props.columnData.prop).length > 0) {
        callback(`${$t('check_unique')?.replace(LABEL_KEY, $t(labelProp || prop))}`)
      } else {
        callback()
      }
    }
  }
])
defineExpose({ validate })

const onChangeAuditData = () => {
  props.auditData.optionValue = ''
  props.auditData.nodeProperty = '1'
  props.auditData.signType = '1'
  props.auditData.dept_post = ''
}
</script>

<style scoped>
.title {
  padding-left: 10px;
}

.control-attr-empty {
  text-align: center;
  color: darkgray;
  margin-bottom: 10px;
}

.placeholder_config {
  padding: 50px 0;
  text-align: center;
  color: gainsboro;
}
</style>