<template>
  <ElForm :style="getStyle()" :label-width="labelWidth" class="FormConfig" size="mini">
    <ElFormItem class="formItem" :rules="getRules(item)" v-for="(item, index) in formList" :key="item.key"
      :label="item.label" :style="gridStyle(item, index)">
      <slot :name="item.key" :data="item" :formData="formData">
        <component :is="getComponent(item.type)" v-bind="getBindData(item)" v-model="formData[item.key]" />
      </slot>
    </ElFormItem>
  </ElForm>
</template>

<script>
import { resolveName } from "./utils/index"
import { reduceDefaultValue } from "./utils/defaultValue"

const files = require.context('./components', true, /^.\/[^/]+\/index\.vue$|^.\/[^/]+.vue$/);

const components = files.keys().reduce((prev, key) => {
  prev[key.match(/[^./]+/g)[0]] = files(key).default;

  return prev;
}, {
  Empty: 'div'
})

export default {
  name: 'FormConfig',
  components: {
    // FormInput,
    // FormTimePicker
  },
  provide() {
    return {
      getComponent: this.getComponent,
      getBindData: this.getBindData
    }
  },
  props: {
    /**
     * {
     *  label: String;
     *  key: String;
     *  type: 'input' | 'timePicker',
     *  gridArea?: "",
     *  gridColumn?: "",
     *  gridRow?: "",
     *  options?: {}
     * }[]
     */
    formList: {
      type: Array,
      default: () => []
    },
    labelWidth: {
      type: String,
      default: "auto"
    },
    rules: {
      type: Object,
      default: null
    },
    column: {
      type: [String, Number],
      default: "3"
    }
  },
  data() {
    return {
      formData: {}
    }
  },
  created() {
    this.reset();
  },
  computed: {
    gridStyle() {
      return (item, index) => ({
        gridRow: `span ${item.gridRow || 1}`,
        gridColumn: `span ${item.gridColumn || item.isAlone && this.column || 1}`,
      })
    }
  },
  methods: {
    reset() {
      return this.formData = reduceDefaultValue(this.formList);
    },
    getStyle() {
      return {
        gridTemplateColumns: `repeat(${this.column}, 1fr)`,
      }
    },
    getBindData(item) {
      return {
        placeholder: "请输入",
        ...item.options
      }
    },
    getComponent(type) {
      if (!type) type = 'input';

      const componentKey = resolveName(type);

      const ElComponentKey = `El${componentKey}`;

      return components[componentKey] || components[ElComponentKey] || ElComponentKey;
    },
    getRules(item) {
      if (this.rules?.[item.key]) return this.rules[item.key];

      if (item.rules) return item.rules;

      if (item.required) return [
        {
          required: true,
          message: `${item.options?.placeholder || `${item.label}不能为空`}`,
          trigger: "blur",
        },
      ]
    }
  }
}
</script>

<style lang='scss' scoped>
.FormConfig {
  display: grid;
  align-content: start;
  width: 100%;
  gap: 15px 15px;
  overflow-x: hidden;

  .formItem {
    display: flex;
    align-items: center;
  }


  ::v-deep {
    .el-form-item {
      align-items: center;
      margin: 0;
      height: 100%;

      &:first-child {
        .el-form-item__label-wrap {
          // padding-top: 9px;
        }
      }

      .el-form-item__label-wrap {
        width: fit-content;
      }

      .el-form-item__label {
        height: 22px;
        font-size: 15px;
        // font-family: PingFang SC, PingFang SC;
        font-weight: 400;
        color: #3DE8FF;
        line-height: 19px;
        // -webkit-background-clip: text;
        // -webkit-text-fill-color: transparent;
      }

      .el-form-item__content {
        margin: 0 !important;
        flex: 1;
        height: 100%;

        .el-input__prefix {
          color: #fff;
        }
      }
    }
  }
}
</style>
