<template>
  <div :class="classes">
    <app-form-item2
      :caption="caption"
      :labelStyle="labelStyle"
      :error="error"
      :labelPos="labelPos"
      :labelWidth="labelWidth"
      :isShowCaption="isShowCaption"
      :isEmptyCaption="isEmptyCaption"
      :name="name"
      :uiStyle="uiStyle"
      :itemRules="itemRules"
      :required="required"
      :tipTag="tipTag"
    >
      <slot></slot>
    </app-form-item2>
  </div>
</template>
<script lang="ts">
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';

@Component({})
export default class AppFormItem extends Vue {

  /**
   * 属性标识
   *
   * @type {*}
   * @memberof AppFormItem
   */
  @Prop()
  tipTag?: string;

  /**
   * 表单的模型对象
   *
   * @type {*}
   * @memberof AppFormItem
   */
  @Prop() controlInstance?: any;

  /**
   * 名称
   *
   * @type {string}
   * @memberof AppFormItem
   */
  @Prop() caption!: string;

  /**
   * 错误信息
   *
   * @type {string}
   * @memberof AppFormItem
   */
  @Prop() error?: string;

  /**
   * label样式
   *
   * @type {string}
   * @memberof AppFormItem
   */
  @Prop() labelStyle?: string;

  /**
   * 标签位置
   *
   * @type {(string | 'BOTTOM' | 'LEFT' | 'NONE' | 'RIGHT' | 'TOP')}
   * @memberof AppFormItem
   */
  @Prop() labelPos?: string | 'BOTTOM' | 'LEFT' | 'NONE' | 'RIGHT' | 'TOP';

  /**
   * 标签宽度
   *
   * @type {number}
   * @memberof AppFormItem
   */
  @Prop({}) labelWidth!: number;

  /**
   * 是否显示标题
   *
   * @type {boolean}
   * @memberof AppFormItem
   */
  @Prop() isShowCaption?: boolean;

  /**
   * 标签是否空白
   *
   * @type {boolean}
   * @memberof AppFormItem
   */
  @Prop() isEmptyCaption?: boolean;

  /**
   * 表单项名称
   *
   * @type {string}
   * @memberof AppFormItem
   */
  @Prop() name!: string;

  /**
   * 内置样式
   *
   * @type {string}
   * @memberof AppFormItem
   */
  @Prop() uiStyle?: string;

  /**
   * 表单项值规则
   *
   * @type {string}
   * @memberof AppFormItem
   */
  @Prop() itemRules!: any;

  /**
   * 表单项实例
   *
   * @type {*}
   * @memberof AppFormItem
   */
  itemRef: any = null;

  /**
   * 是否显示表单项Label提示
   *
   * @memberof AppFormItem
   */
  isShowTip: boolean = false;

  /**
   * 值规则数组
   *
   * @type {any[]}
   * @memberof AppFormItem
   */
  rules: any[] = [];

  /**
   * 是否必填
   *
   * @type {boolean}
   * @memberof AppFormItem
   */
  @Prop({ default: false }) required!: boolean;

  /**
   * 表单项值规则监控
   *
   * @param {*} newVal
   * @param {*} oldVal
   * @memberof AppFormItem
   */
  @Watch('itemRules', { deep: true })
  onItemRulesChange(newVal: any, oldVal: any) {
    if (newVal) {
      try {
        this.rules = [];
        const _rules: any[] = newVal;
        this.rules = [..._rules];
      } catch (error) {}
    }
  }

  /**
   * 计算样式
   *
   * @readonly
   * @type {string []}
   * @memberof AppFormItem
   */
  get classes(): string[] {
    let posClass = '';
    switch (this.labelPos) {
      case 'TOP':
        posClass = 'label-top';
        break;
      case 'LEFT':
        posClass = 'label-left';
        break;
      case 'BOTTOM':
        posClass = 'label-bottom';
        break;
      case 'RIGHT':
        posClass = 'label-right';
        break;
      case 'NONE':
        posClass = 'label-none';
        break;
    }
    return ['app-form-item', posClass];
  }

  /**
   * label样式
   *
   * @readonly
   * @type {string}
   * @memberof AppFormItem
   */
  get labelclasses(): string {
    return this.labelStyle ? this.labelStyle + ' app-form-item-label' : 'app-form-item-label';
  }

  /**
   * label行内样式
   *
   * @readonly
   * @type {string}
   * @memberof AppFormItem
   */
  get labelstyle(): any {
    if (Object.is(this.labelPos, 'LEFT') || Object.is(this.labelPos, 'RIGHT')) {
      return { width: this.labelWidth + 'px' };
    }
  }

  /**
   * slot行内样式
   *
   * @readonly
   * @type {string}
   * @memberof AppFormItem
   */
  get slotstyle(): any {
    if (Object.is(this.labelPos, 'LEFT')) {
      return { marginLeft: this.labelWidth + 'px' };
    } else if (Object.is(this.labelPos, 'RIGHT')) {
      return { marginRight: this.labelWidth + 'px' };
    }
  }

  /**
   * 视图样式
   *
   * @readonly
   * @type {string}
   * @memberof AppFormItem
   */
  get viewStyle(): any {
    return this.controlInstance?.getParentPSModelObject?.()?.viewStyle || 'DEFAULT';
  }

  /**
   * vue 生命周期
   *
   * @memberof AppFormItem
   */
  mounted() {
    this.itemRef = this.$refs[this.name];
    if (this.itemRules) {
      try {
        const _rules: any[] = this.itemRules;
        this.rules = [..._rules];
      } catch (error) {}
    }
    this.getShowTip();
  }

  /**
   * 计算是否显示表单项Label提示
   *
   * @memberof AppFormItem
   */
  getShowTip() {
    if (this.caption && this.caption.length * 14 > this.labelWidth) {
      this.isShowTip = true;
    }
  }
}
</script>
<style lang='less'>
@import './app-form-item.less';
</style>