<script setup lang="ts">
import { ref, watch, onMounted, computed } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useTabs } from "@/composables/useTabs";
import { useRenderers } from "@/composables/useRenderers";
import { useMediaServers } from "@/composables/useMediaServers";
import { useWebRenderer } from "@/composables/useWebRenderer";
import { useSwipe } from "@vueuse/core";

// Import des composants
import BottomTabBar from "@/components/unified/BottomTabBar.vue";
import EmptyState from "@/components/unified/EmptyState.vue";
import ServerDrawer from "@/components/unified/ServerDrawer.vue";
import RendererDrawer from "@/components/unified/RendererDrawer.vue";
import RendererTabContent from "@/components/unified/RendererTabContent.vue";
import ServerTabContent from "@/components/unified/ServerTabContent.vue";

const route = useRoute();
const router = useRouter();
const { tabs, activeTabId, switchTab, activeTab, syncWithRenderers, isEmpty } =
    useTabs();
const { allRenderers, fetchRenderers, getStateById } = useRenderers();
const { allServers, fetchServers } = useMediaServers();

// WebRenderer : ce navigateur s'enregistre automatiquement comme renderer UPnP
const webRenderer = useWebRenderer();
// Rafraîchir la liste des renderers dès que la session WebRenderer est établie
webRenderer.onConnected(() => void fetchRenderers(true));

// État des drawers
const drawerOpen = ref(false);
const rendererDrawerOpen = ref(false);

// Ref pour le swipe edge detection
const viewRef = ref<HTMLElement | null>(null);

// Swipe depuis le bord gauche pour ouvrir le drawer
useSwipe(viewRef, {
    threshold: 50,
    onSwipeEnd(_e: TouchEvent, swipeDirection: string) {
        // Swipe right depuis le bord gauche → ouvrir drawer
        if (swipeDirection === "right" && !drawerOpen.value) {
            const touch = _e.changedTouches[0];
            // Vérifier que le swipe commence depuis le bord gauche (< 50px)
            if (touch && touch.clientX < 50) {
                drawerOpen.value = true;
            }
        }
    },
});

// Récupérer l'ID du renderer actuellement sélectionné
const currentRendererId = computed(() => {
    const currentTab = activeTab.value;
    if (currentTab?.type === "renderer" && currentTab.metadata?.rendererId) {
        return currentTab.metadata.rendererId;
    }
    return null;
});

// Récupérer le renderer actif
const activeRenderer = computed(() => {
    const rendererId = currentRendererId.value;
    if (!rendererId) return null;
    return allRenderers.value.find((r) => r.id === rendererId) || null;
});

// Récupérer l'état du renderer actif
const activeRendererState = computed(() => {
    const rendererId = currentRendererId.value;
    if (!rendererId) return null;
    return getStateById(rendererId);
});

// Nombre de servers online pour afficher dans le badge
const onlineServersCount = computed(
    () => allServers.value.filter((s) => s.online).length,
);

// Nombre de renderers online (filtrés) pour afficher dans le badge
const onlineRenderersCount = computed(
    () => filterRenderers(allRenderers.value).filter((r) => r.online).length,
);

// Gestion de l'ouverture du drawer depuis le bouton
function handleDrawerOpen() {
    drawerOpen.value = true;
}

// Gestion de l'ouverture du renderer drawer depuis le bouton
function handleRendererDrawerOpen() {
    rendererDrawerOpen.value = true;
}

// Gestion de la sélection d'un renderer depuis le drawer
function handleRendererSelect(rendererId: string) {
    // Chercher le tab correspondant à ce renderer ou le créer
    const existingTab = tabs.value.find(
        (t) => t.type === "renderer" && t.metadata?.rendererId === rendererId,
    );
    if (existingTab) {
        switchTab(existingTab.id);
    }
}

// Filter to show only our own WebRenderer based on UDN match
function filterRenderers(renderers: typeof allRenderers.value) {
    const myUdn = webRenderer.rendererUdn.value;
    const normalizedUdn = myUdn?.replace(/^uuid:/, '') ?? null;
    return renderers.filter((r) => {
        // WebRenderers have "Web Audio – " as friendly_name prefix
        const isWebRenderer = r.friendly_name?.startsWith("Web Audio – ") ?? false;
        if (isWebRenderer) {
            if (normalizedUdn === null) return false;
            const normalizedId = r.id.replace(/^uuid:/, '');
            return normalizedId === normalizedUdn;
        }
        return true;
    });
}

// Sync route query params avec l'état des tabs
onMounted(async () => {
    // Fetch renderers et servers au montage
    await Promise.all([fetchRenderers(), fetchServers()]);

    // Sync initial des tabs avec les renderers (en excluant les WebRenderers étrangers)
    syncWithRenderers(filterRenderers(allRenderers.value));

    // Restaurer l'onglet actif depuis l'URL
    const urlTabId = route.query.tab as string;
    if (urlTabId && tabs.value.find((t) => t.id === urlTabId)) {
        switchTab(urlTabId);
    }
});

// Watch renderers pour sync automatique des tabs
// Note: on watch la taille du tableau + les IDs pour éviter un deep watch coûteux
watch(
    () => ({
        length: allRenderers.value.length,
        ids: allRenderers.value.map(r => r.id).join(','),
    }),
    (newVal, oldVal) => {
        // Re-sync uniquement si le nombre ou les IDs ont changé
        if (newVal.length !== oldVal?.length || newVal.ids !== oldVal?.ids) {
            syncWithRenderers(filterRenderers(allRenderers.value));
        }
    },
);

// Watch l'UDN du WebRenderer local : quand il s'établit, resync pour faire apparaître notre onglet
watch(
    () => webRenderer.rendererUdn.value,
    () => {
        syncWithRenderers(filterRenderers(allRenderers.value));
    },
);

// Watch les changements d'URL pour changer d'onglet
watch(
    () => route.query.tab,
    (newTabId) => {
        if (newTabId && typeof newTabId === "string") {
            const tab = tabs.value.find((t) => t.id === newTabId);
            if (tab && activeTabId.value !== newTabId) {
                switchTab(newTabId);
            }
        }
    },
);

// Watch les changements d'onglet actif pour mettre à jour l'URL
watch(
    () => activeTabId.value,
    (newActiveTabId) => {
        const currentTabId = route.query.tab as string;
        if (currentTabId !== newActiveTabId) {
            router.replace({
                query: {
                    ...route.query,
                    tab: newActiveTabId,
                    tabs: tabs.value.map((t) => t.id).join(","),
                },
            });
        }
    },
);

// Composant dynamique selon le type d'onglet
const currentTabComponent = computed(() => {
    const tab = activeTab.value;
    if (!tab) return null;

    switch (tab.type) {
        case "renderer":
            return RendererTabContent;
        case "server":
            return ServerTabContent;
        default:
            return null;
    }
});

// Props pour le composant actif
const currentTabProps = computed(() => {
    const tab = activeTab.value;
    if (!tab || !tab.metadata) return null;

    if (tab.type === "renderer" && tab.metadata.rendererId) {
        return { rendererId: tab.metadata.rendererId };
    }
    if (tab.type === "server" && tab.metadata.serverId) {
        return { serverId: tab.metadata.serverId };
    }
    return null;
});
</script>

<template>
    <div ref="viewRef" class="unified-control-view">
        <!-- Zone de contenu -->
        <main class="content-area">
            <!-- État vide: aucun renderer détecté -->
            <EmptyState v-if="isEmpty" />

            <!-- Onglets renderers/servers avec keep-alive -->
            <keep-alive v-else :max="12">
                <component
                    v-if="currentTabComponent && currentTabProps"
                    :is="currentTabComponent"
                    :key="activeTab?.id"
                    v-bind="currentTabProps"
                />
            </keep-alive>
        </main>

        <!-- Barre d'infos en bas -->
        <BottomTabBar
            :online-servers-count="onlineServersCount"
            :online-renderers-count="onlineRenderersCount"
            :active-renderer="activeRenderer"
            :active-renderer-state="activeRendererState"
            @open-drawer="handleDrawerOpen"
            @open-renderer-drawer="handleRendererDrawerOpen"
        />

        <!-- Drawer servers (swipe depuis bord gauche) -->
        <ServerDrawer
            v-model="drawerOpen"
            :selected-renderer-id="currentRendererId"
        />

        <!-- Drawer renderers (depuis bord droit) -->
        <RendererDrawer
            v-model="rendererDrawerOpen"
            :selected-renderer-id="currentRendererId"
            @select-renderer="handleRendererSelect"
        />
    </div>
</template>

<style scoped>
.unified-control-view {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100vh;
    overflow: hidden;
    background: var(--color-bg);
}

.content-area {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 0;
    position: relative;
}

/* Placeholder temporaire */
.tab-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    padding: var(--spacing-xl);
}

.placeholder-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-lg);
    max-width: 500px;
    padding: var(--spacing-xl);
    background: rgba(255, 255, 255, 0.05);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: var(--radius-lg);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
    text-align: center;
}

.placeholder-icon {
    color: var(--color-primary);
    opacity: 0.5;
}

.placeholder-title {
    font-size: var(--text-2xl);
    font-weight: 700;
    color: var(--color-text);
    margin: 0;
}

.placeholder-text {
    font-size: var(--text-base);
    color: var(--color-text-secondary);
    margin: 0;
    line-height: 1.6;
}

.placeholder-subtitle {
    font-size: var(--text-sm);
    color: var(--color-text-tertiary);
    font-style: italic;
    margin: 0;
}

/* Responsive pour 800x600 landscape */
@media (min-width: 600px) and (orientation: landscape) {
    .content-area {
        padding: var(--spacing-md);
    }
}

/* Responsive mobile portrait */
@media (max-width: 768px) and (orientation: portrait) {
    .content-area {
        padding: var(--spacing-sm);
    }

    .placeholder-card {
        padding: var(--spacing-lg);
    }

    .placeholder-icon {
        width: 48px;
        height: 48px;
    }

    .placeholder-title {
        font-size: var(--text-xl);
    }

    .placeholder-text {
        font-size: var(--text-sm);
    }
}

/* Animation de transition des onglets */
.v-enter-active,
.v-leave-active {
    transition:
        opacity 0.2s ease,
        transform 0.2s ease;
}

.v-enter-from {
    opacity: 0;
    transform: translateX(20px);
}

.v-leave-to {
    opacity: 0;
    transform: translateX(-20px);
}

</style>
