<template>
  <div class="modify-form">
    <el-form
      label-position="right"
      :class="class"
      :label-width="width ? width + 'px' : ''"
      :model="param"
      ref="modifyForm"
      :rules="rules"
    >
      <template v-for="item in items">
        <el-form-item :label="item.name || t(item.i18n)" :prop="item.code" v-if="!modify || (modify && !item.noModify)">
          <template v-if="item.dict || item.maxValue">
            <NoobSelect
              v-if="!item.readonly"
              v-model="param[item.code]"
              :dict="item.dict"
              :max-value="item.maxValue"
              full
              :placeholder="t('rule.pleaseSelect') + (item.name || t(item.i18n))"
              :disabled="item.disabled"
            />
            <el-input v-else readonly :model-value="sysDict[item.dict as string][param[item.code]]" />
          </template>
          <template v-else-if="item.date">
            <NoobDate
              v-if="!item.readonly"
              v-model="param[item.code]"
              :formater="item.formater"
              full
              :placeholder="t('rule.pleaseSelect') + (item.name || t(item.i18n))"
              :disabled="item.disabled || item.readonly"
            />
            <TzDateTime
              v-else
              :value="param[item.code]"
              :value-format="item.formater"
              display-format="YYYY-MM-DD HH:mm:ss"
              slot
            >
              <template #default="{ display }">
                <el-input :model-value="display" readonly />
              </template>
            </TzDateTime>
            <!--            <span>{{ param[item.code].toString() }}</span>-->
          </template>
          <slot v-else-if="item.slot" :name="item.code" />
          <NoobInput
            v-else
            v-model="param[item.code]"
            full
            :type="item.type"
            :rows="item.rows"
            :placeholder="item.readonly || item.disabled ? '空' : t('rule.pleaseEnter') + (item.name || t(item.i18n))"
            :disabled="item.disabled"
            :readonly="item.readonly"
          />
        </el-form-item>
      </template>
      <slot></slot>
      <el-form-item class="form-btns">
        <NoobButton type="primary" @click="formConfirm">{{ t(confirm) }}</NoobButton>
        <NoobButton type="info" @click="emit('cancel')">{{ t(cancel) }}</NoobButton>
      </el-form-item>
    </el-form>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, ref, watch } from "vue";
import { FormInstance } from "element-plus";
import { useI18n } from "vue3-i18n";
import { NoobSelect, NoobInput, NoobDate, NoobButton, TzDateTime, useSysDict } from "noob-mengyxu";

const { t } = useI18n();
const { sysDict, updateDict } = useSysDict();

interface FormItem {
  code: string;
  name?: string;
  i18n?: string;
  dict?: string;
  maxValue?: number;
  date?: boolean;
  formater?: string;
  slot?: boolean;
  type?: string;
  rows?: number;
  disabled?: boolean;
  noModify?: boolean;
  readonly?: boolean;
}

interface Props {
  width?: number;
  param?: Record<string, any>;
  rules?: Record<string, any>;
  class?: string;
  type?: string | null;
  modify?: boolean;
  items?: FormItem[];
  confirm?: string;
  cancel?: string;
}

const prop = withDefaults(defineProps<Props>(), {
  width: 80,
  param: () => ({}),
  rules: () => ({}),
  class: "",
  type: null,
  modify: false,
  items: () => [],
  confirm: "base.confirm",
  cancel: "base.cancel",
});

const emit = defineEmits<{
  confirm: [];
  cancel: [];
}>();

const modifyForm = ref<FormInstance>();

const formConfirm = () => {
  if (!modifyForm.value) return;
  modifyForm.value?.validate((valid, fields) => {
    if (valid) {
      emit("confirm");
      modifyForm.value?.clearValidate();
    }
  });
};

const clearValidate = () => {
  modifyForm.value?.clearValidate();
};

watch(
  () => prop.param,
  () => {
    modifyForm.value?.clearValidate();
  }
);

defineExpose({ clearValidate });

onMounted(async () => {
  await updateDict(prop.items.map((item) => item.dict).filter(Boolean) as string[]);
});
</script>

<style lang="scss" scoped>
//@import url(); 引入公共css类
:deep(.el-select) {
  width: 100%;
}

:deep(.el-date-editor) {
  width: 100% !important;
}

:deep(.el-autocomplete) {
  width: 100%;
}
</style>
