<template>
  <ui-card
    v-on="$listeners"
    v-bind="$attrs"
    class="ui-list-card"
    :class="{ 'ui-list-card_disabled': disabled }"
  >
    <template #title>
      <list-card-header
        @edit="edit"
        @remove="remove"
        :title="cardTitle"
        :title-edit="cardTitleEdit"
        :is-edit-mode="isEditMode"
      >
        <slot name="title" />
      </list-card-header>
    </template>
    <list-card-title-input
      v-if="isEditMode"
      v-model="model.title"
      :label="cardTitleLabel"
    />
    <slot name="beforeItems" />
    <list-card-items
      :title="listTitle"
      :items="model.items"
      :item-text="listItemText"
      :item-placeholder="listItemPlaceholder"
      :is-edit-mode="isEditMode"
    >
      <template v-if="isEditMode" #item-popup="{item}">
        <slot name="item-popup" :item="item" />
      </template>
      <template v-if="isEditMode" #new-item-popup>
        <slot name="new-item-popup" :items="model.items" />
      </template>
    </list-card-items>
    <slot name="afterItems" />
    <template v-if="isEditMode" #footer>
      <div class="flex ui-gap-x-sm">
        <ui-btn @click="save" label="Сохранить" :loading="isSaving" />
        <ui-btn-cancel @click="cancel" />
      </div>
    </template>
  </ui-card>
</template>

<script lang="ts">
import { Component, Emit, Prop, Vue, Watch } from 'vue-property-decorator'
import { nanoid } from 'nanoid'
import UiCard from '../UiCard.vue'
import UiBtn from '../buttons/UiBtn.vue'
import UiBtnCancel from '../buttons/UiBtnCancel.vue'
import ListCardHeader from './list-card/ListCardHeader.vue'
import ListCardItems from './list-card/ListCardItems.vue'
import ListCardTitleInput from './list-card/ListCardTitleInput.vue'
import ListCardSavePayload from '../../types/ListCardSavePayload'

@Component({
  inheritAttrs: false,
  components: {
    ListCardTitleInput,
    ListCardItems,
    ListCardHeader,
    UiBtnCancel,
    UiBtn,
    UiCard,
  },
})
export default class UiListCard<ItemType> extends Vue {
  @Prop({ type: String, required: true })
  cardTitle!: string

  @Prop({ type: String })
  cardTitleEdit!: string

  @Prop({ type: String })
  cardTitleLabel!: string

  @Prop({ type: String, required: true })
  listTitle!: string

  @Prop({ type: Array, required: true })
  listItems!: ItemType[]

  @Prop({ type: Function, required: true })
  listItemText!: (item: ItemType) => string

  @Prop({ type: String })
  listItemPlaceholder!: string

  @Prop({ type: Boolean })
  isEditMode!: boolean

  @Prop({ type: Boolean })
  isSaving!: boolean

  @Prop({ type: Boolean })
  disabled!: boolean

  model: ListCardSavePayload<ItemType> = {
    title: '',
    items: [],
  }

  @Emit()
  save() {
    return {
      ...this.model,
      items: this.model.items.map(item => {
        const clearedItem = { ...item } as ItemType & { _id: string }

        delete clearedItem._id

        return clearedItem
      }),
    }
  }

  @Emit()
  cancel() {
    this.updateModelTitle()
    this.updateModelItems()

    return true
  }

  @Emit()
  edit() {
    return true
  }

  @Emit()
  remove() {
    return true
  }

  @Watch('cardTitle', { immediate: true })
  updateModelTitle() {
    this.model.title = this.cardTitle
  }

  @Watch('listItems', { immediate: true })
  updateModelItems() {
    this.model.items = this.listItems.map(item => ({
      ...item,
      _id: nanoid(),
    }))
  }
}
</script>
