<template>
    <div class="mail-container">
        <div class="mail-sidebar">
            <div class="p-10">
                <div class="sidebar-top-actions">
                    <el-button type="primary" icon="el-icon-plus" class="write-btn" @click="handleWrite">
                        {{ $t('mailboxCollect.writeBtn') }}
                    </el-button>
                    <el-button type="success" icon="el-icon-refresh" class="receive-btn" :loading="syncLoading" @click="handleSyncInbox">
                        {{ $t('mailboxCollect.receiveBtn') }}
                    </el-button>
                </div>
            </div>
            <ul class="folder-list">
                <li :class="{ active: currentFolder === 'inbox' }" @click="switchFolder('inbox')">
                    <i class="el-icon-message"></i> {{ $t('mailboxCollect.inboxTab') }}
                    <span class="badge" v-if="queryIn.num > 0">{{ queryIn.num }}</span>
                </li>
                <!-- <li :class="{ active: currentFolder === 'sent' }" @click="switchFolder('sent')">
                    <i class="el-icon-position"></i><span style="font-size: 14px">{{ $t('mailboxCollect.outboxTab') }}</span>
                </li> -->
                <!-- <li @click="notImplemented"><i class="el-icon-document"></i> <span style="font-size: 14px;">{{ $t('mailboxCollect.draftsTab')}}</span> </li>
        <li @click="notImplemented"><i class="el-icon-delete"></i> <span style="font-size: 14px;">{{ $t('mailboxCollect.deletedTab')}}</span> </li>
     -->
            </ul>

            <div class="sidebar-footer">
                <div class="user-card">
                    <el-avatar size="small" icon="el-icon-user-solid" class="user-avatar"></el-avatar>
                    <div class="user-detail">
                        <div class="user-name">{{ selectedAccount ? selectedAccount.smtp_from_name || 'Nova Demo' : '-' }}</div>
                        <div class="user-email" :title="selectedAccountEmail">{{ selectedAccountEmail }}</div>
                    </div>
                </div>
                <el-button size="mini" type="text" @click="openAccountDialog" class="switch-btn">
                    {{ $t('mailboxCollect.changeAccountBtn') }}
                </el-button>
            </div>
        </div>

        <div class="mail-list-panel" :style="{ width: listWidth + 'px' }" v-if="selectedAccount">
            <!-- <div class="panel-header">
        <el-input 
          v-model="searchKeyword"
          prefix-icon="el-icon-search"
          :placeholder="$t('mailboxCollect.searchPlaceholder')"
          clearable
          @change="handleSearch"
        ></el-input>
        <el-button icon="el-icon-refresh" circle :loading="syncLoading" @click="handleSyncInbox" style="margin-left: 10px;"></el-button> 
      </div> -->

            <div
                ref="listScrollArea"
                class="list-scroll-area"
                @scroll="onListScroll"
                v-loading="inboxLoading"
                :element-loading-text="$t('mailboxCollect.loading')"
            >
            <transition name="el-zoom-in-top">
        <div v-if="newMailsBuffer.length > 0" class="new-mail-alert" @click="newMailsBuffer=[]">
            <i class="el-icon-message"></i>
            {{ $t('mailboxCollect.newMailArrived', { count: newMailsBuffer.length }) || `收到 ${newMailsBuffer.length} 封新邮件，点击查看` }}
        </div>
    </transition>
                <template v-if="displayList.length > 0">
                    <div
                        v-for="(item,i) in displayList"
                        :key="item.id"
                        :class="['mail-item-box', { active: activeMailId === item.id, unread: item.state === 1 }]"
                        @click="selectMail(item,i)"
                    >
                        <div class="item-left">
                            <div v-if="item.is_read === 0" class="unread-dot"></div>
                            <el-avatar :size="32" icon="el-icon-user-solid" class="sender-avatar"></el-avatar>
                        </div>

                        <div class="item-right">
                            <div class="row-one">
                                <span class="sender-name">{{ item.from_name || item.email }}</span>
                                <span class="send-time"><span style="color: #999;margin-right: 4px;" v-if="item.has_attachment==1"><i class="el-icon-paperclip"></i></span>{{ formatDisplayTime(item.email_date) }}</span>
                            </div>
                            <div class="row-two">
                                <span class="mail-subject">{{ item.subject || $t('mailboxCollect.noSubject') }}</span>
                            </div>
                            <div class="row-three">
                                <p class="mail-excerpt">{{ stripHtml(item.content || '') }}</p>
                            </div>
		</div>
					</div>
								</template>
                <div v-if="inboxLoadingMore" class="load-more-tip">
                    <i class="el-icon-loading"></i> {{ $t('mailboxCollect.loadingMore') || '加载更多...' }}
                </div>
                <div v-else-if="displayList.length > 0 && inboxPage >= inboxTotalPages" class="load-more-tip no-more">
                    {{ $t('mailboxCollect.noMore') || '没有更多了' }}
                </div>
                <div v-else-if="displayList.length === 0" class="empty-list-container">
                    <div class="empty-wrapper">
                        <i class="el-icon-message"></i>
                        <p>{{ $t('mailboxCollect.emptyText') }}</p>
                    </div>
                </div>
            </div>
        </div>

        <div class="list-resizer" @mousedown="initResize" v-if="selectedAccount"></div>

        <div class="mail-content-panel" v-if="selectedAccount" v-loading="detailLoading">
            <template v-if="activeMailId && !detailLoading">
                <div class="mail-page">
                    <mail-detail v-if="detailMail" :mailData="detailMail" @close="closeDetail" />
                </div>
								</template>

            <div v-else class="empty-state">
                <div class="empty-wrapper">
                    <i class="el-icon-message"></i>
                    <p>{{ $t('mailboxCollect.selectMailTip') }}</p>
						</div>
					</div>
					</div>

        <el-dialog
            :title="$t('mailboxCollect.selectAccountTitle')"
            :visible.sync="accountDialogVisible"
            width="800px"
            append-to-body
            :close-on-click-modal="false"
            :show-close="true"
            :before-close="handleAccountDialogBeforeClose"
        >
            <el-form inline style="margin-bottom: 10px">
                <el-form-item :label="$t('mailboxCollect.journal')">
                    <el-select v-model="accountJournalId" style="width: 260px" :loading="journalLoading" @change="loadAccountsForJournal">
                        <el-option v-for="item in journalList" :key="item.journal_id" :label="item.title" :value="item.journal_id" />
                    </el-select>
                </el-form-item>
            </el-form>
            <el-table :data="accountList" v-loading="accountLoading" size="small">
                <el-table-column prop="smtp_user" :label="$t('mailboxCollect.accountColumn')" />
                <el-table-column prop="smtp_from_name" :label="$t('mailboxCollect.nameColumn')" />
                <el-table-column :label="$t('mailboxCollect.operation')" width="140">
								<template slot-scope="scope">
                        <span v-if="isCurrentAccount(scope.row)" class="current-account-text">{{
                            $t('mailboxCollect.currentAccountText')
                        }}</span>
                        <el-button v-else type="primary" size="mini" @click="chooseAccount(scope.row)">{{
                            $t('mailboxCollect.switchColumn')
                        }}</el-button>
								</template>
							</el-table-column>
						</el-table>
        </el-dialog>
	</div>
</template>

<script>
const API = {
    getInboxList: 'api/email_client/getInboxList',
    inboxSse: 'api/email_client/inboxSse',
    getEmailDetail: 'api/email_client/getEmailDetail',
    listAttachments: 'api/email_client/listEmailAttachments',
    getAttachment: 'api/email_client/getAttachment',
    syncInbox: 'api/email_client/syncInbox',
    getAccounts: 'api/email_client/getAccounts',
    getOneEmail: 'api/email_client/getOneEmail',
    getAllJournal: 'api/Article/getJournal'
};
import MailDetail from '../../components/page/components/email/MailDetail.vue';
	export default {
		data() {
			return {
                baseUrl: this.Common.baseUrl,
            currentFolder: 'inbox',
            searchKeyword: '',
            syncLoading: false,
            activeMailId: null,
            tableData_in: [],
				tableData_out: [],
            detailMail: {},
            queryIn: { num: 0 },
            inboxPage: 1,
            inboxPerPage:100,
            inboxTotalPages: 1,
            inboxTotal: 0,
            inboxLoadingMore: false,
            inboxLoading: false,
            listWidth: 350,
            minWidth: 260,
            maxWidth: 600,
            selectedAccount: null,
            accountDialogVisible: false,
            journalList: [],
            journalLoading: false,
            accountJournalId: null,
            accountList: [],
            accountLoading: false,
            detailLoading: false,
            // SSE (POST 长连接)
            sseAbortController: null,
            sseReconnectTimer: null,
            sseReader: null,
            sseBuffer: '',
            sseManuallyStopped: false,
            inboxRefreshTimer: null,
            sseSyncing: false,
            newMailsBuffer: [], // SSE 发现的新邮件暂存区
        };
    },
    components: { MailDetail },
    computed: {
        displayList() {
            return this.currentFolder === 'inbox' ? this.tableData_in : this.tableData_out;
        },
        selectedAccountEmail() {
            return this.selectedAccount ? this.selectedAccount.smtp_user : '';
        }
    },
		created() {
        this.loadJournals();
        this.initAccountSelection();
    },
    beforeDestroy() {
        this.stopInboxSse(true);
        if (this.inboxRefreshTimer) {
            clearTimeout(this.inboxRefreshTimer);
            this.inboxRefreshTimer = null;
        }
		},
		methods: {
            insertMailsFromBuffer() {
    // 1. 合并数据
    this.tableData_in = [...this.newMailsBuffer, ...this.tableData_in];
   
    // 3. 滚动到顶部
    this.$nextTick(() => {
        this.$refs.listScrollArea.scrollTop = 0;
    });
},
        closeDetail() {
            this.activeMailId = null;
            this.detailMail = {};
        },
        // 拖拽逻辑
        initResize(e) {
            const startX = e.clientX;
            const startWidth = this.listWidth;
            const doDrag = (moveEvent) => {
                const newWidth = startWidth + (moveEvent.clientX - startX);
                if (newWidth >= this.minWidth && newWidth <= this.maxWidth) {
                    this.listWidth = newWidth;
                }
            };
            const stopDrag = () => {
                document.removeEventListener('mousemove', doDrag);
                document.removeEventListener('mouseup', stopDrag);
                document.body.style.cursor = 'default';
            };
            document.addEventListener('mousemove', doDrag);
            document.addEventListener('mouseup', stopDrag);
            document.body.style.cursor = 'col-resize';
        },
        initAccountSelection() {
            const q = this.$route.query;
            const storedEmailId = localStorage.getItem('mailboxCollect_j_email_id');
            const storedJournalId = localStorage.getItem('mailboxCollect_journal_id');

            // 1. 兼容老链接：如果地址栏里带有参数，优先用并写入本地
            if (q.j_email_id) {
                this.loadAccountById(q.j_email_id);
                localStorage.setItem('mailboxCollect_j_email_id', q.j_email_id);
                if (q.journal_id) {
                    localStorage.setItem('mailboxCollect_journal_id', q.journal_id);
                }
                return;
            }

            // 2. 否则尝试从本地缓存恢复上次选择
            if (storedEmailId) {
                this.loadAccountById(storedEmailId);
                return;
            }

            // 3. 都没有则弹出选择账号弹窗
            this.openAccountDialog();
        },
        clearStoredAccount() {
            localStorage.removeItem('mailboxCollect_j_email_id');
            localStorage.removeItem('mailboxCollect_journal_id');
        },
        loadAccountById(jEmailId) {
            this.$api
                .post(API.getOneEmail, { j_email_id: jEmailId })
                .then((res) => {
                    const email = res && res.data ? res.data.email : null;
                    if (res && res.code === 0 && email) {
                        this.selectedAccount = email;
                        this.fetchData();
                        this.startInboxSse();
                        return;
                    }
                    // 账号不存在或不属于当前用户：清除本地缓存并弹窗选择
                    this.clearStoredAccount();
                    this.selectedAccount = null;
                    this.$message.warning(this.$t('mailboxCollect.accountNotBelong'));
                    this.openAccountDialog();
                })
                .catch(() => {
                    this.clearStoredAccount();
                    this.selectedAccount = null;
                    this.$message.warning(this.$t('mailboxCollect.accountNotBelong'));
                    this.openAccountDialog();
                });
        },
        openAccountDialog() {
            this.accountDialogVisible = true;
            // 期刊列表进入页面时已加载；仅在首次为空时补拉，避免每次切换账号都请求
            if (!this.journalList || this.journalList.length === 0) {
                this.loadJournals();
            }
            if (this.selectedAccount && this.selectedAccount.journal_id) {
                this.accountJournalId = this.selectedAccount.journal_id;
                this.loadAccountsForJournal(this.selectedAccount.journal_id);
            }
        },
        loadJournals() {
            this.journalLoading = true;
            this.$api
                .post(API.getAllJournal, { username: localStorage.getItem('U_name') })
                .then((res) => {
                    this.journalList = (res || []).map((i) => ({
                        journal_id: i.journal_id || i.id,
                        title: i.title || i.name || ''
                    }));
                    if (!this.accountJournalId && this.journalList.length > 0) {
                        this.accountJournalId = this.journalList[0].journal_id;
                        this.loadAccountsForJournal(this.accountJournalId);
                    }
                })
                .finally(() => {
                    this.journalLoading = false;
                });
        },
        loadAccountsForJournal(id) {
            this.accountLoading = true;
            this.$api.post(API.getAccounts, { journal_id: id }).then((res) => {
                this.accountLoading = false;
                this.accountList = res.data || [];
            });
        },
        isCurrentAccount(row) {
            if (!row || !this.selectedAccount) return false;
            return String(row.j_email_id || '') === String(this.selectedAccount.j_email_id || '');
        },
        chooseAccount(row) {
            this.selectedAccount = row;
            this.accountDialogVisible = false;
            this.closeDetail();

            // 将所选邮箱配置持久化到本地，避免暴露在地址栏
            if (row && row.j_email_id) {
                localStorage.setItem('mailboxCollect_j_email_id', String(row.j_email_id));
            }
            if (row && row.journal_id) {
                localStorage.setItem('mailboxCollect_journal_id', String(row.journal_id));
            }

            // 不再写入路由 query，直接拉取数据
            this.fetchData();
            this.startInboxSse();
        },
        handleAccountDialogBeforeClose(done) {
            const hasAccount = this.selectedAccount || this.$route.query.j_email_id;
            if (hasAccount) {
                done();
            } else {
                this.$message.error(this.$t('mailboxCollect.selectAccountTip'));
            }
            // 没选账号时不允许关闭
        },
        // 修改此方法：收到 SSE 后，只拉取最新的一封或几封，不刷新整页
syncInboxBySse(payload) {
    if (!payload || this.sseSyncing) return;
    const jEmailId = String(payload.j_email_id || '');
    const journalId = String(payload.journal_id || '');
    
    this.sseSyncing = true;
    this.$api.post(API.syncInbox, { j_email_id: jEmailId, journal_id: journalId })
        .then(() => {
            // 同步成功后，拉取最新的一封邮件数据（假设后端支持或通过 getInboxList 第一页获取）
            this.fetchLatestSingleMail(jEmailId, journalId);
        })
        .finally(() => { this.sseSyncing = false; });
},

fetchLatestSingleMail(jEmailId, journalId) {
    // 获取第一页的最新数据
    this.$api.post(API.getInboxList, { j_email_id: jEmailId, journal_id: journalId, page: 1, per_page: 100 })
        .then(res => {
            const list = res.data.list || res.data || [];
            this.queryIn.num = res.data.total || 0;
            // 找出 tableData_in 中不存在的新邮件
            list.forEach(item => {
                const isNew = !this.tableData_in.some(old => (old.id === (item.inbox_id || item.id)));
                const isNotBuffered = !this.newMailsBuffer.some(b => (b.id === (item.inbox_id || item.id)));
                
                if (isNew && isNotBuffered) {
                    // 格式化数据结构（保持与 fetchData 映射一致）
                    const formatted = {
                        id: item.inbox_id || item.id,
                        inbox_id: item.inbox_id || item.id,
                        email: item.from_email,
                        from_name: item.from_name,
                        subject: item.subject,
                        email_date: item.email_date,
                        content: item.content_html || item.content_text || '',
                        is_read: item.is_read
                    };
                    this.newMailsBuffer.unshift(formatted);
                    
                }
            });
            this.insertMailsFromBuffer();
        });
},
        // 拉取收件列表，支持分页：page=1 时替换列表，page>1 时追加；接口返回 total、page、per_page、total_pages
        fetchData(page) {
            if (!this.selectedAccount) return;
            const isFirstPage = page === 1 || page == null;
            if (isFirstPage) {
                this.inboxPage = 1;
                // 首次拉取：显示加载中
                this.inboxLoading = true;
                // 避免复用旧列表造成“先空后满”的闪烁
                this.tableData_in = [];
            }
            const params = {
                j_email_id: this.selectedAccount.j_email_id,
                journal_id: this.selectedAccount.journal_id,
                // keyword: this.searchKeyword || '',
                page: isFirstPage ? 1 : page,
                per_page: this.inboxPerPage
            };
            if (isFirstPage) {
                // 第一页不显示 loadingMore，仅翻页时显示
            } else {
                this.inboxLoadingMore = true;
            }
            this.$api
                .post(API.getInboxList, params)
                .then((res) => {
                    const data = res && res.data ? res.data : {};
                    const list = Array.isArray(data.list) ? data.list : Array.isArray(data) ? data : [];
                    const rows = list.map((item) => ({
                        id: item.inbox_id || item.id,
                        inbox_id: item.inbox_id || item.id,
                        email: item.from_email,
                        has_attachment: item.has_attachment,    
                        from_name: item.from_name,
                        subject: item.subject,
                        email_date: item.email_date,
                        content: item.content_html || item.content_text || '',
                        is_read: item.is_read
                    }));
                    if (isFirstPage) {
                        this.tableData_in = rows;
                    } else {
                        // 过滤掉已经在列表中存在的 id (可能来自 SSE 之前手动插入的)
            const filteredRows = rows.filter(row => 
                !this.tableData_in.some(existing => existing.id === row.id)
            );
            this.tableData_in = this.tableData_in.concat(filteredRows);
                        
                    }
                    this.inboxPage = data.page != null ? Number(data.page) : isFirstPage ? 1 : this.inboxPage;
                    this.inboxTotalPages = data.total_pages != null ? Number(data.total_pages) : 1;
                    this.inboxTotal = data.total != null ? Number(data.total) : this.tableData_in.length;
                    this.queryIn.num = this.inboxTotal;
                    this.inboxLoadingMore = false;
                    if (isFirstPage) this.inboxLoading = false;
                })
                .catch(() => {
                    this.inboxLoadingMore = false;
                    if (isFirstPage) this.inboxLoading = false;
                });
        },
        switchFolder(f) {
            this.currentFolder = f;
            this.activeMailId = null;
        },
        selectMail(item,index) {
            this.activeMailId = item.id;
            this.detailLoading = true;
            const inboxId = item.inbox_id || item.id;
            this.$api
                .post(API.getEmailDetail, { inbox_id: inboxId })
                .then((res) => {
                    const d = res && res.data;
                    if (res && res.code === 0 && d) {
                        this.detailMail = { ...d, inbox_id: String(inboxId), attachments: [] };
                        item.state = 0;
                        this.displayList[index].is_read = d.is_read;
                        if (Number(d.has_attachment) === 1) {
                            this.fetchAttachments(String(inboxId));
                        } else {
                            this.detailLoading = false;
                        }
                    } else {
                        this.detailLoading = false;
                    }
                })
                .catch(() => {
                    this.detailLoading = false;
                });
        },
        fetchAttachments(inboxId) {
            this.$api
                .post(API.listAttachments, { inbox_id: inboxId })
                .then((res) => {
                    const list = (res && res.data) || (res && res.list) || [];
                    const arr = Array.isArray(list) ? list : [];
                    const attachments = arr.map((a, idx) => ({
                        ...a,
                        part_index: a.part_index != null ? a.part_index : idx,
                        name: a.filename || a.name || `attachment_${idx}`,
                        size: a.size || '',
                        file_url: ''
                    }));
                    this.$set(this.detailMail, 'attachments', attachments);
                    this.batchFetchDownloadUrls(inboxId, attachments);
                })
                .catch(() => {})
                .finally(() => {
                    this.detailLoading = false;
                });
        },
        batchFetchDownloadUrls(inboxId, attachments) {
            attachments.forEach((att) => {
                this.$api
                    .post(API.getAttachment, {
                        inbox_id: String(inboxId),
                        part_index: String(att.part_index)
                    })
                    .then((res) => {
                        if (res && res.data && res.data.file_url) {
                            this.$set(att, 'file_url', res.data.file_url);
                        }
                    })
                    .catch(() => {});
            });
        },
        // 同步收件箱：api/email_client/syncInbox 参数 j_email_id、journal_id（均为 String），完成后重新拉取 displayList
        handleSyncInbox() {
            if (!this.selectedAccount) return;
            this.syncLoading = true;
            const params = {
                j_email_id: String(this.selectedAccount.j_email_id),
                journal_id: String(this.selectedAccount.journal_id)
            };
            this.$api
                .post(API.syncInbox, params)
                .then((res) => {
                    this.syncLoading = false;
                    if (res && res.code === 0) {
                        this.newMailsBuffer=[]
                        this.$message.success(this.$t('mailboxCollect.syncSuccess'));
                        this.fetchData();
                    } else {
                        this.$message.error((res && res.msg) || this.$t('mailboxCollect.syncFail'));
                    }
                })
                .catch(() => {
                    this.syncLoading = false;
                    this.$message.error(this.$t('mailboxCollect.syncFail'));
                });
        },
        /**
         * 格式化邮件显示时间
         * @param {Number|String} timestamp 后端返回的时间戳 (如: 1773110269)
         * @returns {String} 格式化后的字符串 (如: 15:57, 昨天, 3月8日, 2025-12-05)
         */
        formatDisplayTime(timestamp) {
            if (!timestamp) return '';

            // 1. 处理 10 位秒级时间戳，转为毫秒并实例化 Date 对象
            const date = new Date(Number(timestamp) * 1000);
            const now = new Date();

            // 提取日期信息用于比较
            const dateYear = date.getFullYear();
            const nowYear = now.getFullYear();
            const lang = localStorage.getItem('langs') === 'zh' ? 'zh-CN' : 'en-US';

            // 获取昨天日期
            const yesterday = new Date(now);
            yesterday.setDate(now.getDate() - 1);

            // 获取具体时分并补零 (例如 09:05)
            const hours = date.getHours().toString().padStart(2, '0');
            const minutes = date.getMinutes().toString().padStart(2, '0');
            const timePart = `${hours}:${minutes}`;

            // --- 按照图示规则判断返回 ---

            // 1. 如果是今天：只显示时间，如 "15:57"
            if (date.toDateString() === now.toDateString()) {
                return timePart;
            }

            // 2. 如果是昨天：显示 "昨天 15:57"
            if (date.toDateString() === yesterday.toDateString()) {
                return this.$t('mailboxCollect.yesterday') + ' ' + timePart;
            }

            // 3. 如果是今年（非今天/昨天）：按语言显示月日
            if (dateYear === nowYear) {
                return new Intl.DateTimeFormat(lang, { month: 'short', day: 'numeric' }).format(date);
            }

            // 4. 如果是往年：显示完整年月日，如 "2025-12-05"
            const dateMonth = date.getMonth() + 1;
            const dateDay = date.getDate();
            const fullMonth = dateMonth.toString().padStart(2, '0');
            const fullDay = dateDay.toString().padStart(2, '0');
            return `${dateYear}-${fullMonth}-${fullDay}`;
        },
        stripHtml(html) {
            return new DOMParser().parseFromString(html, 'text/html').body.textContent || '';
        },
        handleWrite() {
            if (!this.selectedAccount) return;
            this.$router.push('/mailboxSend');
        },
        handleSearch() {
            this.fetchData(1);
        },
        onListScroll(e) {
            const el = e.target;
            if (!el || this.currentFolder !== 'inbox' || this.inboxLoadingMore) return;
            if (this.inboxPage >= this.inboxTotalPages) return;
            const threshold = 80;
            if (el.scrollHeight - el.scrollTop - el.clientHeight <= threshold) {
                this.fetchData(this.inboxPage + 1);
            }
        },
        buildSseUrl(jEmailId) {
            // 与现有 axios baseURL=/api + 相对路径 规则一致；GET + query 传参
            const base = `${this.baseUrl}${API.inboxSse}`;
            const q = new URLSearchParams({ j_email_id: String(jEmailId) }).toString();
            return `${base}?${q}`;
        },
        stopInboxSse(manual) {
            this.sseManuallyStopped = !!manual;
            if (this.sseReconnectTimer) {
                clearTimeout(this.sseReconnectTimer);
                this.sseReconnectTimer = null;
            }
            if (this.sseReader) {
                try {
                    this.sseReader.cancel();
                } catch (e) {}
                this.sseReader = null;
            }
            if (this.sseAbortController) {
                try {
                    this.sseAbortController.abort();
                } catch (e) {}
                this.sseAbortController = null;
            }
            this.sseBuffer = '';
        },
        scheduleInboxRefresh() {
            if (!this.selectedAccount || this.currentFolder !== 'inbox') return;
            if (this.inboxRefreshTimer) return;
            this.inboxRefreshTimer = setTimeout(() => {
                this.inboxRefreshTimer = null;
                this.fetchData(1);
            }, 1200);
        },
        syncInboxBySse(payload) {
            if (!payload || this.sseSyncing) return;
            const jEmailId = payload.j_email_id != null ? String(payload.j_email_id) : '';
            const journalId = payload.journal_id != null ? String(payload.journal_id) : '';
            if (!jEmailId || !journalId) return;
            this.sseSyncing = true;
            this.$api
                .post(API.syncInbox, {
                    j_email_id: jEmailId,
                    journal_id: journalId
                })
                .then(() => {
                    this.fetchLatestSingleMail(jEmailId, journalId);
                    // this.scheduleInboxRefresh();
                })
                .catch(() => {})
                .finally(() => {
                    this.sseSyncing = false;
                });
        },
        handleSsePayload(rawData) {
            // 仅 inbox_updated 且 synced=1 时才处理；其它消息不刷新
            let payload = rawData;
            try {
                payload = JSON.parse(rawData);
            } catch (e) {}
            if (payload && payload.type === 'heartbeat') return;
            if (payload && payload.type === 'inbox_updated' && payload.synced>0) {
                this.syncInboxBySse(payload);
            }
        },
        handleSseDisconnected() {
            // 收到后端的“断开”事件：挂掉当前连接并立即重连
            if (this.sseReconnectTimer) return;

            // 标记为手动停止：避免当前 startInboxSse 的 catch 再额外 schedule 重连
            this.stopInboxSse(true);

            this.sseReconnectTimer = setTimeout(() => {
                this.sseReconnectTimer = null;
                this.sseManuallyStopped = false;
                this.startInboxSse();
            }, 800);
        },
        processSseChunk(textChunk) {
            // 归一化换行，避免 \r\n 导致按 \n\n 切块失败
            const normalized = String(textChunk).replace(/\r\n/g, '\n').replace(/\r/g, '\n');
            this.sseBuffer += normalized;
            const events = this.sseBuffer.split('\n\n');
            this.sseBuffer = events.pop() || '';
            events.forEach((evt) => {
                const lines = evt.split('\n');
                const eventNameLine = lines.find((line) => line.trim().startsWith('event:'));
                const eventName = eventNameLine ? eventNameLine.replace(/^\s*event:\s?/, '').trim() : '';
                const dataLines = lines
                    .filter((line) => line.trim().startsWith('data:'))
                    .map((line) => line.replace(/^\s*data:\s?/, ''));

                // 断开事件可能没有 data；因此需要单独处理 event
                if (eventName === 'disconnected') {
                    this.handleSseDisconnected();
                    return;
                }

                if (!dataLines.length) return;
                this.handleSsePayload(dataLines.join('\n'));
            });
        },
//         startInboxSse() {
//   // 1. 使用原生 EventSource，它会自动处理长连接
//   // 2. 注意：如果存在跨域，URL 必须写全；如果配置了 proxy，写代理路径
//   const url = "/api/api/email_client/inboxSse?j_email_id=12";
  
//   const es = new EventSource(url);

//   es.onopen = () => console.log("✅ SSE 连接成功！");
  
//   es.onmessage = (e) => {
//     console.log("📩 收到数据:", e.data);
//   };

//   es.onerror = (err) => {
//     console.error("❌ SSE 连接失败，请检查 Network 面板的 Status Code", err);
//     es.close();
//   };
// },
        async startInboxSse() {
            if (!this.selectedAccount || !this.selectedAccount.j_email_id) return;
            // 账号切换前先断开旧连接
            this.stopInboxSse(false);
            this.sseManuallyStopped = false;
            const jEmailId = String(this.selectedAccount.j_email_id);
            try {
                this.sseAbortController = new AbortController();
                const response = await fetch(this.buildSseUrl(jEmailId), {
                    method: 'GET',
                    signal: this.sseAbortController.signal
                });
                if (!response.ok || !response.body) {
                    throw new Error('SSE response invalid');
                }
                this.sseReader = response.body.getReader();
                const decoder = new TextDecoder('utf-8');
                while (true) {
                    const { done, value } = await this.sseReader.read();
                    if (done) {
                        // 流结束：把缓冲区里剩余内容当作最后一个事件处理
                        if (this.sseBuffer) {
                            this.processSseChunk('\n\n');
                        }
                        break;
                    }
                    if (value) this.processSseChunk(decoder.decode(value, { stream: true }));
                }
            } catch (e) {
                // 只有非手动停止时才尝试重连
                if (!this.sseManuallyStopped) {
                    if (this.sseReconnectTimer) clearTimeout(this.sseReconnectTimer);
                    this.sseReconnectTimer = setTimeout(() => {
                        this.sseReconnectTimer = null;
                        this.startInboxSse();
                    }, 3000);
                }
            }
        },
        notImplemented() {
            this.$message.info(this.$t('mailboxCollect.featureDev'));
        }
		}
	};
</script>

<style scoped>
.mail-container {
    display: flex;
    height: calc(100vh - 120px);
    background: #fff;
    overflow: hidden;
}

/* 1. 左侧栏 */
.mail-sidebar {
    width: 240px;
    background-color: #f8f9fa;
    border-right: 1px solid #eaeaea;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
}
.p-10 {
    padding: 10px;
}
.p-20 {
    padding: 20px;
}
.sidebar-top-actions {
    display: flex;
    gap: 10px;
    padding: 0 6px;
}
.write-btn {
    flex: 1;
    width: auto;
    border-radius: 8px;
    font-weight: bold;
    padding-left: 10px;
    padding-right: 10px;
}
.receive-btn {
    flex: 1;
    width: auto;
    border-radius: 8px;
    font-weight: bold;
    margin-left: 0px;
    padding-left: 10px;
    padding-right: 10px;
}
.folder-list {
    list-style: none;
    padding: 0;
    margin: 0;
    flex: 1;
}
.folder-list li {
    padding: 12px 20px;
    cursor: pointer;
    color: #606266;
    display: flex;
    align-items: center;
}
.folder-list li i {
    margin-right: 12px;
    font-size: 18px;
}
.folder-list li.active {
    background: #edeef0;
    color: #006699;
    font-weight: bold;
    border-left: 3px solid #006699;
}
.badge {
    margin-left: auto;
    background: #ddd;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 12px;
}

.sidebar-footer {
    padding: 10px 0px;
    border-top: 1px solid #eee;
    background: #f8f9fa;
}
.user-card {
    display: flex;
    align-items: center;
    margin-bottom: 8px;
    overflow: hidden;
}
.user-avatar {
    flex-shrink: 0;
    background: #ffeded;
    color: #f56c6c;
}
.user-detail {
    margin-left: 10px;
    overflow: hidden;
    flex: 1;
}
.user-name {
    font-size: 14px;
    font-weight: bold;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.user-email {
    font-size: 12px;
    color: #909399;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.switch-btn {
    padding: 0;
    font-size: 12px;
    color: #409eff;
}

/* 2. 中间列表栏 - 参考 image_8649db.png */
.mail-list-panel {
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    background: #fff;
}
.panel-header {
    padding: 15px;
    border-bottom: 1px solid #f5f5f5;
    display: flex;
}
.list-scroll-area {
    flex: 1;
    overflow-y: auto;
}

.mail-item-box {
    display: flex;
    padding: 8px 16px;
    border-bottom: 1px solid #f0f0f0;
    cursor: pointer;
}
.mail-item-box:hover {
    background: #f5f7fa;
}
.mail-item-box.active {
    background: #eef1f6;
    border-left: 3px solid #006699;
}
.item-left {
    margin-right: 12px;
    display: flex;
    align-items: flex-start;
    padding-top: 4px;
}
.sender-avatar {
    background: #c0c4cc;
}
.item-right {
    flex: 1;
    overflow: hidden;
}
.row-one {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 4px;
}
.sender-name {
    font-size: 14px;
    color: #303133;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.send-time {
    font-size: 12px;
    color: #909399;
    flex-shrink: 0;
}
.row-two {
    margin-bottom: 4px;
}
.mail-subject {
    font-size: 13px;
    color: #6a7282;
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.mail-excerpt {
    font-size: 12px;
    color: #606266;
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.load-more-tip {
    text-align: center;
    padding: 12px;
    font-size: 12px;
    color: #909399;
}
.load-more-tip.no-more {
    color: #c0c4cc;
}
.current-account-text {
    color: #006699;
    font-size: 12px;
}

/* 拖拽条 */
.list-resizer {
    width: 4px;
    cursor: col-resize;
    border-left: 1px solid #eaeaea;
    transition: background 0.2s;
}
.list-resizer:hover {
    background: #409eff;
}

/* 3. 右侧详情 */
.mail-content-panel {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.mail-page {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
}
.detail-toolbar {
    padding: 10px 20px;
    border-bottom: 1px solid #eee;
    display: flex;
    justify-content: space-between;
}
.detail-content {
    padding: 30px 40px;
    overflow-y: auto;
}
.mail-title {
    font-size: 24px;
    margin-bottom: 20px;
}
.mail-info {
    display: flex;
    align-items: center;
}
.info-main {
    margin-left: 15px;
}
.mail-body {
    line-height: 1.6;
    font-size: 15px;
}
.empty-state,
.empty-list-container {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #ccc;
    text-align: center;
}
.empty-state i,
.empty-list-container i {
    font-size: 48px;
    margin-bottom: 10px;
}
.new-mail-alert {
    background-color: #f0f9eb;
    color: #67c23a;
    padding: 10px;
    text-align: center;
    cursor: pointer;
    font-size: 13px;
    border-bottom: 1px solid #e1f3d8;
    position: sticky;
    top: 0;
    z-index: 10;
    font-weight: bold;
}
.new-mail-alert:hover {
    background-color: #e1f3d8;
}
.item-left {
    position: relative; /* 关键：让红点相对于此容器定位 */
    display: flex;
    align-items: center;
    margin-right: 12px;
}

.unread-dot {
    position: absolute;
    top: 16px;      /* 调整红点上下位置 */
    left: -13px;    /* 调整红点左右位置 */
    width: 8px;     /* 红点大小 */
    height: 8px;
    background-color: #F56C6C; /* 经典的警告红 */
    border-radius: 50%;
    border: 1.5px solid #fff;  /* 加个白边，在深色背景或头像上更清晰 */
    z-index: 10;
}
</style>
