<template>
  <view class="dynamic-form">
    <view v-for="(field, index) in fields" :key="field.key" class="form-section">
      <!-- 单行文本 -->
      <view v-if="field.type === 'text'" class="form-item">
        <text :class="['form-label', field.is_required === true ? 'required' : '']">{{ field.label }}</text>
        <input type="text" :value="formData[field.key]" :placeholder="field.placeholder" placeholder-class="placeholder"
          class="form-input" @input="onInput(field.key, $event)" />
      </view>

      <!-- 多行文本 -->
      <view v-else-if="field.type === 'textarea'" class="detail-card">
        <view class="detail-row">
          <text :class="['form-label', field.is_required === true ? 'required' : '']">{{ field.label }}</text>
          <view class="detail-textarea-wrap">
            <textarea class="detail-textarea" :value="formData[field.key]" :placeholder="field.placeholder"
              placeholder-class="placeholder" maxlength="200" @input="onInput(field.key, $event)" />
            <text class="detail-count">{{ (formData[field.key] || '').length }}/200</text>
          </view>
        </view>
      </view>

      <!-- 数字输入 -->
      <view v-else-if="field.type === 'number'" class="form-item" :style="field.tip ? 'flex-wrap: wrap;' : ''">
        <text :class="['form-label', field.is_required === true ? 'required' : '']">{{ field.label }}</text>
        <input type="digit" :value="formData[field.key]" :placeholder="field.placeholder"
          placeholder-class="placeholder" class="form-input" @input="onInput(field.key, $event)" />
        <text v-if="field.tips && !field.tip" class="form-tips">{{ field.tips }}</text>
        <view v-if="field.tip" class="price-tip">
          <text class="price-tip-card">{{ field.tip }}</text>
        </view>
      </view>

      <!-- 多图上传 -->
      <view v-else-if="field.type === 'image_multi'" class="form-item-up upload-item">
        <view>
          <text :class="['form-label', field.is_required === true ? 'required' : '']">{{ field.label }}</text>
          <text class="upload-tip">(仅可上传{{ field.maxCount || 9 }}个图片)</text>
        </view>
        <view class="upload-content">
          <form-item-image :value="formData[field.key]" :maxCount="field.maxCount || 9"
            @input="onInput(field.key, $event)" />
        </view>
      </view>

      <!-- 视频上传 -->
      <view v-else-if="field.type === 'video'" class="form-item-up upload-item">
        <view>
          <text :class="['form-label', field.is_required === true ? 'required' : '']">{{ field.label }}</text>
          <text class="upload-tip">(仅可上传1个视频)</text>
        </view>
        <view class="upload-content">
          <form-item-video :value="formData[field.key]" @input="onInput(field.key, $event)" />
        </view>
      </view>

      <!-- 下拉选择 -->
      <view v-else-if="field.type === 'select'" class="form-item">
        <text :class="['form-label', field.is_required === true ? 'required' : '']">{{ field.label }}</text>
        <form-item-select :value="formData[field.key]" :options="field.options || []" :placeholder="field.placeholder"
          @input="onInput(field.key, $event)" />
      </view>

      <!-- 单选 -->
      <view v-else-if="field.type === 'single_select'" class="form-item" style="flex-wrap: wrap;">
        <text :class="['form-label', field.is_required === true ? 'required' : '']">{{ field.label }}</text>
        <view class="select-options">
          <form-item-radio :value="formData[field.key]" :options="field.options || []"
            @input="onInput(field.key, $event)" />
        </view>
      </view>

      <!-- 多选 -->
      <view v-else-if="field.type === 'multi_select'" class="form-item" style="flex-wrap: wrap;">
        <text :class="['form-label', field.is_required === true ? 'required' : '']">{{ field.label }}</text>
        <view class="select-options">
          <form-item-checkbox :value="formData[field.key]" :options="field.options || []"
            :maxCount="field.maxCount || 0" @input="onInput(field.key, $event)" />
        </view>
      </view>

      <!-- 图文编辑器 -->
      <view v-else-if="field.type === 'richtext_editor'" class="form-item">
        <text :class="['form-label', field.is_required === true ? 'required' : '']">{{ field.label }}</text>
        <form-item-richtext :value="formData[field.key]" @input="onInput(field.key, $event)" />
      </view>
    </view>
  </view>
</template>

<script>
import FormItemText from './FormItemText.vue';
import FormItemTextarea from './FormItemTextarea.vue';
import FormItemNumber from './FormItemNumber.vue';
import FormItemImage from './FormItemImage.vue';
import FormItemVideo from './FormItemVideo.vue';
import FormItemSelect from './FormItemSelect.vue';
import FormItemRadio from './FormItemRadio.vue';
import FormItemCheckbox from './FormItemCheckbox.vue';
import FormItemRichtext from './FormItemRichtext.vue';

export default {
  name: 'DynamicForm',
  components: {
    'form-item-text': FormItemText,
    'form-item-textarea': FormItemTextarea,
    'form-item-number': FormItemNumber,
    'form-item-image': FormItemImage,
    'form-item-video': FormItemVideo,
    'form-item-select': FormItemSelect,
    'form-item-radio': FormItemRadio,
    'form-item-checkbox': FormItemCheckbox,
    'form-item-richtext': FormItemRichtext
  },
  props: {
    fields: {
      type: Array,
      default: function () { return []; }
    },
    value: {
      type: Object,
      default: function () { return {}; }
    }
  },
  data: function () {
    return {
      formData: {}
    };
  },
  watch: {
    value: {
      handler: function (val) {
        this.formData = Object.assign({}, val);
      },
      immediate: true
    },
    fields: {
      handler: function () {
        var self = this;
        var data = {};
        this.fields.forEach(function (field) {
          if (self.formData[field.key] !== undefined) {
            data[field.key] = self.formData[field.key];
          } else if (field.default_value !== undefined) {
            data[field.key] = field.default_value;
          } else if (field.type === 'multi_select' || field.type === 'image_multi') {
            data[field.key] = [];
          } else {
            data[field.key] = '';
          }
        });
        this.formData = Object.assign({}, this.formData, data);
      },
      immediate: true
    }
  },
  methods: {
    onInput: function (key, event) {
      var value = event;
      if (event && event.target && event.target.value !== undefined) {
        value = event.target.value;
      }
      this.$set(this.formData, key, value);
      this.$emit('input', this.formData);
    },
    getData: function () {
      return Object.assign({}, this.formData);
    },
    validate: function () {
      var self = this;
      for (var i = 0; i < this.fields.length; i++) {
        var field = this.fields[i];
        if (field.is_required === true) {
          var value = self.formData[field.key];
          if (!value || (Array.isArray(value) && value.length === 0)) {
            uni.showToast({
              title: field.label + '不能为空',
              icon: 'none'
            });
            return false;
          }
        }
      }
      return true;
    }
  }
};
</script>

<style scoped>
.dynamic-form {
  width: 100%;
}

.form-section {
  width: 100%;
}

.form-item {
  background-color: #fff;
  padding: 24rpx;
  display: flex;
  flex-flow: row nowrap;
  justify-content: space-between;
  align-items: center;
  box-sizing: border-box;
  border-radius: 10rpx;
  margin-bottom: 24rpx;
}

.form-label {
  font-size: 28rpx;
  color: #333333;
}

.required::before {
  content: '*';
  color: #ff0000;
  margin-right: 4rpx;
}

.form-tips {
  font-size: 24rpx;
  color: #999999;
  margin-left: 10rpx;
}

.price-tip {
  width: 100%;
  margin-top: 40rpx;
}

.price-tip-card {
  padding: 8rpx 12rpx;
  background: #FDF0F0;
  border-radius: 8rpx;
  font-weight: 400;
  font-size: 24rpx;
  color: #E8101E;
  line-height: 32rpx;
}

.form-item-up {
  background-color: #fff;
  padding: 24rpx;
  display: flex;
  flex-flow: column nowrap;
  justify-content: space-between;
  align-items: flex-start;
  box-sizing: border-box;
  border-radius: 10rpx;
  margin-bottom: 24rpx;
}

.upload-item {
  padding-bottom: 30rpx;
}

.upload-tip {
  font-size: 24rpx;
  color: #999999;
  margin-left: 10rpx;
}

.upload-content {
  margin-top: 20rpx;
  width: 100%;
}

.select-options {
  width: 100%;
  margin-top: 16rpx;
}

.detail-card {
  background: #ffffff;
  border-radius: 20rpx;
  padding: 0 24rpx 8rpx;
  margin-bottom: 24rpx;
  box-sizing: border-box;
  overflow: hidden;
}

.detail-row {
  padding: 24rpx 0 36rpx;
}

.detail-row .form-label {
  display: block;
  margin-bottom: 20rpx;
  line-height: 40rpx;
}

.detail-textarea-wrap {
  position: relative;
  background: #f7f7f7;
  border-radius: 16rpx;
  padding: 24rpx 24rpx 52rpx;
  box-sizing: border-box;
}

.detail-textarea {
  width: 100%;
  height: 108rpx;
  min-height: 108rpx;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  font-size: 28rpx;
  line-height: 40rpx;
  color: #333333;
  box-sizing: border-box;
}

.detail-count {
  position: absolute;
  right: 24rpx;
  bottom: 16rpx;
  font-size: 22rpx;
  color: #999999;
  line-height: 32rpx;
}
</style>
