<template>
	<transition appear name="fade">
		<div class="modal p-8 overflow-auto items-center" @click.self="close">
			<transition name="slide">
				<div v-if="movie !== undefined" class="relative w-full max-w-6xl bg-white overflow-hidden rounded-xl flex-col flex-shrink-0 shadow-xl">
					<div class="bg-center bg-cover" :class="{ 'text-white': isDark }"
						:style="movie.backdrop_path ? `background: url('/api/tmdb/image/w1280${movie.backdrop_path}')` : ''">
						<div class="movie-modal-content z-10" :style="backdropOverlayStyle">
							<div class="flex p-4">
								<div class="w-24 h-40 flex-shrink-0 md:h-auto md:w-72 rounded-lg md:rounded-xl overflow-hidden shadow-md mdshadow-xl">
									<i v-if="!movie.poster_path" class="fas fa-image mx-auto my-auto"></i>
									<img v-else class="w-full h-full object-cover" ref="poster"
										:src="`/api/tmdb/image/w342${movie.poster_path}`" @load="onPosterLoad">
								</div>
								<div class="p-4 flex flex-col justify-center">
									<h2 class="text-lg md:text-4xl">
										<span class="font-bold">{{ movie.title }}</span>
										<span class="opacity-70" v-if="releaseYear"> ({{ releaseYear }})</span>
									</h2>
									<div class="flex font-light dot-separated">
										<span v-if="releaseDate">{{ releaseDate }}</span>
										<span v-if="runtime">{{ runtime }}</span>
									</div>
									<div v-if="movie?.overview" class="mt-4 hidden md:block">
										<p class="">{{movie?.overview}}</p>
									</div>
									<div class="mt-4 hidden md:block">
										<button class="py-2 px-8 rounded-full shadow-md hover:shadow-lg focus:outline-none ring-0 transition-transform transform hover:scale-105" :class="{ 'bg-white text-black': isDark, 'bg-black text-white': !isDark }">Request</button>
									</div>
								</div>
							</div>
						</div>
					</div>
					<div class="p-4 space-y-4 md:hidden z-20" style="box-shadow: 0px -10px 10px rgba(0, 0, 0, 0.10);" >
						<div v-if="movie?.overview">
							<h3 class="font-bold mb-2">Overview</h3>
							<p>{{ movie?.overview }}</p>
						</div>
						<div class="text-center">
							<button class="py-2 px-8 rounded-full bg-red-500 text-white">Request</button>
						</div>
					</div>
				</div>
			</transition>
		</div>
	</transition>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { IApiDataResponse } from "@common/api_schema";
import { IMovieDetails } from "@lib/tmdb/schema";
import { authFetch } from "../../routes";
import { getAverageRgb } from "../../util";
import { useStore, Mutation } from "../../store";

type movie = IApiDataResponse<IMovieDetails>;

export default defineComponent({
	computed: {
		backdropOverlayStyle(): string {
			let { r, g, b } = this.rgb;
			return `background-image: linear-gradient(to right, rgba(${r}, ${g}, ${b}, 1.0), rgba(${r}, ${g}, ${b}, 0.84)`;
		},
		isDark(): boolean {
			let { r, g, b } = this.rgb;
			return (r*0.299 + g*0.587 + b*0.114) <= 186;
			// r /= 255;
			// g /= 255;
			// b /= 255;
			// r = r <= 0.03928 ? r/12.92 : Math.pow((r+0.055)/1.055, 2.4);
			// g = g <= 0.03928 ? r/12.92 : Math.pow((r+0.055)/1.055, 2.4);
			// b = b <= 0.03928 ? r/12.92 : Math.pow((r+0.055)/1.055, 2.4);
			// let L = 0.2126*r + 0.7152*g + 0.0722*b;
			// return L <= 0.179;
		},
		releaseYear(): string {
			if (!this.movie || !this.movie.release_date) {
				return "";
			}
			return this.movie.release_date.slice(0, 4);
		},
		releaseDate(): string {
			if (!this.movie || !this.movie.release_date) {
				return "";
			}
			let [year, month, day] = this.movie.release_date.split('-');
			return `${month}/${day}/${year}`;
		},
		runtime(): string {
			if (!this.movie || !this.movie.runtime) {
				return "";
			}
			let hours = Math.floor(this.movie.runtime / 60);
			let minutes = Math.floor(this.movie.runtime % 60);
			return (hours > 0 ? `${hours}h ` : "") + `${minutes}m`;
		}
	},
	data() {
		return {
			rgb: {r: 0, g: 0, b: 0},
			movie: <IMovieDetails|undefined>undefined,
			isPosterLoaded: false
		}
	},
	methods: {
		close() {
			this.movie = undefined;
			this.$emit("onClose");
		},
		onKeyPress(event: KeyboardEvent) {
			if (event.key != "Escape") {
				return;
			}
			this.close();
		},
		onPosterLoad() {
			this.isPosterLoaded = true;
			this.computeBackdropColor();
		},
		computeBackdropColor() {
			let rgb: {r: number, g: number, b: number};
			try {
				rgb = getAverageRgb(<HTMLImageElement>this.$refs["poster"]);
			} catch(e) {
				return { r: 0, g: 0, b: 0 };
			}

			// Adjust contrast
			let c = 60;
			let f = 259*(c + 255) / (255*(259 - c));
			for (let k in rgb) {
				rgb[k] = Math.min(Math.max(f*(rgb[k] - 128) + 128, 0), 255);
			}

			// Adjust brightness
			for (let k in rgb) {
				rgb[k] *= 0.90;
			}
			this.rgb = rgb;
		},
		async fetchMovieDetails() {
			let response = <movie> await (authFetch(`/api/movie/details/${this.movieId}`).then(response => response.json()));
			this.movie = response.data;
		}
	},
	mounted() {
		document.addEventListener("keydown", this.onKeyPress);
		this.fetchMovieDetails();
	},
	beforeUnmount() {
		document.removeEventListener("keydown", this.onKeyPress);
	},
	props: {
		movieId: {
			type: [Number, String],
			required: true
		}
	},
	watch: {
		movieId(newId: number, oldId: number) {
			console.log(newId);
		}
	},
	beforeRouteEnter() {
		useStore().commit(Mutation.LockScroll, true);
	},
	beforeRouteLeave() {
		useStore().commit(Mutation.LockScroll, false);
	}
});
</script>

<style>
.modal {
	@apply fixed inset-0 flex flex-col h-screen;
	background: rgba(0, 0, 0, 0.5);
}

.dot-separated > *:not(:first-child)::before {
	@apply px-2;
	content: '\2022'
}

.modal button {
	@apply ring-0;
}

.modal button:focus-visible {
	@apply ring-2 ring-indigo-500 ring-offset-2;
}

</style>
