<template>
  <div v-if="fieldNode" v-show="!isHidden">
    <div :class="{ 'cursor-pointer': expandable }" v-on="listeners">
      <a
        ref="anchor"
        class="subgroup-anchor"
        :name="anchorName"
        :id="anchorName"
      ></a>
      <span v-if="!hideLabel" class="text-subtitle1"
        >{{ label }}﻿<q-icon
          v-if="expandable"
          class="q-expansion-item__toggle-icon q-icon notranslate"
          :class="{ 'q-expansion-item__toggle-icon--rotated': expand }"
          name="keyboard_arrow_down"
      /></span>
    </div>
    <q-slide-transition>
      <div class="subgroup-holder q-mb-lg" v-show="expand">
        <slot />
      </div>
    </q-slide-transition>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import {
  ObjectMetaModel,
  ObjectMetaModelValue,
} from '@devsun/form-generator/dist';
import { FormGeneratorGroup } from '@devsun/form-generator';
import { isChildrensModelNotEmpty } from './group-utils';
import get from 'lodash/get';
import { isArray } from 'lodash';

@Component({
  components: {},
})
export default class CardFormGroup extends Vue {
  @Prop({ required: true }) model: ObjectMetaModel;
  @Prop({ required: true }) fieldNode: FormGeneratorGroup;
  @Prop() value: ObjectMetaModelValue;

  @Prop({}) index?: number;
  @Prop({}) hideNulls!: boolean;
  @Prop({}) labelTemplate?: string;
  @Prop({}) level: number;
  @Prop({}) rootLevel: number;

  private get expandable() {
    return get(this, 'fieldNode.fieldGroup.expandable', false);
  }

  private get expanded() {
    return get(this, 'fieldNode.fieldGroup.expanded', false);
  }

  private get hideLabel() {
    return get(this, 'fieldNode.fieldGroup.hideLabel', false);
  }

  private expand = !this.expandable || this.expanded;

  private toggleExpand() {
    this.expand = !this.expand;
  }

  get listeners(): Record<string, { (event?: unknown): void }> {
    if (!this.expandable) return {};
    return {
      click: this.toggleExpand,
    };
  }

  get anchorName(): string {
    return `group__${this.fieldNode.fieldGroup?.name}`;
  }

  get isHidden(): boolean {
    return (
      !this.checkShowCondition() ||
      (this.hideNulls && !isChildrensModelNotEmpty(this.fieldNode, this.model))
    );
  }

  private checkShowCondition(): boolean {
    const showCondition = this.fieldNode?.fieldGroup?.props?.showCondition;
    if (!showCondition || !isArray(showCondition)) return true;

    const val = get(this.model, showCondition.path, null);
    return showCondition.oneOf.some((v) => v === val);
  }

  get label(): string {
    if (this.labelTemplate) {
      const reg = /\${([\S]+?)}/g;

      return this.labelTemplate
        .replace(reg, (match) =>
          get(this.model, match.substring(2, match.length - 1))
        )
        .replace('$TEXT', () => (this.index >= 0 ? this.fieldNode.label : ''))
        .replace('$INDEX', () =>
          this.index >= 0 ? this.index.toString() : ''
        );
    } else if (this.fieldNode.label) {
      return `${this.fieldNode.label}${
        this.index >= 0 ? ` ${this.index}` : ''
      }`;
    } else {
      return '';
    }
  }
}
</script>
