<i18n>
{
  "en": {
    "title": {
      "create": "Create",
      "edit": "Edit"
    },
    "label": {
      "period": "Suspension period",
      "cause": "Cause suspension",
      "goal": "Target"
    },
    "rules": {
      "error": {
        "numberTerm": "min value 1",
        "causeMax": "max length text 2000 char`s",
        "causeMin": "required",
        "goal": "required"
      }
    }
  },
  "ru": {
    "title": {
      "create": "Добавить приостановку",
      "edit": "Редактировать приостановку"
    },
    "label": {
      "period": "Срок приостановки",
      "cause": "Причина в приостановки",
      "goal": "Цель"
    },
    "rules": {
      "error": {
        "numberTerm": "Минимальное значение 1",
        "causeMax": "Максимальная длина текста 2000 символов",
        "causeMin": "Поле обязательно к заполнению",
        "goal": "Необходимо выбрать значение"
      }
    }
  }
}
</i18n>

<template>
  <q-dialog v-model="dialogOpen" @hide="clearModel">
    <q-card class="full-width no-shadow" style="max-width: 800px">
      <q-card-section>
        <div class="text-h6">{{ formTitle }}</div>
      </q-card-section>

      <form v-if="dataModel" @submit.prevent.stop="handleSubmit">
        <q-card-section class="q-pb-xs">
          <q-input
            v-model.number="dataModel.numberTerm"
            ref="inputNumberTerm"
            type="number"
            filled
            min="1"
            :label="$t('label.period')"
            :rules="[rulesNumberTerm]"
          />
          <q-checkbox
            v-model="dataModel.inCalendarDays"
            label="В календарных днях"
          />
        </q-card-section>

        <q-card-section class="q-pb-xs">
          <q-input
            v-model="cause"
            ref="inputCause"
            type="textarea"
            filled
            :label="$t('label.cause')"
          />
          <q-btn icon="add" @click="createCause(cause)" />
        </q-card-section>

        <q-card-section>
          <q-table
            :columns="causeTableColumns"
            :data="dataModel.causeList"
          >
            <template v-slot:body="props">
              <q-tr :props="props">
                <q-td key="reason" :props="props">
                  {{ props.row.reason }}
                </q-td>
                <q-td key="actions" :props="props">
                  <q-btn
                    icon="edit"
                    text-color="primary"
                    @click="editReason(props.row)"
                  />
                  <q-btn
                    icon="delete"
                    text-color="red"
                    @click="deleteReason(props.row)"
                  />
                </q-td>
              </q-tr>
            </template>
          </q-table>
        </q-card-section>

        <q-card-section class="q-pb-xs">
          <q-select
            v-model="dataModel.goal"
            ref="inputGoal"
            filled
            multiple
            use-chips
            :options="goalsListFilter"
            :label="$t('label.goal')"
            :rules="[rulesGoal]"
          />
        </q-card-section>

        <q-card-actions align="right">
          <q-btn
            @click="handleSubmit"
            :label="formBtnSubmit"
            unelevated
            color="primary"
          />

          <q-btn
            @click="dialogOpen = false"
            :label="$t('base.close')"
            color="white"
            text-color="primary"
            outline
          />
        </q-card-actions>
      </form>
    </q-card>
  </q-dialog>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import cloneDeep from 'lodash/cloneDeep';
import { v4 } from 'uuid';
import { TranslateResult } from 'vue-i18n';

import { notifyError } from '@utils/notify';
import { BaseCardCommon } from '@/interfaces';
import { generate } from '@/utils/base/idGenerator';

type Goal = {
  value: string;
  label: string;
};

export type Suspense = {
  uuid: string;
  numberTerm: number;
  inCalendarDays: boolean;
  causeList: Record<string, string>[];
  goal: Goal['value'][];
};

type Data = 'createMode' | Suspense | null;

@Component({})
export default class SuspenseDialog extends Vue {
  @Prop() common?: BaseCardCommon;

  dialogOpen = false;
  dataModel: Suspense | null = null;
  cause = '';
  reasonEditFlag = false;
  reasonEditId = '';
  reasonEditSelected = false;
  causeTableColumns = [
    {
      name: 'reason',
      label: 'Причина',
      field: 'reason',
      align: 'left',
    },
    {
      name: 'actions',
      label: 'Действия',
      align: 'right',
    },
  ];

  get formTitle() {
    return this.dataModel?.uuid
      ? this.$t('title.edit')
      : this.$t('title.create');
  }

  get formBtnSubmit() {
    return this.dataModel?.uuid ? this.$t('base.save') : this.$t('base.create');
  }

  get card() {
    return this.$store.getters['registryService/services/servicesCard'];
  }

  get extendDueDate(): Suspense[] {
    return this.card?.extendDueDate || [];
  }

  get goalsListByExtendDueDate() {
    return this.extendDueDate.reduce<Goal['value'][]>((result, suspense) => {
      if (suspense.uuid === this.dataModel?.uuid) return result;

      result = [...result, ...suspense.goal];

      return result;
    }, []);
  }

  get goalsList(): Goal[] {
    return this.card?.goalsList || [];
  }

  get goalsListFilter(): Goal['value'][] {
    if (!this.goalsList.length) {
      return this.dataModel?.goal || [];
    }

    return this.goalsList
      .filter((v) => !this.goalsListByExtendDueDate.includes(v.value))
      .map((v) => v.value);
  }

  @Watch('common.models.SuspenseDialog.data', { immediate: true })
  dataHandler(data?: Data) {
    if (!data) return;
    if (data === 'createMode') {
      this.dataModel = {
        uuid: '',
        inCalendarDays: false,
        numberTerm: 1,
        causeList: [],
        goal: [],
      };
    } else {
      this.dataModel = data;
      if (!this.dataModel.hasOwnProperty('inCalendarDays')) {
        this.dataModel.inCalendarDays = false;
      }
      if (!this.dataModel.hasOwnProperty('causeList')) {
        this.dataModel.causeList = [];
      }
    }

    this.dialogOpen = true;
  }

  destroyed() {
    this.clearModel();
  }

  clearModel() {
    this.dataModel = null;

    this.$emit('commonModels', {
      SuspenseDialog: { data: null },
    });
  }

  rulesNumberTerm(value: number): boolean | TranslateResult {
    return value > 0 || this.$t('rules.error.numberTerm');
  }

  rulesCause(value: string): boolean | TranslateResult {
    const text = String(value || '').trim();

    if (text.length > 2000) return this.$t('rules.error.causeMax');
    if (!text.length) return this.$t('rules.error.causeMin');

    return true;
  }

  rulesGoal(value?: Goal[]): boolean | TranslateResult {
    return !!value?.length || this.$t('rules.error.goal');
  }

  handleSubmit() {
    type Input = Vue & { validate: () => void; hasError: boolean };
    const { inputNumberTerm, inputCause, inputGoal } = this.$refs as {
      [key: string]: Input;
    };

    const errors = [inputNumberTerm, inputCause, inputGoal].filter((input) => {
      input.validate();
      return input.hasError;
    });

    if (errors.length) {
      notifyError(this.$t('validation.basic.formErrors') as string);
      return;
    }

    const card = cloneDeep(this.card);
    const extendDueDate: Suspense[] = card.extendDueDate || [];
    const suspense = this.dataModel as Suspense;

    if (!suspense.uuid) {
      extendDueDate.push({ ...suspense, uuid: v4() });
    } else {
      const findIndex = extendDueDate.findIndex(
        (s) => s.uuid === suspense.uuid
      );

      if (findIndex > -1) {
        extendDueDate[findIndex] = suspense;
      }
    }

    card.extendDueDate = extendDueDate.map((v) => ({
      ...v,
      goal: v.goal.map((v) => {
        const number = parseInt(v);

        if (Number.isNaN(number)) return v;
        return number;
      }),
    }));

    this.$store.dispatch('registryService/services/setCardForJson', card);
    this.dialogOpen = false;
  }

  createCause(val: string): void {
    if (val.length > 0) {
      if (this.reasonEditFlag) {
        if (this.dataModel) {
          // eslint-disable-next-line array-callback-return
          this.dataModel?.causeList.map(element => {
            if (element.id === this.reasonEditId) {
              element.reason = val;
            }
          });
        }
        this.cause = '';
        this.reasonEditFlag = false;
        this.reasonEditId = '';
        return;
      }
      let flag = true;
      this.dataModel?.causeList.forEach((item) => {
        if (item.reason === val) {
          flag = false;
        }
      });

      if (flag) {
        console.log('новая причина')
        const value = {
          id: generate(),
          reason: val,
        };
        // eslint-disable-next-line no-prototype-builtins
        if (this.dataModel) {
          console.log('добавляем')
          this.dataModel?.causeList.push(value);
        }
        this.cause = '';
      }
    }
  }

  /**
   * Удаление причины приостановки из списка
   * @param scope {object} - полный объект причины из селекта
   */
  deleteReason(scope: Record<string, string>): void {
    if (this.dataModel) {
      this.dataModel.causeList = this.dataModel?.causeList.filter(
        (e) => e.id !== scope.id
      );
    }
  }

  /**
   * Редактирование причины
   * @param scope {object} - полный объект причины из селекта
   */
  editReason(scope: Record<string, string>): void {
    this.cause = scope.reason;
    this.reasonEditFlag = true;
    this.reasonEditId = scope.id;
  }
}
</script>

<style lang="scss">
.SelectItemSection {
  display: flex;
  justify-content: space-between;
  flex-direction: row;
  align-items: center;
  flex-wrap: nowrap;
  border-bottom: 1px solid rgba(0, 0, 0, 0.5);
}
.SelectItem {
  flex-basis: 80%;
  height: 100%;
  display: flex;
  align-items: center;
  padding: 0 10px;
  cursor: pointer;
}
.SelectLabelFocused {
  background-color: rgba(0, 0, 0, 0.05);
}
</style>
