/*
 * 会话窗口模块：负责选择用户、消息轮询、发送与顶部状态反馈。
 * 作者: @ccfork
 */
import { apiGet, apiPost, apiUploadImage } from './api.js';
import { els, setMobileView, state } from './state.js';
import { escapeHtml } from './utils.js';
import { loadSessions, renderSessions } from './sessions.js';
import { closeResultsPanel } from './results.js';
import { loadWatchState, startWatchPolling } from './watch.js';
import { updateCurrentSessionHeader } from './session-header.js';

function adminMessageReadText(messageId) {
    const seenId = Number(state.currentSession?.chat_seen_admin_id || 0);
    return seenId >= Number(messageId || 0) ? '已读' : '未读';
}

function refreshAdminMessageReadStates() {
    els.adminMessages.querySelectorAll('.message.admin[data-message-id] .message-read').forEach((node) => {
        const message = node.closest('.message.admin');
        node.textContent = adminMessageReadText(message?.dataset.messageId);
    });
}

function updateUploadProgress(percent, text = '图片发送中') {
    if (!els.adminImageUploadProgress) return;
    const value = Math.max(0, Math.min(100, Number(percent || 0)));
    els.adminImageUploadProgress.hidden = false;
    els.adminImageUploadProgress.querySelector('.upload-progress-bar span').style.width = `${value}%`;
    els.adminImageUploadProgress.querySelector('p').textContent = `${text} ${value}%`;
}

function hideUploadProgress() {
    if (!els.adminImageUploadProgress) return;
    els.adminImageUploadProgress.hidden = true;
    els.adminImageUploadProgress.querySelector('.upload-progress-bar span').style.width = '0%';
    els.adminImageUploadProgress.querySelector('p').textContent = '图片发送中 0%';
}

function messagePreview(msg) {
    return window.MessageActions?.previewMessage(msg) || String(msg?.message || '').slice(0, 80);
}

function replyHtml(msg) {
    return window.MessageActions?.renderReplyBlock(msg.reply, { selfSender: 'admin' }) || '';
}

function messageTimeHtml(msg) {
    const recallText = msg.sender === 'admin' ? '已撤回' : '对方已撤回';
    const recall = msg.recalled ? `<span class="message-recall-label">${recallText}</span>` : '';
    if (msg.sender === 'admin') {
        const read = `<span class="message-read">${escapeHtml(adminMessageReadText(msg.id))}</span>`;
        return `<div class="message-time">${recall}${read}<span>${escapeHtml(msg.time || '')}</span></div>`;
    }
    return `<div class="message-time">${recall}<span>${escapeHtml(msg.time || '')}</span></div>`;
}

export async function selectSession(sessionId) {
    state.currentSessionId = sessionId;
    state.currentSession = state.allSessions.find((s) => s.id === sessionId) || { id: sessionId, user_id: sessionId };
    state.lastMessageId = 0;
    state.lastRecallSeq = Number(state.currentSession?.recall_seq || 0);
    els.adminMessages.innerHTML = '<div class="empty-state">正在打开小纸条...</div>';
    updateCurrentSessionHeader();
    closeResultsPanel();
    document.querySelectorAll('.user-card').forEach((card) => card.classList.toggle('active', card.dataset.session === sessionId));
    await loadWatchState({ preferChatProgress: true });
    startWatchPolling();
    await loadMessages(true);
    await apiPost({ action: 'mark_read', session_id: sessionId, last_read_id: state.lastMessageId });
    await loadSessions();
    if (state.pollingInterval) clearInterval(state.pollingInterval);
    state.pollingInterval = setInterval(() => loadMessages(false), 1400);
    setMobileView('chat');
}

export async function loadMessages(reset) {
    if (!state.currentSessionId) return;
    if (reset) state.lastMessageId = 0;
    try {
        const data = await apiGet('get_messages', {
            scope: 'admin',
            session_id: state.currentSessionId,
            last_id: String(state.lastMessageId)
        });
        if (!data.success) return;
        if (data.session) {
            state.currentSession = data.session;
            updateCurrentSessionHeader();
        }
        const recallSeq = Number(data.recall_seq || data.session?.recall_seq || 0);
        if (!reset && recallSeq > Number(state.lastRecallSeq || 0)) {
            state.lastRecallSeq = recallSeq;
            await loadMessages(true);
            return;
        }
        if (recallSeq > Number(state.lastRecallSeq || 0)) {
            state.lastRecallSeq = recallSeq;
        }
        if (reset && Number(data.clear_after_id || 0) > state.lastMessageId) {
            state.lastMessageId = Number(data.clear_after_id || 0);
        }
        if (reset) els.adminMessages.innerHTML = '';
        const messages = data.messages || [];
        if (messages.length) {
            appendMessages(messages);
            state.lastMessageId = messages[messages.length - 1].id;
            await apiPost({ action: 'mark_read', session_id: state.currentSessionId, last_read_id: state.lastMessageId });
            loadSessions();
        } else if (reset) {
            els.adminMessages.innerHTML = '<div class="empty-state">还没有聊天记录～</div>';
        }
        if (data.session) {
            refreshAdminMessageReadStates();
            renderSessions();
        }
    } catch (error) {
        console.error(error);
    }
}

function appendMessages(messages) {
    if (els.adminMessages.querySelector('.empty-state')) els.adminMessages.innerHTML = '';
    const stickerPacks = state.emojiPanel?.getStickerPacks() || [];
    const fragment = document.createDocumentFragment();
    messages.forEach((msg) => {
        const div = document.createElement('div');
        const isImage = msg.type === 'image' && msg.image && msg.image.url;
        const content = isImage ? null : window.ChatEmoji.renderMessageContent(msg.message, stickerPacks);
        div.className = `message ${msg.sender === 'admin' ? 'admin' : 'user'}`;
        if (msg.recalled) div.classList.add('recalled');
        div.dataset.messageId = String(msg.id || 0);
        div.dataset.sender = msg.sender === 'admin' ? 'admin' : 'user';
        div.dataset.type = isImage ? 'image' : 'text';
        div.dataset.preview = messagePreview(msg);
        div.dataset.recalled = msg.recalled ? '1' : '0';
        const timeHtml = messageTimeHtml(msg);
        div.innerHTML = isImage
            ? `<div class="message-bubble image-bubble">${replyHtml(msg)}<img class="message-image" src="${escapeHtml(msg.image.url)}" alt="图片消息"></div>${timeHtml}`
            : `<div class="message-bubble">${replyHtml(msg)}<div class="message-text">${content.html}</div></div>${timeHtml}`;
        if (!isImage && content.hasSoloSticker) div.querySelector('.message-bubble')?.classList.add('has-sticker');
        fragment.appendChild(div);
    });
    els.adminMessages.appendChild(fragment);
    els.adminMessages.scrollTop = els.adminMessages.scrollHeight;
}

async function recallAdminMessage(message) {
    if (!message?.id || !state.currentSessionId) return;
    try {
        const data = await apiPost({
            action: 'recall_message',
            session_id: state.currentSessionId,
            message_id: message.id,
            sender: 'admin'
        });
        if (!data.success) {
            alert(data.error || '撤回失败');
            return;
        }
        await loadMessages(true);
        await loadSessions();
    } catch (error) {
        alert('撤回失败');
    }
}

async function sendAdminImage(file) {
    if (!file || !state.currentSessionId) return;
    if (file.size > 5 * 1024 * 1024) {
        alert('图片最大 5MB');
        return;
    }
    els.adminImageBtn.disabled = true;
    updateUploadProgress(0);
    try {
        const data = await apiUploadImage({
            sessionId: state.currentSessionId,
            sender: 'admin',
            file,
            reply: state.messageActions?.getReply() || null,
            onProgress: (percent) => updateUploadProgress(percent)
        });
        if (!data.success) {
            alert(data.error || '图片发送失败');
            return;
        }
        updateUploadProgress(100, '图片已发送');
        state.messageActions?.clearReply();
        await loadMessages(false);
        await loadSessions();
    } finally {
        setTimeout(hideUploadProgress, 600);
        els.adminImageBtn.disabled = false;
        els.adminImageInput.value = '';
    }
}

async function sendAdminMessage() {
    const msg = window.ChatEmoji.convertEmoji(els.adminMessageInput.value.trim());
    if (!msg || !state.currentSessionId) return;
    state.emojiPanel?.close();
    els.adminSendBtn.disabled = true;
    try {
        const data = await apiPost({
            action: 'admin_send',
            session_id: state.currentSessionId,
            message: msg,
            reply: state.messageActions?.getReply() || null
        });
        if (data.success) {
            els.adminMessageInput.value = '';
            state.messageActions?.clearReply();
            resizeInput();
            await loadMessages(false);
            await loadSessions();
        }
    } catch (error) {
        alert('发送失败');
    } finally {
        els.adminSendBtn.disabled = false;
        els.adminMessageInput.focus();
    }
}

function resizeInput() {
    const input = els.adminMessageInput;
    input.style.height = 'auto';
    input.style.height = `${Math.min(input.scrollHeight, 124)}px`;
}

export function bindChatPanel() {
    state.messageActions = window.MessageActions?.bindMessageActions({
        container: els.adminMessages,
        input: els.adminMessageInput,
        draftHost: els.adminEmojiHost,
        selfSender: 'admin',
        canRecall: (message) => message.sender === 'admin' && !message.recalled,
        onRecall: recallAdminMessage
    });
    els.adminSendBtn.addEventListener('click', sendAdminMessage);
    els.adminImageBtn.addEventListener('click', () => els.adminImageInput.click());
    els.adminImageInput.addEventListener('change', () => sendAdminImage(els.adminImageInput.files?.[0]));
    els.adminMessageInput.addEventListener('input', resizeInput);
    els.adminMessageInput.addEventListener('keydown', (event) => {
        if (event.key === 'Enter' && !event.shiftKey) {
            event.preventDefault();
            sendAdminMessage();
        }
    });
}
