<!-- Лайк/дизлайк с числами и прогрессбаром реакций -->
<template>
  <div
    :class="{'--mini': mini}"
    class="player-like"
  >
    <button
      :class="{'--active': isLiked}"
      :aria-pressed="isLiked"
      :title="t('like')"
      class="player-like__control"
      type="button"
      @click="onReactionClick('like')"
    >
      <UiIcon
        :name="isLiked ? 'thumbs-up-filled' : 'thumbs-up'"
        class="player-like__control-icon"
        size="24"
      />
      <span class="player-like__count">{{ $n(Number(resultLikes), 'compact') }}</span>
    </button>
    <div
      v-if="bar"
      class="player-like__bar"
    >
      <div
        :style="{ width: likePercent + '%' }"
        class="player-like__bar-likes"
      />
    </div>
    <button
      :class="{'--active': isDisliked}"
      :aria-pressed="isDisliked"
      :title="t('dislike')"
      class="player-like__control"
      type="button"
      @click="onReactionClick('dislike')"
    >
      <UiIcon
        :name="isDisliked ? 'thumbs-down-filled' : 'thumbs-down'"
        class="player-like__control-icon"
        size="24"
      />
      <span class="player-like__count">{{ $n(Math.abs(Number(resultDislikes)), 'compact') }}</span>
    </button>
  </div>
</template>

<script setup lang="ts">
import { VideosApiService } from '../../services/api/videos.service';
import { PlaylistsApiService } from '../../services/api/playlists.service';
import { applyReaction } from '../../utils/player-like/apply-reaction';
import { getReactionPercents } from '../../utils/player-like/get-reaction-percents';

const { t } = useI18n();

const props = defineProps<{
  id?: string
  mini?: boolean
  likes: number
  dislikes: number
  bar?: boolean
  videoMd5?: string
}>();

const { execute: executeVideoLike } = useApiAction(VideosApiService.videoLike);
const { execute: executeVideoDislike } = useApiAction(VideosApiService.videoDislike);
const { execute: executePlaylistLike } = useApiAction(PlaylistsApiService.playlistLike);
const { execute: executePlaylistDislike } = useApiAction(PlaylistsApiService.playlistDislike);

const storageKey = computed(() => props.videoMd5 || props.id || '');

const likeStatus = ref<'like' | 'dislike' | null>(null);
const isLiked = computed(() => likeStatus.value === 'like');
const isDisliked = computed(() => likeStatus.value === 'dislike');
const resultLikes = ref(props.likes);
const resultDislikes = ref(props.dislikes);

function syncFromProps() {
  likeStatus.value = null;
  resultLikes.value = props.likes;
  resultDislikes.value = props.dislikes;

  const stored = localStorage.getItem(storageKey.value);
  if (stored === 'like' || stored === 'dislike') {
    likeStatus.value = stored;
    if (stored === 'like') resultLikes.value += 1;
    if (stored === 'dislike') resultDislikes.value += 1;
  }
}

onMounted(syncFromProps);

watch(storageKey, syncFromProps);

async function onReactionClick(type: 'like' | 'dislike') {
  if (likeStatus.value !== type) {
    likeStatus.value = type;
    localStorage.setItem(storageKey.value, type);

    const isLike = type === 'like';

    const next = applyReaction(type, resultLikes.value, resultDislikes.value);
    resultLikes.value = next.likes;
    resultDislikes.value = next.dislikes;

    if (props.videoMd5) {
      if (isLike) {
        await executeVideoLike([props.videoMd5]);
      } else {
        await executeVideoDislike([props.videoMd5]);
      }
    } else {
      if (isLike) {
        await executePlaylistLike([props.id!]);
      } else {
        await executePlaylistDislike([props.id!]);
      }
    }
  }
}

const likePercent = computed(() => getReactionPercents(resultLikes.value, resultDislikes.value).likePercent);
</script>

<style lang="scss">
.player-like {
  display: flex;
  column-gap: 6px;
  align-items: center;
}

.player-like.--mini {
  column-gap: 4px;
}

/* На мобиле контрол — вертикальная ячейка «иконка над числом», как в остальном мобильном
   ряду действий; от sm возвращается в строку с числом сбоку. */
.player-like__control {
  display: flex;
  flex-direction: column;
  align-items: center;
  row-gap: 6px;
  padding-block: 4px;
  color: $like-mobile-icon;
  cursor: pointer;
  transition: var(--transition) color, var(--transition) opacity;

  @include from-br(sm) {
    flex-direction: row;
    row-gap: 0;
    column-gap: 6px;
    padding: 6px;
    border-radius: $radius-small;
    color: $like-icon;
  }

  @include hover(color, opacity) {
    color: $like-icon--hover;
  }
}

.player-like__control:active {
  opacity: 0.7;
}

.player-like__control.--active {
  color: $like-icon--active;
}

.player-like.--mini .player-like__control {
  flex-direction: row;
  column-gap: 4px;
  padding: 0;

  /* Только до sm: от sm цвет и так берётся из базового правила, а трёхклассовый
     селектор перебивал бы им ховер. */
  @include to-br(sm) {
    color: $like-icon;
  }
}

.player-like__control-icon {
  @include from-br(sm) {
    $size: 16px;

    width: $size;
    height: $size;
  }
}

.--mini .player-like__control-icon {
  $size: 14px;

  width: $size;
  height: $size;
}

.player-like__count {
  @include font-xs;

  color: $like-mobile-count;

  @include from-br(sm) {
    color: $like-count;
  }
}

.--mini .player-like__count {
  color: $like-count;
}

.player-like__bar {
  display: none;
  width: 64px;
  height: 6px;
  margin-inline: 4px;
  border-radius: $radius-full;
  overflow: hidden;
  background-color: $like-bar-bg;

  @include from-br(sm) {
    display: flex;
    width: 48px;
    height: 4px;
  }
}

.--mini .player-like__bar {
  display: flex;
  width: 36px;
}

.player-like__bar-likes {
  background-color: $like-bar-likes;
  border-radius: $radius-full;
}
</style>
