import { Component, Prop, Watch } from 'vue-property-decorator';
import uniq from 'lodash/uniq';
import get from 'lodash/get';
import isEmpty from 'lodash/isEmpty';
import has from 'lodash/has';
import Vue from 'vue';

@Component
export default class ReferenceBookItem extends Vue {
  @Prop() dictionary!: string;
  @Prop({ default: 'value' }) name!: string;
  @Prop({ default: false }) nested!: boolean;
  @Prop() selectedGroupIndex!: number; // using only for "nested" case
  @Prop() value!: string;

  loading = true;

  @Watch('options')
  onOptionsChange(options: any): void {
    this.$emit('load', options);
  }

  get referenceBook() {
    return this.$store.getters['registryService/referenceBooks/referenceBooks'][
      this.dictionary
    ];
  }

  get options() {
    if (isEmpty(this.referenceBook)) {
      return [];
    }

    const GROUPS: string[] = uniq([
      ...Object.values(this.referenceBook)
        .map((value: any) => Object.keys(value))
        .flat(1),
    ]);

    let options: ReferenceBooksItemOption[];

    if (GROUPS.length > 1 && this.nested) {
      options = GROUPS.map((group) => {
        const groupChildren: ReferenceBooksItemOption[] = [];

        Object.entries(this.referenceBook).forEach(([key, value]: any[]) => {
          if (value[group]) {
            groupChildren.push({
              label: value[group],
              value: key,
            });
          }
        });

        return {
          label: group,
          children: groupChildren,
        };
      });

      if (
        this.selectedGroupIndex !== null &&
        has(options, [this.selectedGroupIndex, 'children'])
      ) {
        options = options[this.selectedGroupIndex]
          .children as ReferenceBooksItemOption[];
      }
    } else {
      options = Object.entries(this.referenceBook).map(
        ([key, value]: any[]) => ({
          label: value[this.name],
          value: key,
        })
      );
    }

    return options;
  }

  get outValue() {
    if (this.selectedGroupIndex >= 0) {
      return get(
        this.referenceBook,
        `[${this.selectedGroupIndex}][${this.value}]${this.name}`,
        this.value
      );
    }
    return get(this.referenceBook, `[${this.value}]${this.name}`, this.value);
  }

  async created() {
    const ref = {
      id: this.dictionary,
      valueName: this.name,
      // type: this.fieldNode.rawAttrs.dictionaryType,
      // value: external,
    } as any;
    if (ref.id) {
      this.loading = true;
      await this.$store.dispatch(
        'registryService/referenceBooks/initReferenceBooks',
        [ref]
      );
      this.$emit('load', this.options);
      this.loading = false;
    }
  }
}

// todo perform better - without "?"
export type ReferenceBooksItemOption = ReferenceBooksItemSingleOption &
  ReferenceBooksItemMultipleOption;

export interface ReferenceBooksItemSingleOption {
  label: string;
  value?: string;
}

export interface ReferenceBooksItemMultipleOption {
  label: string;
  children?: ReferenceBooksItemOption[];
}
