'use client'

import { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react'
import type { Contact, Conversation, Message, MessageTemplate, MessagesStats, MessagesContextType } from './messages/types'
import { mockContacts, mockConversations, mockMessages, mockTemplates } from './messages/mock-data'

// Re-export types and helpers for backward compatibility
export type { Contact, Conversation, Message, MessageTemplate, MessagesStats } from './messages/types'
export { formatMessageTime, formatMessageDate, getContactInitials, getRoleLabel, getRoleColor, emojiCategories } from './messages/helpers'

const MessagesContext = createContext<MessagesContextType | null>(null)

export function MessagesProvider({ children }: { children: ReactNode }) {
  const [contacts, setContacts] = useState<Contact[]>(mockContacts)
  const [conversations, setConversations] = useState<Conversation[]>(mockConversations)
  const [messages, setMessages] = useState<Record<string, Message[]>>(mockMessages)
  const [templates] = useState<MessageTemplate[]>(mockTemplates)
  const [stats] = useState<MessagesStats>({
    total_contacts: mockContacts.length,
    total_conversations: mockConversations.length,
    total_messages: Object.values(mockMessages).flat().length,
    unread_messages: mockConversations.reduce((sum, c) => sum + c.unread_count, 0)
  })
  const [isLoading] = useState(false)
  const [error] = useState<string | null>(null)
  const [currentConversationId, setCurrentConversationId] = useState<string | null>(null)
  const [mounted, setMounted] = useState(false)

  useEffect(() => { setMounted(true) }, [])

  const unreadCount = conversations.reduce((sum, c) => sum + c.unread_count, 0)

  const recentConversations = [...conversations].sort((a, b) => {
    if (a.pinned && !b.pinned) return -1
    if (!a.pinned && b.pinned) return 1
    const aTime = a.last_message_time ? new Date(a.last_message_time).getTime() : 0
    const bTime = b.last_message_time ? new Date(b.last_message_time).getTime() : 0
    return bTime - aTime
  })

  const fetchContacts = useCallback(async () => { setContacts(mockContacts) }, [])
  const fetchConversations = useCallback(async () => { setConversations(mockConversations) }, [])
  const fetchMessages = useCallback(async (conversationId: string): Promise<Message[]> => {
    return messages[conversationId] || []
  }, [messages])

  const sendMessage = useCallback(async (
    conversationId: string, content: string, sendEmail = false, replyTo?: string
  ): Promise<Message | null> => {
    const newMsg: Message = {
      id: `msg_${Date.now()}`, conversation_id: conversationId, sender_id: 'self',
      content, content_type: 'text', timestamp: new Date().toISOString(),
      read: true, delivered: true, send_email: sendEmail, email_sent: sendEmail, reply_to: replyTo
    }
    setMessages(prev => ({ ...prev, [conversationId]: [...(prev[conversationId] || []), newMsg] }))
    setConversations(prev => prev.map(c =>
      c.id === conversationId
        ? { ...c, last_message: content.length > 50 ? content.slice(0, 50) + '...' : content,
            last_message_time: newMsg.timestamp, updated_at: newMsg.timestamp }
        : c
    ))
    return newMsg
  }, [])

  const markAsRead = useCallback(async (conversationId: string) => {
    setMessages(prev => ({ ...prev, [conversationId]: (prev[conversationId] || []).map(m => ({ ...m, read: true })) }))
    setConversations(prev => prev.map(c => c.id === conversationId ? { ...c, unread_count: 0 } : c))
  }, [])

  const createConversation = useCallback(async (contactId: string): Promise<Conversation | null> => {
    const existing = conversations.find(c => !c.is_group && c.participant_ids.includes(contactId))
    if (existing) return existing
    const contact = contacts.find(c => c.id === contactId)
    const newConv: Conversation = {
      id: `conv_${Date.now()}`, participant_ids: [contactId],
      created_at: new Date().toISOString(), updated_at: new Date().toISOString(),
      unread_count: 0, is_group: false, title: contact?.name || 'Neue Konversation'
    }
    setConversations(prev => [newConv, ...prev])
    setMessages(prev => ({ ...prev, [newConv.id]: [] }))
    return newConv
  }, [conversations, contacts])

  const addReaction = useCallback((messageId: string, emoji: string) => {
    setMessages(prev => {
      const newMessages = { ...prev }
      for (const convId of Object.keys(newMessages)) {
        newMessages[convId] = newMessages[convId].map(msg => {
          if (msg.id !== messageId) return msg
          const reactions = [...(msg.reactions || [])]
          const existingIndex = reactions.findIndex(r => r.user_id === 'self')
          if (existingIndex >= 0) {
            if (reactions[existingIndex].emoji === emoji) { reactions.splice(existingIndex, 1) }
            else { reactions[existingIndex] = { ...reactions[existingIndex], emoji } }
          } else { reactions.push({ emoji, user_id: 'self' }) }
          return { ...msg, reactions }
        })
      }
      return newMessages
    })
  }, [])

  const deleteMessage = useCallback((conversationId: string, messageId: string) => {
    setMessages(prev => ({ ...prev, [conversationId]: (prev[conversationId] || []).filter(m => m.id !== messageId) }))
  }, [])

  const pinConversation = useCallback((conversationId: string) => {
    setConversations(prev => prev.map(c => c.id === conversationId ? { ...c, pinned: !c.pinned } : c))
  }, [])

  const muteConversation = useCallback((conversationId: string) => {
    setConversations(prev => prev.map(c => c.id === conversationId ? { ...c, muted: !c.muted } : c))
  }, [])

  const value: MessagesContextType = {
    contacts: mounted ? contacts : [], conversations: mounted ? conversations : [],
    messages: mounted ? messages : {}, templates: mounted ? templates : [],
    stats: mounted ? stats : { total_contacts: 0, total_conversations: 0, total_messages: 0, unread_messages: 0 },
    unreadCount: mounted ? unreadCount : 0,
    recentConversations: mounted ? recentConversations : [],
    fetchContacts, fetchConversations, fetchMessages, sendMessage, markAsRead,
    createConversation, addReaction, deleteMessage, pinConversation, muteConversation,
    isLoading, error, currentConversationId,
    setCurrentConversationId: mounted ? setCurrentConversationId : () => {}
  }

  return <MessagesContext.Provider value={value}>{children}</MessagesContext.Provider>
}

export function useMessages() {
  const context = useContext(MessagesContext)
  if (!context) {
    throw new Error('useMessages must be used within a MessagesProvider')
  }
  return context
}
