<template>
    <view class="qy-loading">
        <view class="qy-loading-inner">
            <!-- ========== 加载中模式 ========== -->
            <template v-if="mode === 'loading'">
                <image
                    v-if="!loadError"
                    class="qy-loading-img"
                    :style="imgStyle"
                    :src="loadingSrc"
                    mode="aspectFit"
                    @error="onImageError"
                />
                <view v-else class="qy-loading-fallback">
                    <view class="qy-loading-placeholder"></view>
                </view>
                <text v-if="text" class="qy-loading-text">{{ text }}</text>
            </template>

            <!-- ========== 空数据模式 ========== -->
            <template v-else-if="mode === 'empty'">
                <view class="qy-empty-illustration">
                    <!-- 外圈光晕 -->
                    <view class="qy-empty-glow"></view>
                    <!-- 主图：空文档 -->
                    <view class="qy-empty-doc">
                        <view class="qy-empty-doc-fold"></view>
                        <view class="qy-empty-doc-body">
                            <view class="qy-empty-doc-line long"></view>
                            <view class="qy-empty-doc-line medium"></view>
                            <view class="qy-empty-doc-line short"></view>
                        </view>
                        <!-- 放大镜 -->
                        <view class="qy-empty-magnifier">
                            <view class="qy-empty-magnifier-glass"></view>
                            <view class="qy-empty-magnifier-handle"></view>
                        </view>
                    </view>
                </view>
                <text class="qy-empty-text">{{ text || '暂无数据' }}</text>
                <text v-if="subText" class="qy-empty-subtext">{{ subText }}</text>
            </template>
        </view>
    </view>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
// 直接引用 static 下的 loading.webp，由构建输出正确路径
import defaultLoadingImg from '@/static/loading.gif';

const props = withDefaults(
    defineProps<{
        /** 模式：loading 加载中（默认）| empty 空数据 */
        mode?: 'loading' | 'empty';
        /** 提示文字；loading 模式不传则不显示，empty 模式默认"暂无数据" */
        text?: string;
        /** 副文本提示（仅 empty 模式），如"请稍后再试" */
        subText?: string;
        /** 尺寸，单位 rpx，默认 120（仅 loading 模式下的动画尺寸） */
        size?: number;
        /** 自定义图片路径（仅 loading 模式），不传则使用 static/loading.gif */
        src?: string;
    }>(),
    {
        mode: 'loading',
        text: '',
        subText: '',
        size: 120,
        src: '',
    },
);

const loadError = ref(false);

const loadingSrc = computed(() => {
    if (props.src) return props.src;
    return defaultLoadingImg;
});

const imgStyle = computed(() => ({
    width: props.size + 'rpx',
    height: props.size + 'rpx',
}));

function onImageError() {
    loadError.value = true;
}
</script>

<style lang="scss" scoped>
/* ========== 通用容器 ========== */
.qy-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 120rpx;
    padding: 24rpx 0;
}

.qy-loading-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

/* ========== Loading 模式 ========== */
.qy-loading-img {
    flex-shrink: 0;
}

.qy-loading-fallback {
    width: 80rpx;
    height: 80rpx;
    display: flex;
    align-items: center;
    justify-content: center;
}

.qy-loading-placeholder {
    width: 56rpx;
    height: 56rpx;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.25);
}

.qy-loading-text {
    margin-top: 20rpx;
    font-size: 28rpx;
    color: #fff;
    text-align: center;
}

/* ========== Empty 模式 ========== */
.qy-empty-illustration {
    position: relative;
    width: 100rpx;
    height: 100rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    animation: emptyFloat 3s ease-in-out infinite;
}

/* 背景光晕 */
.qy-empty-glow {
    position: absolute;
    width: 90rpx;
    height: 90rpx;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(143, 157, 247, 0.15) 0%, rgba(143, 157, 247, 0) 70%);
}

/* 文档主体 */
.qy-empty-doc {
    position: relative;
    width: 55rpx;
    height: 65rpx;
    background: #fff;
    border-radius: 6rpx;
    box-shadow: 0 4rpx 16rpx rgba(100, 116, 200, 0.15), 0 1rpx 4rpx rgba(100, 116, 200, 0.08);
    overflow: visible;
}

/* 文档折角 */
.qy-empty-doc-fold {
    position: absolute;
    top: 0;
    right: 0;
    width: 14rpx;
    height: 14rpx;
    background: linear-gradient(135deg, transparent 50%, #e8ecf4 50%);
    border-radius: 0 6rpx 0 0;

    &::before {
        content: '';
        position: absolute;
        bottom: 0;
        left: 0;
        width: 14rpx;
        height: 14rpx;
        background: linear-gradient(135deg, transparent 50%, #dce1ed 50%);
        border-bottom-right-radius: 4rpx;
    }
}

/* 文档内容行 */
.qy-empty-doc-body {
    padding: 18rpx 7rpx 7rpx;
    display: flex;
    flex-direction: column;
    gap: 6rpx;
}

.qy-empty-doc-line {
    height: 4rpx;
    border-radius: 2rpx;
    background: #e8ecf4;

    &.long {
        width: 100%;
    }
    &.medium {
        width: 70%;
    }
    &.short {
        width: 45%;
    }
}

/* 放大镜 */
.qy-empty-magnifier {
    position: absolute;
    right: -9rpx;
    bottom: -7rpx;
    transform: rotate(-45deg);
}

.qy-empty-magnifier-glass {
    width: 20rpx;
    height: 20rpx;
    border-radius: 50%;
    border: 3rpx solid #8f9df7;
    background: rgba(143, 157, 247, 0.08);
}

.qy-empty-magnifier-handle {
    width: 3rpx;
    height: 10rpx;
    background: linear-gradient(to bottom, #8f9df7, #b5bfff);
    border-radius: 0 0 2rpx 2rpx;
    margin-left: 9rpx;
    margin-top: -1rpx;
}

/* 文字 */
.qy-empty-text {
    margin-top: 12rpx;
    font-size: 16rpx;
    color: #fff;
    text-align: center;
    letter-spacing: 1rpx;
}

.qy-empty-subtext {
    margin-top: 4rpx;
    font-size: 20rpx;
    color: #b5bfcf;
    text-align: center;
}

/* 悬浮动画 */
@keyframes emptyFloat {
    0%, 100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-5rpx);
    }
}
</style>
