/* 縮小失敗。正在傳回未縮小的內容。
(1,5): run-time error CSS1030: Expected identifier, found 'component('
(1,5): run-time error CSS1031: Expected selector, found 'component('
(1,5): run-time error CSS1025: Expected comma or open brace, found 'component('
(64,2): run-time error CSS1019: Unexpected token, found ')'
(66,5): run-time error CSS1030: Expected identifier, found 'component('
(66,5): run-time error CSS1031: Expected selector, found 'component('
(66,5): run-time error CSS1025: Expected comma or open brace, found 'component('
(119,2): run-time error CSS1019: Unexpected token, found ')'
 */
Vue.component('gh-notification', {
    template: `
        <div :class="['notification-wrapper', direction]">
            <div class="notification-container">
                <gh-notification-content
                    v-for="(notification, index) in notifications"
                    :key="notification.id"
                    v-bind="notification"
                    @close="removeNotification(notification.id)"
                ></gh-notification-content>
            </div>
        </div>
    `,
    data() {
        return {
            notifications: [],
            direction: 'top-right',
        };
    },
    methods: {
        // 初始化
        init(options = {}, type) {
            // 決定通知位置
            this.direction = Object.hasOwn(options, 'direction') ? options.direction : 'top-right';

            // 清空現有通知，確保只有一個通知
            const isStack = Object.hasOwn(options, 'stack') ? options.stack : true;
            if (!isStack) {
                this.notifications = [];
            }

            return {
                id: crypto.randomUUID(),
                type: type,
                title: Object.hasOwn(options, 'title') ? options.title : '',
                body: Object.hasOwn(options, 'body') ? options.body : '',
                icon: Object.hasOwn(options, 'icon') ? options.icon : '',
                timeout: Object.hasOwn(options, 'timeout') ? parseInt(options.timeout) : 3000,
            };
        },
        sleep(ms) {
            return new Promise((resolve) => setTimeout(resolve, ms));
        },
        // 通知
        notify(options = {}) {
            const opts = this.init(options, 'basic');
            this.notifications.push(opts);
        },
        // 警告
        warn(options = {}) {
            const opts = this.init(options, 'warning');
            this.notifications.push(opts);
        },
        // 錯誤
        error(options = {}) {
            const opts = this.init(options, 'danger');
            this.notifications.push(opts);
        },
        // 移除堆疊
        removeNotification(id) {
            this.notifications = this.notifications.filter((n) => n.id !== id);
        },
    },
});

Vue.component('gh-notification-content', {
    template: `
        <div :class="notificationBoxClass" :style="{ opacity: isVisible ? 1 : 0 }">
            <div v-if="icon" :class="iconClass"></div>
            <div class="text">
                <p class="title" v-if="title">{{ title }}</p>
                <p class="body">{{ body }}</p>
            </div>
        </div>
    `,
    data() {
        return {
            isVisible: false,
        };
    },
    props: {
        id: { type: String, required: true },
        type: { type: String, required: true },
        title: { type: String, required: true },
        body: { type: String, required: true },
        icon: { type: String },
        timeout: { type: Number, required: true },
    },
    computed: {
        notificationBoxClass() {
            return ['notification-box', 'notification-' + this.type, this.icon ? 'has-icon' : ''];
        },
        iconClass() {
            return ['icon', 'icon-' + this.icon];
        },
    },
    mounted() {
        this.showNotification();
    },
    methods: {
        // 顯示通知
        showNotification() {
            // 渲染後延遲調整 isVisible，確保淡入效果執行
            setTimeout(() => {
                this.isVisible = true;
            }, 100);

            // timeout 後開始關閉
            setTimeout(() => {
                this.isVisible = false;

                // 等待動畫後再處理
                setTimeout(() => {
                    this.$emit('close');
                }, 300);
            }, this.timeout);
        },
    },
});

