<template>
  <div
    ref="root"
    :class="rootClasses"
    class="wt-vidstack-player"
  >
    <media-player
      ref="player"
      :autoplay="props.autoplay"
      :muted="props.muted"
      :src="normalizedSrcObject"
      class="wt-vidstack-player__player"
      cross-origin
      playsinline
      @close="emit('close')"
      @can-play="onCanPlay"
    >
      <media-provider class="wt-vidstack-player__provider"></media-provider>

      <video-layout
        :autoplay="props.autoplay"
        :closable="props.closable"
        :hide-controls-panel="props.hideControlsPanel"
        :hide-expand="props.hideExpand"
        :hide-video-display-panel="props.hideVideoDisplayPanel"
        :title="props.title"
        :username="props.username"
        :countdown-time-mode="props.countdownTimeMode"
        @close-player="emit('close')"
      >
        <template v-if="$slots['avatar']" #avatar>
          <slot name="avatar" />
        </template>

        <template #controls-panel>
          <slot :size="size" name="controls-panel" />
        </template>

        <template #content>
          <slot :size="size" name="content" />
        </template>
      </video-layout>

    </media-player>
  </div>
</template>

<script lang="ts" setup>
import 'vidstack/player';
import 'vidstack/player/ui';
import type { MediaSrc } from 'vidstack';
import { computed, provide, ref, toRefs, useTemplateRef } from 'vue';

import { ComponentSize } from '../../enums';
import { VideoLayout } from './components';
import { useVidstackSrc } from './composables/useVidstackSrc';

interface Props {
	src?: MediaSrc;
	mime?: string;
	autoplay?: boolean;
	muted?: boolean;
	title?: string;
	username?: string;
	closable?: boolean;
	countdownTimeMode?: boolean;
	static?: boolean;
	stream?: MediaStream;
	size?: ComponentSize;
	hideVideoDisplayPanel?: boolean;
	hideControlsPanel?: boolean;
	hideBackground?: boolean;
	hideExpand?: boolean;
	stretch?: boolean;
	videoObjectFit?: 'cover' | 'contain';
	mirrorVideo?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
	mime: 'video/mp4',
	autoplay: false,
	muted: true,
	title: '',
	username: '',
	closable: false,
	countdownTimeMode: false,
	static: false,
	hideControlsPanel: false,
	videoObjectFit: 'contain',
});

const emit = defineEmits<{
	close: [];
	'change-size': [
		ComponentSize,
	];
}>();

// const player = useTemplateRef<MediaPlayerElement>('player');
const rootEl = useTemplateRef<HTMLElement>('root');
const size = ref(props.size || ComponentSize.SM);
const fullscreen = ref(false);

const changeSize = (value) => {
	size.value = value;
	emit('change-size', value);
};

const enterFullscreen = () => {
	rootEl.value?.requestFullscreen();
};

/** @author liza-pohranichna
 * options: [sm, md, lg]
 */
provide('size', {
	size,
	fullscreen,
	changeSize,
	enterFullscreen,
});

const { src: srcRef, mime: typeRef, stream: streamRef } = toRefs(props);

const { normalizedSrcObject } = useVidstackSrc({
	src: srcRef,
	type: typeRef,
	stream: streamRef,
});

const rootClasses = computed(() => [
	`wt-vidstack-player--${size.value}`,
	`wt-vidstack-player-video-object-fit--${props.videoObjectFit}`,
	props.mirrorVideo && 'wt-vidstack-player--mirror-video',
	fullscreen.value && 'wt-vidstack-player--fullscreen',
	props.stretch && 'wt-vidstack-player--stretch',
	props.static && 'wt-vidstack-player--static',
	props.hideBackground && 'wt-vidstack-player--hide-background',
]);

const onCanPlay = (ev: Event) => {
	if (!props.autoplay) return;

	(ev.target as HTMLMediaElement)?.play();
};
</script>

<style scoped>
.wt-vidstack-player {
  /*
    Shortened size tokens for player sizes border-radius:
    --video-border-radius-* = size-specific radius values for video tag
    --video-border-radius = final computed radius used by component
  */
  --video-border-radius-sm: var(--p-player-control-bar-sm-border-radius);
  --video-border-radius-md: var(--p-player-control-bar-md-border-radius);
  --video-border-radius-lg: var(--p-player-control-bar-lg-border-radius);
  --video-border-radius-br: 0;

  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  transition: var(--transition);
  box-shadow: var(--elevation-10);
}

.wt-vidstack-player__player {
  position: relative;
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  transform: translateZ(0);
  overflow: hidden;
}

.wt-vidstack-player__provider {
  display: block;
  height: 100%;
  background: var(--p-player-wrapper-background);
  border-radius: var(--video-border-radius);
}

.wt-vidstack-player--sm {
  --video-border-radius: var(--video-border-radius-sm);

  position: fixed;
  z-index: 10;
  right: var(--spacing-md);
  bottom: var(--spacing-md);
  overflow: hidden;
  max-width: var(--p-player-wrapper-sm-width);
  height: var(--p-player-wrapper-sm-height);
  max-height: var(--p-player-wrapper-sm-height);
  border-radius: var(--p-player-wrapper-sm-border-radius);
}

.wt-vidstack-player--sm .wt-vidstack-player__provider {
  padding-bottom: var(--p-player-control-bar-sm-height);
}
.wt-vidstack-player--sm .wt-vidstack-player__player {
  height: 100%;
}

.wt-vidstack-player--md {
  --video-border-radius: var(--video-border-radius-md);

  overflow: hidden;
  flex: 0 0 auto;
  max-width: 100%;
  max-height: 100%;
  border-radius: var(--p-player-wrapper-md-border-radius);
}

.wt-vidstack-player--md.wt-vidstack-player--static {
  max-width: var(--p-player-wrapper-md-width);
  max-height: var(--p-player-wrapper-md-height);
}

.wt-vidstack-player--md .wt-vidstack-player__player {
  overflow: hidden;
  width: 100%;
  max-width: var(--p-player-wrapper-md-width);
  height: 100%;
  max-height: var(--p-player-wrapper-md-height);
  border-radius: var(--p-player-wrapper-md-border-radius);
}

/* @author liza-pohranichna
 * need to use wt-popup styles for md size https://webitel.atlassian.net/browse/WTEL-7723
 * Note: popup-wrapper and popup-container mixins removed - apply popup styles separately if needed
 */
.wt-vidstack-player--md:not(.wt-vidstack-player--static) {
  display: flex;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  justify-content: center;
  align-items: center;
  z-index: var(--popup-wrapper-z-index);
  background: var(--wt-popup-shadow-color);
  border-radius: 0;
  overflow: visible;
}

.wt-vidstack-player--md:not(.wt-vidstack-player--static) .wt-vidstack-player__player {
  flex-direction: column;
  gap: var(--popup-sections-gap);
  z-index: 1;
  box-shadow: var(--elevation-10);
  background: var(--wt-popup-background-color);
  position: relative;
  display: block;
  padding: 0;
  margin: 0;
  max-height: var(--p-player-wrapper-md-height);
  border-radius: var(--p-player-wrapper-md-border-radius);
  overflow: hidden;
}

.wt-vidstack-player--lg {
  --video-border-radius: var(--video-border-radius-lg);

  z-index: 10;
  overflow: hidden;
  border-radius: var(--p-player-wrapper-lg-border-radius);
}

.wt-vidstack-player--lg .wt-vidstack-player__player {
  display: flex;
  align-items: center;
  min-height: 100%;
}

.wt-vidstack-player--lg .wt-vidstack-player__provider {
  width: 100%;
  min-width: 0;
}

.wt-vidstack-player--fullscreen {
  border-radius: 0;
}

.wt-vidstack-player--fullscreen .wt-vidstack-player__provider :deep(video) {
  border-radius: 0;
}

.wt-vidstack-player--static {
  position: relative;
  z-index: 1;
  right: unset;
  bottom: unset;
  flex: 0 0 auto;
}

.wt-vidstack-player--static .wt-vidstack-player__player {
  width: 100%;
  height: 100%;
  margin: 0;
}

.wt-vidstack-player--stretch {
  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
}

.wt-vidstack-player--static .wt-vidstack-player__provider,
.wt-vidstack-player--stretch .wt-vidstack-player__provider {
  padding: 0;
}

.wt-vidstack-player--hide-background.wt-vidstack-player--md {
  z-index: calc(var(--p-galleria-mask-z-index) - 1);
  pointer-events: none;
  background: none;
}

.wt-vidstack-player--hide-background .wt-vidstack-player__player {
  pointer-events: all;
}

.wt-vidstack-player :deep(video) {
  width: 100%;
  min-width: 0;
  height: 100%;
  border-radius: var(--video-border-radius);
}

.wt-vidstack-player-video-object-fit--cover :deep(video) {
  object-fit: cover;
}

.wt-vidstack-player-video-object-fit--contain :deep(video) {
  object-fit: contain;
}

.wt-vidstack-player--mirror-video :deep(video) {
  transform: scaleX(-1);
}

/*
 * @author Oleksandr Palonnyi
 * WTEL-9094: https://webitel.atlassian.net/browse/WTEL-9094
 * Comment: https://webitel.atlassian.net/browse/WTEL-8974?focusedCommentId=735933
 */
.wt-vidstack-player :deep(.controls-group) {
  margin-bottom: -1px;
}
</style>
