// noqa: js-006 - async init pattern is safe, loadData has try/catch
/**
 * Admin Messages Page
 *
 * Handles the messaging interface including:
 * - Conversation list with filtering and pagination
 * - Message thread display
 * - Sending messages with attachments
 * - Creating new conversations
 */

const messagesLog = window.LogConfig?.createLogger('MESSAGES') || console;

/**
 * Admin Messages Component
 */
function adminMessages(initialConversationId = null) {
    return {
        ...data(),
        currentPage: 'messages',

        // Loading states
        loading: true,
        error: null,
        loadingConversations: false,
        loadingMessages: false,
        sendingMessage: false,
        creatingConversation: false,

        // Conversations state
        conversations: [],
        page: 1,
        skip: 0,
        limit: 20,
        totalConversations: 0,
        totalUnread: 0,

        // Filters
        filters: {
            conversation_type: '',
            is_closed: ''
        },

        // Selected conversation
        selectedConversationId: initialConversationId,
        selectedConversation: null,

        // Reply form
        replyContent: '',
        attachedFiles: [],

        // Close conversation confirm state
        showCloseConversationConfirm: false,

        // Compose modal
        showComposeModal: false,
        compose: {
            recipientType: '',
            recipientId: null,
            subject: '',
            message: ''
        },
        recipients: [],
        loadingRecipients: false,

        // Polling
        pollInterval: null,

        /**
         * Initialize component
         */
        async init() {
            // Load i18n translations
            await I18n.loadModule('messaging');

            // Guard against multiple initialization
            if (window._adminMessagesInitialized) return;
            window._adminMessagesInitialized = true;

            try {
                messagesLog.debug('Initializing messages page');
                await this.loadConversations();

                if (this.selectedConversationId) {
                    await this.loadConversation(this.selectedConversationId);
                }

                // Start polling for new messages
                this.startPolling();
            } catch (error) {
                messagesLog.error('Failed to initialize messages page:', error);
            } finally {
                this.loading = false;
            }
        },

        /**
         * Start polling for updates
         */
        startPolling() {
            this.pollInterval = setInterval(async () => {
                // Only poll if we have a selected conversation
                if (this.selectedConversationId && !document.hidden) {
                    await this.refreshCurrentConversation();
                }
                // Update unread count
                await this.updateUnreadCount();
            }, 30000); // 30 seconds
        },

        /**
         * Stop polling
         */
        destroy() {
            if (this.pollInterval) {
                clearInterval(this.pollInterval);
            }
        },

        // ============================================================================
        // CONVERSATIONS LIST
        // ============================================================================

        /**
         * Load conversations with current filters
         */
        async loadConversations() {
            this.loadingConversations = true;
            try {
                this.skip = (this.page - 1) * this.limit;
                const params = new URLSearchParams();
                params.append('skip', this.skip);
                params.append('limit', this.limit);

                if (this.filters.conversation_type) {
                    params.append('conversation_type', this.filters.conversation_type);
                }
                if (this.filters.is_closed !== '') {
                    params.append('is_closed', this.filters.is_closed);
                }

                const response = await apiClient.get(`/admin/messages?${params}`);
                this.conversations = response.conversations || [];
                this.totalConversations = response.total || 0;
                this.totalUnread = response.total_unread || 0;

                messagesLog.debug(`Loaded ${this.conversations.length} conversations`);
            } catch (error) {
                messagesLog.error('Failed to load conversations:', error);
                Utils.showToast(I18n.t('messaging.messages.failed_to_load_conversations'), 'error');
            } finally {
                this.loadingConversations = false;
            }
        },

        /**
         * Update unread count
         */
        async updateUnreadCount() {
            try {
                const response = await apiClient.get('/admin/messages/unread-count');
                this.totalUnread = response.total_unread || 0;
            } catch (error) {
                messagesLog.error('Failed to update unread count:', error);
            }
        },

        /**
         * Select a conversation
         */
        async selectConversation(conversationId) {
            if (this.selectedConversationId === conversationId) return;

            this.selectedConversationId = conversationId;
            await this.loadConversation(conversationId);

            // Update URL without reload
            const url = new URL(window.location);
            url.pathname = `/admin/messages/${conversationId}`;
            window.history.pushState({}, '', url);
        },

        /**
         * Load conversation detail
         */
        async loadConversation(conversationId) {
            this.loadingMessages = true;
            try {
                const response = await apiClient.get(`/admin/messages/${conversationId}?mark_read=true`);
                this.selectedConversation = response;

                // Update unread count in list
                const conv = this.conversations.find(c => c.id === conversationId);
                if (conv) {
                    this.totalUnread = Math.max(0, this.totalUnread - conv.unread_count);
                    conv.unread_count = 0;
                }

                messagesLog.debug(`Loaded conversation ${conversationId} with ${response.messages?.length || 0} messages`);

                // Scroll to bottom
                await this.$nextTick();
                this.scrollToBottom();
            } catch (error) {
                messagesLog.error('Failed to load conversation:', error);
                Utils.showToast(I18n.t('messaging.messages.failed_to_load_conversation'), 'error');
            } finally {
                this.loadingMessages = false;
            }
        },

        /**
         * Refresh current conversation
         */
        async refreshCurrentConversation() {
            if (!this.selectedConversationId) return;

            try {
                const response = await apiClient.get(`/admin/messages/${this.selectedConversationId}?mark_read=true`);
                const oldCount = this.selectedConversation?.messages?.length || 0;
                const newCount = response.messages?.length || 0;

                this.selectedConversation = response;

                // If new messages, scroll to bottom
                if (newCount > oldCount) {
                    await this.$nextTick();
                    this.scrollToBottom();
                }
            } catch (error) {
                messagesLog.error('Failed to refresh conversation:', error);
            }
        },

        /**
         * Scroll messages to bottom
         */
        scrollToBottom() {
            const container = this.$refs.messagesContainer;
            if (container) {
                container.scrollTop = container.scrollHeight;
            }
        },

        // ============================================================================
        // SENDING MESSAGES
        // ============================================================================

        /**
         * Handle file selection
         */
        handleFileSelect(event) {
            const files = Array.from(event.target.files);
            this.attachedFiles = files;
            messagesLog.debug(`Selected ${files.length} files`);
        },

        /**
         * Send a message
         */
        async sendMessage() {
            if (!this.replyContent.trim() && this.attachedFiles.length === 0) return;
            if (!this.selectedConversationId) return;

            this.sendingMessage = true;
            try {
                const formData = new FormData();
                formData.append('content', this.replyContent);

                for (const file of this.attachedFiles) {
                    formData.append('files', file);
                }

                const message = await apiClient.postFormData(`/admin/messages/${this.selectedConversationId}/messages`, formData);

                // Add to messages
                if (this.selectedConversation) {
                    this.selectedConversation.messages.push(message);
                    this.selectedConversation.message_count++;
                }

                // Clear form
                this.replyContent = '';
                this.attachedFiles = [];
                if (this.$refs.fileInput) {
                    this.$refs.fileInput.value = '';
                }

                // Scroll to bottom
                await this.$nextTick();
                this.scrollToBottom();

                messagesLog.debug(`Sent message ${message.id}`);
            } catch (error) {
                messagesLog.error('Failed to send message:', error);
                Utils.showToast(error.message || 'Failed to send message', 'error');
            } finally {
                this.sendingMessage = false;
            }
        },

        // ============================================================================
        // CONVERSATION ACTIONS
        // ============================================================================

        /**
         * Close conversation
         */
        async closeConversation() {
            try {
                await apiClient.post(`/admin/messages/${this.selectedConversationId}/close`);

                if (this.selectedConversation) {
                    this.selectedConversation.is_closed = true;
                }

                // Update in list
                const conv = this.conversations.find(c => c.id === this.selectedConversationId);
                if (conv) {
                    conv.is_closed = true;
                }

                Utils.showToast(I18n.t('messaging.messages.conversation_closed'), 'success');
            } catch (error) {
                messagesLog.error('Failed to close conversation:', error);
                Utils.showToast(I18n.t('messaging.messages.failed_to_close_conversation'), 'error');
            }
        },

        /**
         * Reopen conversation
         */
        async reopenConversation() {
            try {
                await apiClient.post(`/admin/messages/${this.selectedConversationId}/reopen`);

                if (this.selectedConversation) {
                    this.selectedConversation.is_closed = false;
                }

                // Update in list
                const conv = this.conversations.find(c => c.id === this.selectedConversationId);
                if (conv) {
                    conv.is_closed = false;
                }

                Utils.showToast(I18n.t('messaging.messages.conversation_reopened'), 'success');
            } catch (error) {
                messagesLog.error('Failed to reopen conversation:', error);
                Utils.showToast(I18n.t('messaging.messages.failed_to_reopen_conversation'), 'error');
            }
        },

        // ============================================================================
        // CREATE CONVERSATION
        // ============================================================================

        /**
         * Load recipients for compose modal
         */
        async loadRecipients() {
            if (!this.compose.recipientType) {
                this.recipients = [];
                return;
            }

            this.loadingRecipients = true;
            try {
                const response = await apiClient.get(`/admin/messages/recipients?recipient_type=${this.compose.recipientType}&limit=100`);
                this.recipients = response.recipients || [];
                messagesLog.debug(`Loaded ${this.recipients.length} recipients`);
            } catch (error) {
                messagesLog.error('Failed to load recipients:', error);
                Utils.showToast(I18n.t('messaging.messages.failed_to_load_recipients'), 'error');
            } finally {
                this.loadingRecipients = false;
            }
        },

        /**
         * Create new conversation
         */
        async createConversation() {
            if (!this.compose.recipientId || !this.compose.subject.trim()) return;

            this.creatingConversation = true;
            try {
                // Determine conversation type
                const conversationType = this.compose.recipientType === 'store'
                    ? 'admin_store'
                    : 'admin_customer';

                // Get store_id if customer
                let storeId = null;
                if (this.compose.recipientType === 'customer') {
                    const recipient = this.recipients.find(r => r.id === parseInt(this.compose.recipientId));
                    storeId = recipient?.store_id;
                }

                const response = await apiClient.post('/admin/messages', {
                    conversation_type: conversationType,
                    subject: this.compose.subject,
                    recipient_type: this.compose.recipientType,
                    recipient_id: parseInt(this.compose.recipientId),
                    store_id: storeId,
                    initial_message: this.compose.message || null
                });

                // Close modal and reset
                this.showComposeModal = false;
                this.compose = {
                    recipientType: '',
                    recipientId: null,
                    subject: '',
                    message: ''
                };
                this.recipients = [];

                // Reload conversations and select new one
                await this.loadConversations();
                await this.selectConversation(response.id);

                Utils.showToast(I18n.t('messaging.messages.conversation_created'), 'success');
            } catch (error) {
                messagesLog.error('Failed to create conversation:', error);
                Utils.showToast(error.message || 'Failed to create conversation', 'error');
            } finally {
                this.creatingConversation = false;
            }
        },

        // ============================================================================
        // HELPERS
        // ============================================================================

        /**
         * Get other participant name
         */
        getOtherParticipantName() {
            if (!this.selectedConversation?.participants) return 'Unknown';

            const other = this.selectedConversation.participants.find(
                p => p.participant_type !== 'admin'
            );

            return other?.participant_info?.name || 'Unknown';
        },

        /**
         * Format relative time
         */
        formatRelativeTime(dateString) {
            if (!dateString) return '';

            const date = new Date(dateString);
            const now = new Date();
            const diff = Math.floor((now - date) / 1000);

            if (diff < 60) return 'Now';
            if (diff < 3600) return `${Math.floor(diff / 60)}m`;
            if (diff < 86400) return `${Math.floor(diff / 3600)}h`;
            if (diff < 172800) return 'Yesterday';
            if (diff < 604800) return `${Math.floor(diff / 86400)}d`;

            return date.toLocaleDateString();
        },

        /**
         * Format time for messages
         */
        formatTime(dateString) {
            if (!dateString) return '';

            const date = new Date(dateString);
            const now = new Date();
            const isToday = date.toDateString() === now.toDateString();

            if (isToday) {
                return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
            }

            return date.toLocaleString([], {
                month: 'short',
                day: 'numeric',
                hour: '2-digit',
                minute: '2-digit'
            });
        }
    };
}

// Make available globally
window.adminMessages = adminMessages;
