<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue';
import assets from '../assets';

import { regions, type RegionData, type Store } from '../data';
import AniEle from '../components/AniEle.vue';

const regionsPos = [
    { w: 68.8, h: 68.8, l: -1, t: 0, src: assets.p1.大北区, tt: '大北区', trt: -13, ad: 6, key: '大北区' },
    { w: 73.3, h: 73.3, l: 44, t: 20, src: assets.p1.大东区, tt: '大东区', ad: 3, key: '大东区' },
    { w: 62.3, h: 63.7, l: -32, t: 72, src: assets.p1['大南区&免税'], tt: '大南区&免税', trt: 5, ad: 3, key: '大南区&免税' },
    { w: 59.6, h: 59.6, l: -37, t: 15, src: assets.p1.大西区, tt: '大西区', ad: 5, key: '大西区' },
    { w: 52.1, h: 52, l: 3, t: 40, src: assets.p1.奥莱, tt: '奥莱', ad: 2, key: '奥莱' },
    { w: 62.7, h: 62.7, l: 33, t: 74, src: assets.p1.博物馆, tt: '博物馆', tc: '#fff', ad: 0, key: '博物馆' },
]

// 响应式状态
const showStoreSelector = ref(false);
const selectedRegion = ref<string>('');
const selectedStores = ref<Store[]>([]);
const selectedStoreIndex = ref(0);
const selectedBubbleEl = ref<HTMLElement | null>(null);
const selectionInProgress = ref(false);

// 区域映射
const regionKeyMap: { [key: string]: keyof RegionData | 'combined' } = {
    '大北区': '大北区',
    '大东区': '大东区',
    '大南区&免税': 'combined',
    '大西区': '大西区',
    '奥莱': 'combined',
    '博物馆': '博物馆',
};

// 获取区域数据
function getRegionStores(regionKey: string): Store[] {
    const mappedKey = regionKeyMap[regionKey];
    if (mappedKey === 'combined') {
        if (regionKey === '大南区&免税') {
            return [...regions.大南区, ...regions.免税];
        } else if (regionKey === '奥莱') {
            return [...regions.奥莱北区, ...regions.奥莱东区];
        }
    } else if (mappedKey) {
        return regions[mappedKey];
    }
    return [];
}

// 拖拽选择逻辑 - 使用 Intersection Observer
let observer: IntersectionObserver | null = null;

function initializeStoreSelector() {
    setTimeout(() => {
        const storeItems = document.querySelectorAll('.store-item');
        if (storeItems.length === 0) return;

        observer = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    const index = Array.from(storeItems).indexOf(entry.target);
                    if (index !== -1 && index !== selectedStoreIndex.value) {
                        selectedStoreIndex.value = index;
                    }
                }
            });
        }, {
            root: document.querySelector('.store-list'),
            rootMargin: '-45% 0px -45% 0px',
            threshold: 0.5
        });

        storeItems.forEach(item => {
            observer?.observe(item);
        });
    }, 100);
}

function selectStore(index: number) {
    selectedStoreIndex.value = index;
    const storeItems = document.querySelectorAll('.store-item');
    if (storeItems[index]) {
        storeItems[index].scrollIntoView({
            behavior: 'smooth',
            block: 'center'
        });
    }
}

function cleanupObserver() {
    if (observer) {
        observer.disconnect();
        observer = null;
    }
}

const emit = defineEmits<{
    (e: 'startExploration', payload: { region: string; store: string, username: string }): void;
}>();

const noticeToInputName = ref(false);
async function startExploration() {
    console.log('开始探索:', selectedStores.value[selectedStoreIndex.value]);
    if (!selectedRegion.value || selectedStores.value.length === 0) {
        alert('请选择一个区域和店铺！');
        return;
    }
    const nameInput = document.querySelector('.name-input') as HTMLInputElement;
    if (nameInput.value.trim() === '') {
        noticeToInputName.value = true;
        return;
    }
    startExplorationRules.value[0].reverse = true;
    // 2. 将放大的气泡恢复原状

    let bubble = selectedBubbleEl.value;
    if (!bubble) return;

    bubble.classList.remove('zoomed');
    bubble.style.transform = 'translate3d(-50%, -50%, 0) scale(0)';

    document.querySelector('.sun-wrap')?.classList.add('fade-out');

    emit('startExploration', {
        region: selectedRegion.value,
        store: selectedStores.value[selectedStoreIndex.value].店铺,
        username: nameInput.value
    });
}


// 动画相关的 refs
const mainLogoRules = ref([
    { name: 'main', frame: 41, loop: 1, pauseAfter: true, duration: 33, reverse: false }
]);
const selectInfoRules = ref([{ name: 'main', frame: 26, loop: 1, duration: 33, reverse: false }]);
const startExplorationRules = ref([{ name: 'start', frame: 19, loop: 1, duration: 33, reverse: false }]);

const showSelectInfo = ref(false);
const showSun = ref(false);

// Refs for DOM elements to control their styles
const logoEl = ref<HTMLElement | null>(null);
const mainLogoWrapperEl = ref<HTMLElement | null>(null);
const selectInfoContainerEl = ref<HTMLElement | null>(null);

onMounted(() => {
    const wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));

    requestAnimationFrame(async () => {
        // --- 初始化动画 ---

        // 1. Logo 淡入
        setTimeout(() => {
            if (logoEl.value) logoEl.value.style.opacity = '1';
        }, 2000);

        // 2. 主标题和选择提示的容器淡入 (AniEle本身播放，我们控制其容器)

        // 3. 气泡下落动画
        const regionBubbles = document.querySelectorAll<HTMLElement>('.region-bubble');

        regionBubbles.forEach((bubble, index) => {
            const region = regionsPos[index];
            const startTop = `${region.t + 50 - 200 - (100 - region.t)}%`;
            const startLeft = `${region.l / 2 + 50}%`;
            const endTop = `${region.t + 50}%`;
            const endLeft = `${region.l + 50}%`;

            // 设置初始离屏位置
            Object.assign(bubble.style, {
                top: startTop,
                left: startLeft,
                transform: 'translate3d(-50%, -50%, 0) scale(0.1)',
                transitionDuration: `0ms`
            });

            // 延迟触发动画
            setTimeout(() => {
                Object.assign(bubble.style, {
                    top: endTop,
                    left: endLeft,
                    transform: 'translate3d(-50%, -50%, 0) scale(1)',

                    transitionDuration: `${600 + region.ad * 100}ms`
                });
            }, 1000); // 基础延迟

            // --- 绑定事件 ---
            const pDown = () => {
                if (selectionInProgress.value) return;
                bubble.style.filter = 'brightness(0.9)';
                bubble.style.transform = 'translate3d(-50%,-50%, 0) scale(0.92)';
            };

            const pUp = () => {
                if (selectionInProgress.value) return;
                selectionInProgress.value = true;
                selectedBubbleEl.value = bubble;

                selectedRegion.value = region.tt;
                selectedStores.value = getRegionStores(region.key);
                selectedStoreIndex.value = 0;

                // 放大选中的气泡
                bubble.classList.add('zoomed');
                bubble.style.filter = 'brightness(1)';

                // 隐藏气泡文字
                const span = bubble.querySelector('span');
                if (span) span.style.opacity = '0';

                // 淡出其他UI元素
                if (logoEl.value) logoEl.value.style.opacity = '0';

                mainLogoRules.value[0].reverse = true;
                selectInfoRules.value[0].reverse = true;

                // 淡出其他气泡
                regionBubbles.forEach(otherBubble => {
                    if (otherBubble !== bubble) {
                        otherBubble.style.transform = 'translate3d(-50%, -50%, 0) scale(0)';
                        otherBubble.style.opacity = '0';
                    } else {
                        otherBubble.style.transitionTimingFunction = 'cubic-bezier(0.71, 0.14, 0.27, 1.55)';
                        setTimeout(() => {
                            otherBubble.style.transitionTimingFunction = 'ease';
                        }, 1000);
                    }
                });

                // 动画完成后显示选择界面
                setTimeout(() => {
                    showStoreSelector.value = true;
                    initializeStoreSelector();
                }, 1000); // 等待放大动画完成
            };

            bubble.addEventListener('pointerdown', pDown);
            bubble.addEventListener('pointerup', pUp);
        });

        await wait(1300);
        showSelectInfo.value = true;
        // 等待showSelectInfo渲染后，设置其容器淡入
        await wait(10);
        if (selectInfoContainerEl.value) selectInfoContainerEl.value.style.opacity = '1';

        await wait(300);
        showSun.value = true;
    });
});


function goBackToRegionSelection() {
    if (!selectedBubbleEl.value) return;
    selectionInProgress.value = true; // 加锁防止重复操作

    mainLogoRules.value[0].reverse = false;
    selectInfoRules.value[0].reverse = false;

    // 1. 隐藏店铺选择器
    showStoreSelector.value = false;
    cleanupObserver();

    const bubble = selectedBubbleEl.value;

    // 2. 将放大的气泡恢复原状
    bubble.classList.remove('zoomed');

    // 3. 恢复气泡文字
    const span = bubble.querySelector('span');
    if (span) span.style.opacity = '1';

    // 4. 恢复其他UI元素
    if (logoEl.value) logoEl.value.style.opacity = '1';
    if (mainLogoWrapperEl.value) mainLogoWrapperEl.value.style.opacity = '1';
    if (selectInfoContainerEl.value) selectInfoContainerEl.value.style.opacity = '1';

    // 5. 恢复其他气泡
    const allBubbles = document.querySelectorAll<HTMLElement>('.region-bubble');
    allBubbles.forEach(otherBubble => {
        if (otherBubble !== bubble) {
            otherBubble.style.opacity = '1';
            otherBubble.style.transform = 'translate3d(-50%, -50%, 0) scale(1)';
        }
    });

    // 6. 动画结束后重置状态
    setTimeout(() => {
        selectedRegion.value = '';
        selectedStores.value = [];
        selectedStoreIndex.value = 0;
        selectedBubbleEl.value = null;
        selectionInProgress.value = false; // 解锁
    }, 1000); // 等待动画完成
}


onUnmounted(() => {
    cleanupObserver();
});

</script>

<template>
    <section class="p1">
        <img :src="assets.标准logo" alt="" class="logo" ref="logoEl">

        <div class="main-logo-wrapper" ref="mainLogoWrapperEl">
            <AniEle :url="assets.ani.主标出现" :width="1015" :height="336"
                :rules="mainLogoRules" style="top: 10%;width: 84%;left: 8%;" />
        </div>

        <div class="sun-warp" v-if="showSun">
            <AniEle :url="assets.ani.P1太阳总" :width="1000" :height="1000"
                :rules="[{ name: '下落', frame: 69, loop: 1, duration: 33 }, { name: '循环', frame: 75, loop: 0, duration: 33, reverse: false }]" />
        </div>

        <div
            style="width: 86vw;height: 86vw;top: 47%; left: 50%;transform: translate3d(-50%, -50%, 0); z-index: -1;">
            <div v-for="i in regionsPos" :key="i.key" :style="{
                width: i.w + '%',
                height: i.h + '%',
            }" class="region-bubble">

                <img :src="i.src" alt="" style="height: 100%;width: 100%;"
                    draggable="false">
                <span
                    :style="{ color: i.tc || '#000', top: (i.trt ?? 0) + 50 + '%' }">
                    *{{ i.tt }}
                </span>
            </div>
        </div>

        <div class="select-info-container" ref="selectInfoContainerEl"
            v-if="showSelectInfo">
            <AniEle :url="assets.ani.点击选择阵营" :width="1179" :height="2462"
                :rules="selectInfoRules" />
        </div>


        <!-- 店铺选择界面 -->
        <div v-if="showStoreSelector" class="store-selector">
            <div class="store-selector-content">
                <h2 class="region-title">你来自{{ selectedRegion }}的</h2>

                <div class="store-list-container">
                    <div class="store-list relative">
                        <div class="scroll-padding relative"></div>

                        <div v-for="(store, index) in selectedStores"
                            :key="store.店铺号" class="store-item relative"
                            :class="{ active: index === selectedStoreIndex }"
                            @click="selectStore(index)">
                            <div class="store-name relative">{{ store.店铺 }}
                            </div>
                        </div>

                        <div class="scroll-padding relative"></div>
                    </div>
                </div>

                <div class="name-input-section relative">
                    <div class="title relative">请输入你的名字</div>
                    <div class="input-container relative">
                        <input type="text" class="name-input" placeholder="">
                    </div>
                </div>
                <img class="input-your-name-notice"
                    src="../assets/p1/请填写你的名字.png" alt=""
                    v-if="noticeToInputName">

                <AniEle :url="assets.ani.开始探索" :width="548" :height="143"
                    :rules="startExplorationRules" class="start-button"
                    @click="startExploration">
                </AniEle>
            </div>

            <img src="../assets/返回按钮.png" alt="返回"
                @click="goBackToRegionSelection" class="back-button" />
        </div>
    </section>
</template>

<style scoped lang="scss">
/* --- Base Styles and Transitions --- */
.logo {
    top: 6%;
    left: 8%;
    width: 12%;
    opacity: 0;
    transition: opacity 0.5s ease-in-out;
}

.main-logo-wrapper {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.select-info-container {
    position: absolute;
    inset: 0;
    width: 100%;
    top: 52%;
    pointer-events: none;
    opacity: 0;
    transition: opacity 1s ease-in-out;
}

.region-bubble {
    position: absolute;
    cursor: pointer;
    // transition-duration is set dynamically in script
    transition-property: top, left, transform, opacity;
    transition-timing-function: ease;
    will-change: top, left, transform, opacity;

    &.zoomed {
        top: 53% !important;
        left: 50% !important;
        transform: translate3d(-50%, -50%, 0) scale(4) !important;
        transition-duration: 1000ms !important;
    }

    span {
        font-size: 4.5vw;
        left: 50%;
        transform: translate(-50%, -50%);
        font-weight: 400;
        width: fit-content;
        position: absolute;
        opacity: 1;
        transition: opacity 1s ease-in-out;
    }
}


/* --- Other Styles --- */

@keyframes sun-drop {
    0% {
        transform: translateY(-90vw);
    }

    100% {
        transform: translateY(0);
    }
}

.sun-warp {
    top: 32%;
    width: 24%;
    left: 4.5%;
    z-index: -1;
    transform: translateY(-90vw);
    animation: sun-drop 1s cubic-bezier(0.54, 0.46, 0.44, 1.28) forwards;
}

@keyframes fade-in {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

span,
div,
img {
    position: absolute;
}

.store-selector {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 10;
    animation: fade-in 0.5s ease-in-out;
}

.back-button {
    position: absolute;
    top: 16vw;
    left: 8vw;
    width: 8vw;
    animation: fade-in 0.3s ease-in-out;
    cursor: pointer;
    pointer-events: all;
    z-index: 111;
}

.store-selector-content {
    top: 10%;
    left: 5%;
    width: 90%;
    text-align: center;
    color: #333;
}

.region-title {
    font-size: 6vw;
    font-weight: 400;
    margin-bottom: 6vw;
    color: #333;
}

.store-list-container {
    margin-bottom: 12vw;
    height: 35vh;
    overflow: hidden;
    position: relative;
    mask-image: linear-gradient(to bottom, transparent 0%, black 15%, black 85%, transparent 100%);
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 15%, black 85%, transparent 100%);
}

.store-list {
    height: 100%;
    overflow-y: auto;
    scroll-behavior: smooth;
    scroll-snap-type: y mandatory;
    padding: 0;

    &::-webkit-scrollbar {
        display: none;
    }

    -ms-overflow-style: none;
    scrollbar-width: none;
}

.scroll-padding {
    height: calc(20vh - 4vw);
    flex-shrink: 0;
}

.store-item {
    width: 50vw;
    height: 8vw;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 8vw;
    scroll-snap-align: center;
    transition: all 0.3s ease;
    cursor: pointer;
    opacity: 0.6;
    font-size: 4vw;
    margin: 1vw auto;
    flex-shrink: 0;
}

.store-item.active {
    background: rgba(255, 255, 255, 0.9);
    opacity: 1;
    font-weight: bold;
}

.name-input-section {
    margin-bottom: 2vw;

    .title {
        font-size: 5vw;
        color: #333;
        margin-bottom: 4vw;
        font-weight: normal;
    }
}

@keyframes pop-up {
    from {
        scale: 0;
    }

    to {
        scale: 1;
    }
}

.input-your-name-notice {
    width: 40%;
    left: 30%;
    animation: pop-up 0.3s ease-out forwards;
    transform-origin: top center;
}

.input-container {
    position: relative;
    width: 80%;
    margin: 0 auto;
}

.name-input {
    width: 100%;
    padding: 2vw 0;
    font-size: 4.5vw;
    background: transparent url('../assets/p1/输入框.png') center / contain no-repeat;
    border: none;
    outline: none;
    color: #333;
    text-align: center;
}

.start-button {
    width: 40vw;
    left: 30%;
    cursor: pointer;
    transition: transform 0.1s ease;
    bottom: -30%;

    &:hover {
        transform: scale(1.05);
    }
}
</style>