import React, { useState, useEffect } from 'react';
import { useQuery, useMutation } from 'convex/react';
import { api } from '../../../../convex/_generated/api';
import MessageItem from './MessageItem';
import { usePlatform } from '../platform';

const TAG_LENGTH = 32;

const PinnedMessagesPanel = ({
    channelId,
    visible,
    onClose,
    channelKey,
    onJumpToMessage,
    userId,
    username,
    roles,
    Attachment,
    LinkPreview,
    DirectVideo,
    onReactionClick,
    onProfilePopup,
    onImageClick,
}) => {
    const { crypto } = usePlatform();
    const [decryptedPins, setDecryptedPins] = useState([]);

    const pinnedMessages = useQuery(
        api.messages.listPinned,
        channelId ? { channelId, userId: userId || undefined } : "skip"
    ) || [];

    const unpinMutation = useMutation(api.messages.pin);

    useEffect(() => {
        if (!pinnedMessages.length || !channelKey) {
            setDecryptedPins([]);
            return;
        }

        let cancelled = false;

        const decryptAll = async () => {
            // Build batch arrays for message decryption
            const decryptItems = [];
            const decryptMsgMap = [];
            const replyDecryptItems = [];
            const replyMsgMap = [];
            const verifyItems = [];
            const verifyMsgMap = [];

            for (const msg of pinnedMessages) {
                if (msg.ciphertext && msg.ciphertext.length >= TAG_LENGTH) {
                    const tag = msg.ciphertext.slice(-TAG_LENGTH);
                    const content = msg.ciphertext.slice(0, -TAG_LENGTH);
                    decryptItems.push({ ciphertext: content, key: channelKey, iv: msg.nonce, tag });
                    decryptMsgMap.push(msg);
                }

                if (msg.replyToContent && msg.replyToNonce) {
                    const rTag = msg.replyToContent.slice(-TAG_LENGTH);
                    const rContent = msg.replyToContent.slice(0, -TAG_LENGTH);
                    replyDecryptItems.push({ ciphertext: rContent, key: channelKey, iv: msg.replyToNonce, tag: rTag });
                    replyMsgMap.push(msg);
                }

                if (msg.signature && msg.public_signing_key) {
                    verifyItems.push({ publicKey: msg.public_signing_key, message: msg.ciphertext, signature: msg.signature });
                    verifyMsgMap.push(msg);
                }
            }

            const [decryptResults, replyResults, verifyResults] = await Promise.all([
                decryptItems.length > 0 ? crypto.decryptBatch(decryptItems) : [],
                replyDecryptItems.length > 0 ? crypto.decryptBatch(replyDecryptItems) : [],
                verifyItems.length > 0 ? crypto.verifyBatch(verifyItems) : [],
            ]);

            if (cancelled) return;

            const decryptedMap = new Map();
            for (let i = 0; i < decryptResults.length; i++) {
                const msg = decryptMsgMap[i];
                const result = decryptResults[i];
                decryptedMap.set(msg.id, result.success ? result.data : '[Decryption Error]');
            }

            const replyMap = new Map();
            for (let i = 0; i < replyResults.length; i++) {
                const msg = replyMsgMap[i];
                const result = replyResults[i];
                if (result.success) {
                    let text = result.data;
                    if (text.startsWith('{')) text = '[Attachment]';
                    else if (text.length > 100) text = text.substring(0, 100) + '...';
                    replyMap.set(msg.id, text);
                } else {
                    replyMap.set(msg.id, '[Encrypted]');
                }
            }

            const verifyMap = new Map();
            for (let i = 0; i < verifyResults.length; i++) {
                const msg = verifyMsgMap[i];
                verifyMap.set(msg.id, verifyResults[i].success && verifyResults[i].verified);
            }

            const results = pinnedMessages.map(msg => ({
                ...msg,
                content: decryptedMap.get(msg.id) ?? '[Encrypted Message]',
                isVerified: verifyMap.get(msg.id) ?? false,
                decryptedReply: replyMap.get(msg.id) ?? null,
            }));

            if (!cancelled) setDecryptedPins(results);
        };

        decryptAll();
        return () => { cancelled = true; };
    }, [pinnedMessages, channelKey]);

    if (!visible) return null;

    const noop = () => {};

    return (
        <div className="pinned-panel">
            <div className="pinned-panel-header">
                <h3>Pinned Messages</h3>
                <button className="pinned-panel-close" onClick={onClose}>&times;</button>
            </div>
            <div className="pinned-panel-content">
                {decryptedPins.length === 0 ? (
                    <div className="pinned-panel-empty">
                        No pinned messages in this channel yet.
                    </div>
                ) : (
                    decryptedPins.map(msg => {
                        const isOwner = msg.username === username;
                        return (
                            <div key={msg.id} className="pinned-message-card">
                                <MessageItem
                                    msg={msg}
                                    isGrouped={false}
                                    showDateDivider={false}
                                    showUnreadDivider={false}
                                    dateLabel=""
                                    isMentioned={false}
                                    isOwner={isOwner}
                                    isEditing={false}
                                    isHovered={false}
                                    editInput=""
                                    username={username}
                                    roles={roles}
                                    onHover={noop}
                                    onLeave={noop}
                                    onContextMenu={(e) => e.preventDefault()}
                                    onAddReaction={noop}
                                    onEdit={noop}
                                    onReply={noop}
                                    onMore={noop}
                                    onEditInputChange={noop}
                                    onEditKeyDown={noop}
                                    onEditSave={noop}
                                    onEditCancel={noop}
                                    onReactionClick={onReactionClick}
                                    onScrollToMessage={onJumpToMessage}
                                    onProfilePopup={onProfilePopup}
                                    onImageClick={onImageClick}
                                    scrollToBottom={noop}
                                    Attachment={Attachment}
                                    LinkPreview={LinkPreview}
                                    DirectVideo={DirectVideo}
                                />
                                <div className="pinned-message-actions">
                                    <button
                                        className="pinned-action-btn"
                                        onClick={() => onJumpToMessage && onJumpToMessage(msg.id)}
                                    >
                                        Jump
                                    </button>
                                    <button
                                        className="pinned-action-btn pinned-action-danger"
                                        onClick={() => unpinMutation({ id: msg.id, pinned: false })}
                                    >
                                        Unpin
                                    </button>
                                </div>
                            </div>
                        );
                    })
                )}
            </div>
        </div>
    );
};

export default PinnedMessagesPanel;
