<script setup lang="ts">
import { computed, toRef, ref } from "vue";
import { useRenderer } from "@/composables/useRenderers";
import { useUIStore } from "@/stores/ui";
import { api } from "@/services/pmocontrol/api";
import { Music, X } from "lucide-vue-next";

const props = defineProps<{
    rendererId: string;
}>();

const { state } = useRenderer(toRef(props, "rendererId"));
const uiStore = useUIStore();
const metadata = computed(() => state.value?.current_track);
const isSeeking = ref(false);
const isDragging = ref(false);
const dragProgress = ref(0);
const seekTargetMs = ref<number | null>(null);

// État pour l'overlay de la cover
const showCoverOverlay = ref(false);
const showMetadata = ref(false);

function openCoverOverlay() {
    if (hasCover.value) {
        showCoverOverlay.value = true;
        showMetadata.value = false; // Reset metadata visibility when opening
    }
}

function closeCoverOverlay() {
    showCoverOverlay.value = false;
    showMetadata.value = false;
}

// Détecter le clic sur la partie basse de l'image
function handleOverlayContentClick(event: MouseEvent) {
    const target = event.currentTarget as HTMLElement;
    const rect = target.getBoundingClientRect();
    const clickY = event.clientY - rect.top;
    const height = rect.height;

    // Si le clic est dans le tiers inférieur, toggle les métadonnées
    if (clickY > height * 0.66) {
        showMetadata.value = !showMetadata.value;
    }
}

// Calcul du pourcentage de progression
const progressPercent = computed(() => {
    // Si on est en train de drag, utiliser la position du drag
    if (isDragging.value) {
        return dragProgress.value;
    }

    // Si on a une cible de seek active
    if (seekTargetMs.value !== null) {
        const currentPosition = state.value?.position_ms || 0;

        // Si la position actuelle est proche de la cible (tolérance de 2 secondes)
        if (Math.abs(currentPosition - seekTargetMs.value) < 2000) {
            // On peut libérer le contrôle
            seekTargetMs.value = null;
            dragProgress.value = 0;
        } else {
            // Sinon, continuer à afficher la position cible
            return dragProgress.value;
        }
    }

    const position = state.value?.position_ms;
    const duration = state.value?.duration_ms;
    if (position && duration && duration > 0) {
        return (position / duration) * 100;
    }
    return 0;
});

// Formater la durée en MM:SS
function formatTime(ms: number | null | undefined): string {
    if (!ms) return "--:--";
    const totalSeconds = Math.floor(ms / 1000);
    const minutes = Math.floor(totalSeconds / 60);
    const seconds = totalSeconds % 60;
    return `${minutes}:${seconds.toString().padStart(2, "0")}`;
}

const currentTime = computed(() => formatTime(state.value?.position_ms));
const totalTime = computed(() => formatTime(state.value?.duration_ms));

const hasCover = computed(() => !!metadata.value?.album_art_uri);

function handleImageError(event: Event) {
    const img = event.target as HTMLImageElement;
    img.style.display = "none";
}

// Calculer le pourcentage à partir d'une position X dans la barre
function calculateProgressFromX(
    clientX: number,
    progressBar: HTMLElement,
): number {
    const rect = progressBar.getBoundingClientRect();
    const x = Math.max(0, Math.min(clientX - rect.left, rect.width));
    return (x / rect.width) * 100;
}

// Gestion du drag sur la progress bar
function handleProgressBarMouseDown(event: MouseEvent) {
    const duration = state.value?.duration_ms;
    if (!duration || duration === 0 || isSeeking.value) return;

    const progressBar = event.currentTarget as HTMLElement;
    isDragging.value = true;
    dragProgress.value = calculateProgressFromX(event.clientX, progressBar);

    const handleMouseMove = (e: MouseEvent) => {
        if (!isDragging.value) return;
        dragProgress.value = calculateProgressFromX(e.clientX, progressBar);
    };

    const handleMouseUp = async (e: MouseEvent) => {
        if (!isDragging.value) return;

        const finalPercent = calculateProgressFromX(e.clientX, progressBar);
        const newPositionMs = (finalPercent / 100) * duration;
        const newPositionSeconds = Math.floor(newPositionMs / 1000);

        // Garder dragProgress à jour et définir la cible
        dragProgress.value = finalPercent;
        seekTargetMs.value = newPositionMs;

        // D'abord arrêter le drag pour éviter les mouvements pendant le seek
        isDragging.value = false;

        try {
            isSeeking.value = true;
            await api.seekTo(props.rendererId, newPositionSeconds);
        } catch (error) {
            uiStore.notifyError(
                `Impossible de seek: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
            );
            // En cas d'erreur, réinitialiser
            seekTargetMs.value = null;
            dragProgress.value = 0;
        } finally {
            isSeeking.value = false;
        }

        document.removeEventListener("mousemove", handleMouseMove);
        document.removeEventListener("mouseup", handleMouseUp);
    };

    document.addEventListener("mousemove", handleMouseMove);
    document.addEventListener("mouseup", handleMouseUp);
}

// Gestion du seek sur la progress bar (clic simple)
async function handleProgressBarClick(event: MouseEvent) {
    // Ne rien faire si on vient de drag (géré par mouseup)
    if (isDragging.value) return;

    const duration = state.value?.duration_ms;
    if (!duration || duration === 0 || isSeeking.value) return;

    const progressBar = event.currentTarget as HTMLElement;
    const percent = calculateProgressFromX(event.clientX, progressBar);
    const newPositionMs = (percent / 100) * duration;
    const newPositionSeconds = Math.floor(newPositionMs / 1000);

    // Définir la cible et la position visuelle
    dragProgress.value = percent;
    seekTargetMs.value = newPositionMs;

    try {
        isSeeking.value = true;
        await api.seekTo(props.rendererId, newPositionSeconds);
    } catch (error) {
        uiStore.notifyError(
            `Impossible de seek: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
        );
        // En cas d'erreur, réinitialiser
        seekTargetMs.value = null;
        dragProgress.value = 0;
    } finally {
        isSeeking.value = false;
    }
}
</script>

<template>
    <div class="current-track">
        <!-- Cover Art -->
        <div
            class="cover-container"
            :class="{ clickable: hasCover }"
            @click="openCoverOverlay"
        >
            <img
                v-if="hasCover"
                :src="metadata?.album_art_uri!"
                :alt="metadata?.album || 'Album cover'"
                class="cover-image"
                loading="lazy"
                @error="handleImageError"
            />
            <div v-else class="cover-placeholder">
                <Music :size="64" />
            </div>
        </div>

        <!-- Metadata -->
        <div class="metadata">
            <h2 class="title">{{ metadata?.title || "Aucun titre" }}</h2>
            <p class="artist">{{ metadata?.artist || "Artiste inconnu" }}</p>
            <p class="album" v-if="metadata?.album">{{ metadata.album }}</p>
        </div>

        <!-- Progress Bar -->
        <div class="progress-section">
            <div
                class="progress-bar"
                @click="handleProgressBarClick"
                @mousedown="handleProgressBarMouseDown"
                :class="{ seeking: isSeeking, dragging: isDragging }"
            >
                <div
                    class="progress-bar-fill"
                    :style="{ width: `${progressPercent}%` }"
                >
                    <div class="progress-bar-thumb"></div>
                </div>
            </div>
            <div class="time-display">
                <span>{{ currentTime }}</span>
                <span>{{ totalTime }}</span>
            </div>
        </div>

        <!-- Overlay cover en grand avec effet glassmorphism -->
        <Teleport to="body">
            <Transition name="cover-overlay">
                <div
                    v-if="showCoverOverlay"
                    class="cover-overlay"
                    @click="closeCoverOverlay"
                >
                    <div
                        class="cover-overlay-content"
                        @click.stop="handleOverlayContentClick"
                    >
                        <button
                            class="cover-overlay-close"
                            @click="closeCoverOverlay"
                            title="Fermer"
                        >
                            <X :size="24" />
                        </button>
                        <img
                            v-if="hasCover"
                            :src="metadata?.album_art_uri!"
                            :alt="metadata?.album || 'Album cover'"
                            class="cover-overlay-image"
                        />
                        <Transition name="metadata-fade">
                            <div
                                v-if="metadata && showMetadata"
                                class="cover-overlay-metadata"
                            >
                                <h2>{{ metadata.title }}</h2>
                                <p class="artist">{{ metadata.artist }}</p>
                                <p v-if="metadata.album" class="album">
                                    {{ metadata.album }}
                                </p>
                            </div>
                        </Transition>
                    </div>
                </div>
            </Transition>
        </Teleport>
    </div>
</template>

<style scoped>
.current-track {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-lg);
}

.cover-container {
    width: 100%;
    aspect-ratio: 1;
    max-width: 300px;
    margin: 0 auto;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background-color: var(--color-bg-secondary);
    box-shadow: var(--shadow-lg);
    transition:
        transform 0.3s ease,
        box-shadow 0.3s ease;
}

.cover-container.clickable {
    cursor: pointer;
}

.cover-container.clickable:hover {
    transform: scale(1.02);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
}

.cover-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.cover-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-text-tertiary);
}

.metadata {
    text-align: center;
}

.title {
    font-size: var(--text-2xl);
    font-weight: 700;
    color: var(--color-text);
    margin: 0 0 var(--spacing-sm);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.artist {
    font-size: var(--text-lg);
    color: var(--color-text-secondary);
    margin: 0 0 var(--spacing-xs);
}

.album {
    font-size: var(--text-base);
    color: var(--color-text-tertiary);
    margin: 0;
}

.progress-section {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-xs);
    padding: 0 10px;
}

.progress-bar {
    position: relative;
    width: 100%;
    height: 6px;
    background: linear-gradient(
        to bottom,
        rgba(255, 255, 255, 0.15) 0%,
        rgba(255, 255, 255, 0.25) 50%,
        rgba(255, 255, 255, 0.15) 100%
    );
    border-radius: 3px;
    cursor: pointer;
    transition: background 0.2s ease;
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
    overflow: visible;
}

.progress-bar:hover {
    background: linear-gradient(
        to bottom,
        rgba(255, 255, 255, 0.2) 0%,
        rgba(255, 255, 255, 0.35) 50%,
        rgba(255, 255, 255, 0.2) 100%
    );
}

.progress-bar.dragging {
    cursor: grabbing;
    background: linear-gradient(
        to bottom,
        rgba(255, 255, 255, 0.2) 0%,
        rgba(255, 255, 255, 0.35) 50%,
        rgba(255, 255, 255, 0.2) 100%
    );
}

.progress-bar.seeking {
    cursor: wait;
    opacity: 0.7;
}

.progress-bar-fill {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    background: linear-gradient(90deg, #059669 0%, #10b981 50%, #34d399 100%);
    border-radius: 3px;
    transition: width 0.1s linear;
    z-index: 1;
    box-shadow: 0 0 8px rgba(16, 185, 129, 0.5);
    overflow: visible;
}

.progress-bar.dragging .progress-bar-fill {
    transition: width 0s;
    box-shadow: 0 0 12px rgba(16, 185, 129, 0.8);
}

.progress-bar-thumb {
    position: absolute;
    right: -10px;
    top: 50%;
    transform: translateY(-50%);
    width: 20px;
    height: 20px;
    background: white;
    border: 3px solid rgba(0, 0, 0, 0.8);
    border-radius: 50%;
    box-shadow:
        0 2px 8px rgba(0, 0, 0, 0.6),
        inset 0 1px 2px rgba(0, 0, 0, 0.1);
    transition: all 0.2s ease;
    z-index: 2;
    cursor: grab;
}

.progress-bar:hover .progress-bar-thumb {
    transform: translateY(-50%) scale(1.2);
    box-shadow:
        0 3px 12px rgba(0, 0, 0, 0.7),
        inset 0 1px 2px rgba(0, 0, 0, 0.1);
}

.progress-bar.dragging .progress-bar-thumb {
    transform: translateY(-50%) scale(1.3);
    cursor: grabbing;
    box-shadow:
        0 4px 16px rgba(0, 0, 0, 0.8),
        inset 0 1px 2px rgba(0, 0, 0, 0.1);
}

.time-display {
    display: flex;
    justify-content: space-between;
    font-size: var(--text-sm);
    color: var(--color-text-secondary);
    font-variant-numeric: tabular-nums;
}

/* Responsive */
@media (min-width: 768px) {
    .cover-container {
        max-width: 250px;
    }
}

@media (min-width: 1024px) {
    .cover-container {
        max-width: 300px;
    }
}

/* Mode kiosque - compactage pour petites hauteurs (800x600) */
@media (max-height: 700px) and (orientation: landscape) {
    .current-track {
        gap: var(--spacing-sm);
    }

    .cover-container {
        max-width: 160px !important;
        max-height: 160px;
    }

    .cover-placeholder {
        font-size: 40px;
    }

    .metadata {
        margin-top: -8px;
    }

    .title {
        font-size: var(--text-lg);
        margin: 0 0 4px;
    }

    .artist {
        font-size: var(--text-sm);
        margin: 0 0 2px;
    }

    .album {
        font-size: var(--text-xs);
    }

    .progress-section {
        gap: 4px;
    }

    .time-display {
        font-size: 11px;
    }
}

/* Overlay cover en grand - Liquid metal style */
.cover-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(20px) saturate(150%);
    -webkit-backdrop-filter: blur(20px) saturate(150%);
    padding: 16px;
}

.cover-overlay-content {
    position: relative;
    width: calc(100vw - 32px);
    height: calc(100vh - 32px);
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(40px) saturate(180%);
    -webkit-backdrop-filter: blur(40px) saturate(180%);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 24px;
    box-shadow:
        0 20px 60px rgba(0, 0, 0, 0.5),
        inset 0 1px 0 rgba(255, 255, 255, 0.2),
        inset 0 -1px 0 rgba(0, 0, 0, 0.3);
}

@media (prefers-color-scheme: dark) {
    .cover-overlay-content {
        background: rgba(0, 0, 0, 0.3);
        border-color: rgba(255, 255, 255, 0.15);
    }

    .cover-overlay-metadata {
        background: rgba(0, 0, 0, 0.7);
    }
}

.cover-overlay-close {
    position: absolute;
    top: var(--spacing-md);
    right: var(--spacing-md);
    width: 48px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.2);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.3);
    border-radius: 50%;
    cursor: pointer;
    color: var(--color-text);
    transition: all 0.3s ease;
    z-index: 10;
}

.cover-overlay-close:hover {
    background: rgba(255, 255, 255, 0.3);
    transform: scale(1.1) rotate(90deg);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.cover-overlay-close:active {
    transform: scale(1) rotate(90deg);
}

@media (prefers-color-scheme: dark) {
    .cover-overlay-close {
        background: rgba(0, 0, 0, 0.3);
        border-color: rgba(255, 255, 255, 0.2);
    }

    .cover-overlay-close:hover {
        background: rgba(0, 0, 0, 0.5);
    }
}

.cover-overlay-image {
    width: calc(100vw - 64px);
    height: calc(100vh - 64px);
    border-radius: 16px;
    box-shadow:
        0 30px 80px rgba(0, 0, 0, 0.6),
        0 0 2px rgba(255, 255, 255, 0.2);
    object-fit: contain;
}

.cover-overlay-metadata {
    position: absolute;
    bottom: 24px;
    left: 24px;
    right: 24px;
    text-align: center;
    padding: var(--spacing-lg);
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(30px) saturate(180%);
    -webkit-backdrop-filter: blur(30px) saturate(180%);
    border-radius: 20px;
    border: 1px solid rgba(255, 255, 255, 0.15);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
}

.cover-overlay-metadata h2 {
    font-size: clamp(1.5rem, 4vw, 2.5rem);
    font-weight: 700;
    color: white;
    margin: 0;
    text-shadow: 0 2px 12px rgba(0, 0, 0, 0.8);
    line-height: 1.2;
}

.cover-overlay-metadata .artist {
    font-size: clamp(1rem, 2.5vw, 1.5rem);
    font-weight: 500;
    color: rgba(255, 255, 255, 0.9);
    margin: 8px 0 0 0;
    text-shadow: 0 1px 8px rgba(0, 0, 0, 0.6);
    padding-top: 8px;
    border-top: 1px solid rgba(255, 255, 255, 0.2);
}

.cover-overlay-metadata .album {
    font-size: clamp(0.875rem, 2vw, 1.125rem);
    font-weight: 400;
    font-style: italic;
    color: rgba(255, 255, 255, 0.75);
    margin: 6px 0 0 0;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.6);
}

/* Animations de transition */
.cover-overlay-enter-active,
.cover-overlay-leave-active {
    transition: all 0.3s ease;
}

.cover-overlay-enter-active .cover-overlay-content,
.cover-overlay-leave-active .cover-overlay-content {
    transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.cover-overlay-enter-from,
.cover-overlay-leave-to {
    opacity: 0;
    backdrop-filter: blur(0px);
    -webkit-backdrop-filter: blur(0px);
}

.cover-overlay-enter-from .cover-overlay-content,
.cover-overlay-leave-to .cover-overlay-content {
    opacity: 0;
    transform: scale(0.9);
}

.cover-overlay-enter-to,
.cover-overlay-leave-from {
    opacity: 1;
}

.cover-overlay-enter-to .cover-overlay-content,
.cover-overlay-leave-from .cover-overlay-content {
    opacity: 1;
    transform: scale(1);
}

/* Responsive overlay */
@media (max-width: 768px) {
    .cover-overlay {
        padding: 12px;
    }

    .cover-overlay-content {
        width: calc(100vw - 24px);
        height: calc(100vh - 24px);
        border-radius: 16px;
    }

    .cover-overlay-image {
        width: calc(100vw - 48px);
        height: calc(100vh - 48px);
    }

    .cover-overlay-metadata {
        bottom: 16px;
        left: 16px;
        right: 16px;
        padding: var(--spacing-md);
    }

    .cover-overlay-close {
        width: 40px;
        height: 40px;
        top: 12px;
        right: 12px;
    }
}

/* Mode kiosque - overlay adapté */
@media (max-height: 700px) and (orientation: landscape) {
    .cover-overlay {
        padding: 12px;
    }

    .cover-overlay-content {
        width: calc(100vw - 24px);
        height: calc(100vh - 24px);
    }

    .cover-overlay-image {
        width: calc(100vw - 48px);
        height: calc(100vh - 48px);
    }

    .cover-overlay-metadata {
        bottom: 12px;
        left: 12px;
        right: 12px;
        padding: var(--spacing-sm);
    }

    .cover-overlay-metadata .artist {
        padding-top: 4px;
    }

    .cover-overlay-metadata .album {
        display: none; /* Masquer l'album en mode kiosque pour plus d'espace */
    }
}

/* Transition pour les métadonnées */
.metadata-fade-enter-active,
.metadata-fade-leave-active {
    transition: all 0.3s ease;
}

.metadata-fade-enter-from,
.metadata-fade-leave-to {
    opacity: 0;
    transform: translateY(20px);
}

.metadata-fade-enter-to,
.metadata-fade-leave-from {
    opacity: 1;
    transform: translateY(0);
}
</style>
