  <template>
    <transition name="fade">
        <div v-if="visible" :class="['position-message', type, position]" :style="positionStyle">
            <img :src="defaultImages[type]" class="message-image" />
            <span>{{ currentMessage }}</span>
        </div>
    </transition>
</template>

<script>
export default {
    props: {
        type: {
            type: String,
            default: 'info',
            validator: val => ['info', 'success', 'error', 'warning'].includes(val)
        },
        position: {
            type: String,
            default: 'top',
            validator: val => ['top', 'bottom'].includes(val)
        },
        message: String,
        target: null,
        offset: {
            type: Number,
            default: 10
        },
        duration: {
            type: Number,
            default: 2000
        }
    },
    data() {
        return {
            visible: false,
            positionStyle: {},
            currentMessage: this.message, // 使用内部数据存储message
            defaultImages: {
                success: require('@/assets/message_Success.png'),
                info: require('@/assets/message_Warning.png'),
                warning: require('@/assets/message_Warning.png'),
                error: require('@/assets/message_error.png')
            },
            timer: null
        }
    },
    watch: {
        // 监听props的message变化
        message(newVal) {
            this.currentMessage = newVal;
            this.$nextTick(() => {
                this.calculatePosition();
            });
        }
    },
    computed: {
        iconClass() {
            return {
                info: 'el-icon-info',
                success: 'el-icon-success',
                error: 'el-icon-error'
            }[this.type]
        }
    },
    methods: {
        show() {
            this.visible = true
            this.$nextTick(() => {
                this.calculatePosition();

                // 设置自动隐藏计时器（duration为0表示一直显示）
                if (this.duration > 0) {
                    this.clearTimer();
                    this.timer = setTimeout(() => {
                        this.hide();
                    }, this.duration);
                }
            });

            return this;
        },
        hide() {
            this.visible = false;
            this.clearTimer();
            return this;
        },
        updateMessage(newMessage) {
            this.currentMessage = newMessage;
            this.$nextTick(() => {
                this.calculatePosition();
            });
            return this;
        },
        updateConfig(newConfig) {
            // 更新多个配置项
            if (newConfig.message !== undefined) {
                this.currentMessage = newConfig.message;
            }
            if (newConfig.type) {
                this.$emit('update:type', newConfig.type);
            }
            if (newConfig.position) {
                this.$emit('update:position', newConfig.position);
            }

            this.$nextTick(() => {
                this.calculatePosition();
            });
            return this;
        },
        destroy() {
            this.hide();
            // 等待动画完成后移除DOM
            setTimeout(() => {
                if (this.$el && this.$el.parentNode) {
                    this.$el.parentNode.removeChild(this.$el);
                }
                this.$destroy();
            }, 300);
        },
        clearTimer() {
            if (this.timer) {
                clearTimeout(this.timer);
                this.timer = null;
            }
        },
        calculatePosition() {
            if (!this.$el || !this.visible) return;

            const targetEl = typeof this.target === 'string'
                ? document.querySelector(this.target)
                : this.target?.$el || this.target;

            if (!targetEl?.getBoundingClientRect) {
                console.error('Invalid target:', this.target);
                return;
            }

            const targetRect = targetEl.getBoundingClientRect();
            const messageWidth = this.$el.offsetWidth;
            const viewportWidth = window.innerWidth;
            const messageHeight = this.$el.offsetHeight;
            const scrollY = window.scrollY || window.pageYOffset;

            // 默认居中位置
            let left = targetRect.left + targetRect.width / 2 - messageWidth / 2;
            let top = 0;

            // 边界检测
            if (left < 5) {
                left = 5; // 左侧留一点边距
            } else if (left + messageWidth > viewportWidth - 5) {
                left = viewportWidth - messageWidth - 5; // 右侧留一点边距
            }

            if (this.position === 'top') {
                top = targetRect.top + scrollY - this.offset - messageHeight;
                // 如果上方空间不足，则显示在下方
                if (top < scrollY) {
                    top = targetRect.bottom + scrollY + this.offset;
                }
            } else {
                top = targetRect.bottom + scrollY + this.offset;
                // 如果下方超出可视区域，则显示在上方
                if (top + messageHeight > scrollY + window.innerHeight) {
                    top = targetRect.top + scrollY - this.offset - messageHeight;
                }
            }

            this.positionStyle = {
                top: `${top}px`,
                left: `${left}px`,
                right: 'auto'
            };
        },
    },
    beforeDestroy() {
        this.clearTimer();
    }
}
</script>

<style scoped lang="scss">
.position-message {
    position: absolute;
    min-width: 100px;
    padding: 14px 21px;
    border-radius: 4px;
    z-index: 9999;
    display: flex;
    align-items: center;
    background: #FFFFFF;
    box-sizing: border-box;
    box-shadow: 0px 3px 8px 0px rgba(0, 0, 0, 0.16);
    pointer-events: none;

    span {
        letter-spacing: 0.08em;
        color: #626573;
        white-space: nowrap;
    }
}
.message-image {
    width: 18px;
    height: 18px;
    margin-right: 10px;
    flex-shrink: 0;
}

.fade-enter-active,
.fade-leave-active {
    transition: opacity 0.3s, transform 0.3s;
}

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