<template>
  <!--  Add-->
  <transition mode="out-in">
    <UiPopup
      v-if="isPlaylistAdd"
      v-model="isPlaylistAdd"
      :back="!!onBack"
      class="playlist-add"
      sheet
      transparent-backdrop
      @back="handleBack"
      @close="closePopup"
    >
      <template #title>{{ $t('playlist.add') }}</template>

      <template #fixedContent>
        <CardVideoMini
          v-if="videoCard"
          :card="videoCard"
          class="playlist-add__mini-card"
        />
      </template>
      <div
        :class="{'_loading': loadingUserPlaylists || loadingPostVideo}"
        class="playlist-add__wrapper"
      >
        <template v-if="playlistsItems && playlistsItems.length">
          <template
            v-for="(item, index) in playlistsItems"
            :key="`playlist-${index}`"
          >
            <UiCheckbox
              :model-value="selectValue.includes(item.value)"
              class="playlist-add__item"
              right
              @update:model-value="togglePlaylist(item.value)"
            >
              <div class="playlist-add__item-wrapper">
                <UiIcon
                  class="playlist-add__item-icon"
                  name="playlist"
                  size="20"
                />
                <span class="playlist-add__item-text">{{ item.title }}</span>
                <UiIcon
                  :name="item.typeIcon"
                  class="playlist-add__item-icon"
                  size="14"
                />
                <span class="playlist-add__item-icon">
                  <UiIcon
                    name="video-camera"
                    size="14"
                  />
                  {{ item.videosCount }}
                </span>
              </div>
              <button
                class="playlist-add__item-edit"
                type="button"
                @click.prevent="openEdit(item.card)"
              >
                <UiIcon
                  name="pen"
                  size="16"
                />
              </button>
            </UiCheckbox>
          </template>
        </template>
        <button
          v-if="step !== 'new'"
          type="button"
          class="playlist-add__item --new"
          @click="step = 'new'"
        >
          <UiIcon
            class="playlist-add__item-icon --new"
            name="plus"
            size="20"
          />
          {{ $t('playlist.new_playlist') }}
        </button>
        <PlaylistInput
          v-else
          v-model="newPlaylistName"
          v-model:type="playlistType"
          :error="nameError"
          :placeholder="$t('playlist_name')"
          @update:error="nameError = $event"
          @close="clearNewPlaylist"
          @submit="onSaveClick"
        />
      </div>

      <template #footer>
        <div class="playlist-add__buttons">
          <UiBtn
            wide
            :disabled="loadingUserPlaylists || loadingPostVideo"
            size="l"
            theme="muted"
            @click="closePopup"
          >{{ $t('cancel') }}
          </UiBtn>
          <UiBtn
            wide
            :disabled="submitDisabled"
            size="l"
            theme="primary"
            @click="onSaveClick"
          >{{ $t('add') }}
          </UiBtn>
        </div>
      </template>
    </UiPopup>
  </transition>
  <!--  Add-->

</template>

<script setup lang="ts">
import type { IPlaylistVideoFormType, IPlaylistShort, IPlaylistCard, PaginatedResponse } from '../../types';
import { PLAYLIST_TYPE_ICON, PlaylistStep, PlaylistType } from '../../runtime';

const props = defineProps<{
  loadingPostPlaylist: boolean
  loadingUserPlaylists: boolean
  loadingPostVideo: boolean
  userPlaylists: PaginatedResponse<IPlaylistCard> | null
}>();

const emit = defineEmits<{
  (eventName: 'execute-user-playlists'): void
  (eventName: 'save-video-to-playlist', eventValue: {
    form: IPlaylistVideoFormType
    id: string
    newPlaylist?: IPlaylistShort
  }): void
}>();

const { videoCard, closePlaylistAdd, isPlaylistAdd, selectValue, step, onBack } = usePlaylistAdd();
const { openPlaylistEdit, onBack: onEditBack } = usePlaylistEdit();

/**
 * Редактирование открывается вместо добавления, не поверх. Карточку видео не сбрасываем —
 * из редактирования по «назад» возвращаемся сюда же.
 */
function openEdit(card: IPlaylistCard) {
  onEditBack.value = () => {
    isPlaylistAdd.value = true;
  };
  isPlaylistAdd.value = false;
  openPlaylistEdit(PlaylistStep.Edit, false, card);
}

function handleBack() {
  const callback = onBack.value;
  closePopup();
  callback?.();
}

const playlistsItems = computed(() => {
  return props.userPlaylists?.items
    ?.map((item: IPlaylistCard) => ({
      title: item.name,
      value: item.id,
      videosCount: item.videosCount,
      typeIcon: PLAYLIST_TYPE_ICON[item.playlistType] ?? PLAYLIST_TYPE_ICON[PlaylistType.Public],
      card: item,
    }));
});


function togglePlaylist(value: string) {
  const idx = selectValue.value.indexOf(value);
  if (idx === -1) {
    selectValue.value.push(value);
  } else {
    selectValue.value.splice(idx, 1);
  }
}

watch(isPlaylistAdd, (val) => {
  if (val) {
    selectValue.value = [];
    emit('execute-user-playlists');
  }
}, { immediate: true });

async function closePopup() {
  step.value = 'add';
  selectValue.value = [];
  newPlaylistName.value = '';
  playlistType.value = PlaylistType.Public;
  isPlaylistAdd.value = false;
  closePlaylistAdd();
}

const newPlaylistName = ref('');
const playlistType = ref<PlaylistType>(PlaylistType.Public);
const nameError = ref(false);

function clearNewPlaylist() {
  newPlaylistName.value = '';
  playlistType.value = PlaylistType.Public;
  step.value = 'add';
}

const submitDisabled = computed(() => {
  if (props.loadingUserPlaylists || props.loadingPostVideo) return true;
  if (step.value === 'new') return !newPlaylistName.value.trim();
  return !selectValue.value.length;
});

const postVideoForm = computed(() => ({
  playlistId: selectValue.value.length ? selectValue.value : undefined,
  videoId: videoCard.value?.id ?? '',
  VideoGUID: videoCard.value?.guid ?? '',
  videoMd5: videoCard.value?.md5 ?? '',
  thumbNum: videoCard.value?.thumbNum ?? 0,
  name: videoCard.value?.title ?? '',
  duration: videoCard.value?.duration ?? 0,
}));

const { setErrorState, show, showError } = useSnackbar();
const { generateLink } = useGenerateLink();
const { t } = useI18n();

/**
 * Куда добавили: при одном плейлисте — его имя и ссылка на него же, при нескольких —
 * количество и ссылка на список. У нового плейлиста id появляется только после ответа
 * бэка, поэтому для него тоже ссылка на список.
 */
function getTarget(newPlaylistName?: string) {
  const selected = props.userPlaylists?.items
    ?.filter((item: IPlaylistCard) => selectValue.value.includes(item.id)) ?? [];
  const total = selected.length + (newPlaylistName ? 1 : 0);
  const single = total === 1 ? selected[0] : undefined;

  if (single) {
    // Пустому плейлисту первым видео становится только что добавленное.
    const firstVideoId = single.firstVideoId ?? videoCard.value?.id;

    return {
      label: single.name,
      link: generateLink(`/playlists/${single.id}/${firstVideoId}`),
    };
  }

  return {
    label: total === 1 ? newPlaylistName! : t('plural.playlists', total),
    link: generateLink('/playlists'),
  };
}

async function onSaveClick() {
  let newPlaylist: IPlaylistShort | undefined;

  if (step.value === 'new') {
    const name = newPlaylistName.value.trim();
    if (!name) return;

    const nameExists = props.userPlaylists?.items?.some(
      (item: IPlaylistCard) => item.name.toLowerCase() === name.toLowerCase()
    );

    if (nameExists) {
      nameError.value = true;
      showError('playlist_name_exists');
      return;
    }

    newPlaylist = {
      name,
      type: playlistType.value,
    };
  }

  const target = getTarget(newPlaylist?.name);

  try {
    emit('save-video-to-playlist', {
      form: postVideoForm.value as IPlaylistVideoFormType,
      id: String(selectValue.value),
      newPlaylist,
    });
    closePopup();
    show('added_to', {
      icon: 'playlist',
      highlight: target.label,
      actionText: 'see_list',
      onAction: () => navigateTo(target.link),
    });
  } catch (error) {
    setErrorState(error);
    console.log(error, 'error add video to playlist');
  }
}
</script>

<style lang="scss">
.playlist-add.ui-popup {
  @include from-br(sm) {
    --popup-min-width: 574px;
  }
}

/* Ширина фиксирована: длинное название плейлиста обрезается, а не растягивает модалку. */
.playlist-add .ui-popup__wrapper {
  @include from-br(sm) {
    width: var(--popup-min-width);
  }
}

.playlist-add .ui-popup__back {
  @include from-br(sm) {
    display: none;
  }
}

.playlist-add .ui-popup__content {
  padding: 0;
}

.playlist-add .ui-popup__footer {
  padding-inline: 24px;
}

/* minmax(0, 1fr), а не дефолтный auto-трек: иначе трек растёт до max-content и длинное
   название плейлиста делает строку шире модалки вместо обрезки. */
.playlist-add__wrapper {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.playlist-add__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  column-gap: 12px;
  padding: 16px 24px;

  @include hover(background-color) {
    background-color: $playlist-add-item-bg--hover;
  }
}

/* Два класса не случайно: `.ui-checkbox` едет отдельным CSS-чанком и с одним классом
   перебивает display по порядку загрузки. */
.playlist-add .playlist-add__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  column-gap: 12px;
}

.playlist-add__item:not(:last-child) {
  border-bottom: 1px solid $playlist-add-item-border;
}

.playlist-add__item-wrapper {
  display: flex;
  align-items: center;
  justify-content: start;
  column-gap: 12px;
  min-width: 0;
}

.ui-checkbox__label .playlist-add__item-wrapper {
  @include font-base;

  font-weight: 500;
}

.playlist-add .ui-checkbox__label {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  min-width: 0;
}

.playlist-add__item:last-child {
  justify-content: start;
}

.playlist-add__buttons {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 12px;
}

.playlist-add__item-icon {
  @include font-xs;

  color: $playlist-add-item-icon;
  display: flex;
  align-items: center;
  column-gap: 4px;
}

.playlist-add__item-icon:first-child {
  color: $playlist-add-item-icon-first;
}

.playlist-add__item-icon.--new {
  color: inherit;
}

.playlist-add__item-text {
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  min-width: 0;
  color: $playlist-add-item-text;
}

.playlist-add__item.--new {
  @include font-base;

  color: $playlist-add-item-new;
  font-weight: 500;
}

.playlist-add__item-edit {
  position: relative;
  color: $playlist-add-item-edit;
  flex-shrink: 0;
  margin-left: auto;
  padding: 8px;

  @include hover(color) {
    color: $playlist-add-item-edit--hover;
  }
}
</style>
