'use client'

import { useMutation, useQuery } from '@apollo/client'
import { Send, FileText, MessageCircle } from 'lucide-react'
import { useState, useRef, useEffect, useMemo } from 'react'

import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { EmojiPickerComponent } from '@/components/ui/emoji-picker'
import { FileMessage } from '@/components/ui/file-message'
import { FileUploader } from '@/components/ui/file-uploader'
import { ImageMessage } from '@/components/ui/image-message'
import { VoicePlayer } from '@/components/ui/voice-player'
import { VoiceRecorder } from '@/components/ui/voice-recorder'
import {
  SEND_MESSAGE,
  SEND_VOICE_MESSAGE,
  SEND_IMAGE_MESSAGE,
  SEND_FILE_MESSAGE,
  MARK_MESSAGES_AS_READ,
} from '@/graphql/mutations'
import { GET_MESSAGES, GET_CONVERSATIONS } from '@/graphql/queries'
import { useAuthContext } from '@/contexts/AuthContext'
import { useRealtime } from '@/hooks/useRealtime'

import { MessengerAttachments } from './messenger-attachments'

interface Organization {
  id: string
  inn: string
  name?: string
  fullName?: string
  type: 'FULFILLMENT' | 'SELLER' | 'LOGIST' | 'WHOLESALE'
  address?: string
  phones?: Array<{ value: string }>
  emails?: Array<{ value: string }>
  users?: Array<{ id: string; avatar?: string; managerName?: string }>
  createdAt: string
}

interface Message {
  id: string
  content?: string
  type?: 'TEXT' | 'VOICE' | 'IMAGE' | 'FILE' | null
  voiceUrl?: string
  voiceDuration?: number
  fileUrl?: string
  fileName?: string
  fileSize?: number
  fileType?: string
  senderId: string
  senderOrganization: Organization
  receiverOrganization: Organization
  createdAt: string
  isRead: boolean
}

interface MessengerChatProps {
  counterparty: Organization
  onMessagesRead?: () => void
}

export function MessengerChat({ counterparty, onMessagesRead }: MessengerChatProps) {
  const { user } = useAuthContext()
  const [message, setMessage] = useState('')
  const [currentView, setCurrentView] = useState<'chat' | 'attachments'>('chat')
  const messagesEndRef = useRef<HTMLDivElement>(null)
  const messageInputRef = useRef<HTMLTextAreaElement>(null)

  // Загружаем сообщения с контрагентом
  const { data: messagesData, loading, refetch } = useQuery(GET_MESSAGES, {
    variables: { counterpartyId: counterparty.id },
    fetchPolicy: 'cache-and-network',
    errorPolicy: 'all',
  })

  // Мутация для отметки сообщений как прочитанных
  const [markMessagesAsReadMutation] = useMutation(MARK_MESSAGES_AS_READ, {
    onCompleted: () => {
      setTimeout(() => {
        onMessagesRead?.()
      }, 500)
    },
    onError: (error) => {
      console.error('Ошибка отметки сообщений как прочитанных:', error)
    },
  })

  const [sendMessageMutation] = useMutation(SEND_MESSAGE, {
    onCompleted: () => {
      refetch()
    },
  })

  const [sendVoiceMessageMutation] = useMutation(SEND_VOICE_MESSAGE, {
    onCompleted: () => {
      refetch()
    },
    refetchQueries: [{ query: GET_MESSAGES, variables: { counterpartyId: counterparty.id, limit: 1000 } }],
  })

  const [sendImageMessageMutation] = useMutation(SEND_IMAGE_MESSAGE, {
    onCompleted: () => {
      refetch()
    },
    refetchQueries: [{ query: GET_MESSAGES, variables: { counterpartyId: counterparty.id, limit: 1000 } }],
  })

  const [sendFileMessageMutation] = useMutation(SEND_FILE_MESSAGE, {
    onCompleted: () => {
      refetch()
    },
    refetchQueries: [{ query: GET_MESSAGES, variables: { counterpartyId: counterparty.id, limit: 1000 } }],
  })

  const messages = useMemo(() => messagesData?.messages || [], [messagesData?.messages])

  // Реалтайм: обновляем чат при поступлении новых сообщений
  useRealtime({
    onEvent: (evt) => {
      if (evt.type !== 'message:new') return
      const { senderOrgId, receiverOrgId } = (evt.payload || {}) as {
        senderOrgId?: string
        receiverOrgId?: string
      }
      if (!user?.organization?.id) return
      // Refetch if event is for this conversation
      if (
        senderOrgId === counterparty.id ||
        receiverOrgId === counterparty.id ||
        senderOrgId === user.organization.id ||
        receiverOrgId === user.organization.id
      ) {
        refetch()
      }
    },
  })

  // Отмечаем сообщения как прочитанные только если есть непрочитанные
  useEffect(() => {
    if (messages.length > 0 && user?.organization?.id && counterparty.id) {
      const hasUnreadMessages = messages.some(
        (msg: Message) => !msg.isRead && msg.senderOrganization?.id === counterparty.id,
      )

      if (hasUnreadMessages) {
        const conversationId = `${user.organization.id}-${counterparty.id}`
        markMessagesAsReadMutation({
          variables: { conversationId },
        })
      }
    }
  }, [messages, counterparty.id, user?.organization?.id, markMessagesAsReadMutation])

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })
  }

  useEffect(() => {
    scrollToBottom()
  }, [messages])

  // Автофокус на поле ввода при открытии чата
  useEffect(() => {
    if (currentView === 'chat') {
      const timer = setTimeout(() => {
        messageInputRef.current?.focus()
      }, 100)
      return () => clearTimeout(timer)
    }
  }, [counterparty.id, currentView])

  const getOrganizationName = (org: Organization) => {
    return org.name || org.fullName || 'Организация'
  }

  const getShortCompanyName = (fullName: string) => {
    if (!fullName) return 'Полное название не указано'

    const legalFormReplacements: { [key: string]: string } = {
      'Общество с ограниченной ответственностью': 'ООО',
      'Открытое акционерное общество': 'ОАО',
      'Закрытое акционерное общество': 'ЗАО',
      'Публичное акционерное общество': 'ПАО',
      'Непубличное акционерное общество': 'НАО',
      'Акционерное общество': 'АО',
      'Индивидуальный предприниматель': 'ИП',
      'Товарищество с ограниченной ответственностью': 'ТОО',
      'Частное предприятие': 'ЧП',
      'Субъект предпринимательской деятельности': 'СПД',
    }

    let result = fullName

    for (const [fullForm, shortForm] of Object.entries(legalFormReplacements)) {
      const regex = new RegExp(`^${fullForm}\\s+`, 'i')
      if (regex.test(result)) {
        result = result.replace(regex, `${shortForm} `)
        break
      }
    }

    return result
  }

  const getTypeLabel = (type: string) => {
    switch (type) {
      case 'FULFILLMENT':
        return 'Фулфилмент'
      case 'SELLER':
        return 'Селлер'
      case 'LOGIST':
        return 'Логистика'
      case 'WHOLESALE':
        return 'Поставщик'
      default:
        return type
    }
  }

  const getTypeColor = (type: string) => {
    switch (type) {
      case 'FULFILLMENT':
        return 'bg-blue-500/20 text-blue-300 border-blue-500/30'
      case 'SELLER':
        return 'bg-green-500/20 text-green-300 border-green-500/30'
      case 'LOGIST':
        return 'bg-orange-500/20 text-orange-300 border-orange-500/30'
      case 'WHOLESALE':
        return 'bg-purple-500/20 text-purple-300 border-purple-500/30'
      default:
        return 'bg-gray-500/20 text-gray-300 border-gray-500/30'
    }
  }

  const getInitials = (org: Organization) => {
    const name = getOrganizationName(org)
    return name.charAt(0).toUpperCase()
  }

  const handleSendMessage = async () => {
    if (!message.trim()) return

    try {
      await sendMessageMutation({
        variables: {
          receiverOrganizationId: counterparty.id,
          content: message.trim(),
        },
      })
      setMessage('')
    } catch (error) {
      console.error('Ошибка отправки сообщения:', error)
    }
  }

  const handleKeyPress = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault()
      handleSendMessage()
    }
  }

  const handleEmojiSelect = (emoji: string) => {
    setMessage((prev) => prev + emoji)
  }

  const handleSendVoice = async (audioUrl: string, duration: number) => {
    try {
      await sendVoiceMessageMutation({
        variables: {
          receiverOrganizationId: counterparty.id,
          voiceUrl: audioUrl,
          voiceDuration: duration,
        },
      })
    } catch (error) {
      console.error('Ошибка отправки голосового сообщения:', error)
    }
  }

  const handleSendFile = async (
    fileUrl: string,
    fileName: string,
    fileSize: number,
    fileType: string,
    messageType: 'IMAGE' | 'FILE',
  ) => {
    try {
      if (messageType === 'IMAGE') {
        await sendImageMessageMutation({
          variables: {
            receiverOrganizationId: counterparty.id,
            fileUrl,
            fileName,
            fileSize,
            fileType,
          },
        })
      } else {
        await sendFileMessageMutation({
          variables: {
            receiverOrganizationId: counterparty.id,
            fileUrl,
            fileName,
            fileSize,
            fileType,
          },
        })
      }
    } catch (error) {
      console.error('Ошибка отправки файла:', error)
    }
  }

  const formatTime = (dateString: string) => {
    const date = new Date(dateString)
    if (isNaN(date.getTime())) {
      return '00:00'
    }
    return date.toLocaleTimeString('ru-RU', {
      hour: '2-digit',
      minute: '2-digit',
    })
  }

  const formatDate = (dateString: string) => {
    const date = new Date(dateString)
    if (isNaN(date.getTime())) {
      return 'Неизвестная дата'
    }

    const today = new Date()
    const yesterday = new Date(today)
    yesterday.setDate(yesterday.getDate() - 1)

    if (date.toDateString() === today.toDateString()) {
      return 'Сегодня'
    } else if (date.toDateString() === yesterday.toDateString()) {
      return 'Вчера'
    } else {
      return date.toLocaleDateString('ru-RU', {
        day: '2-digit',
        month: '2-digit',
        year: 'numeric',
      })
    }
  }

  return (
    <div className="flex flex-col h-full">
      {/* Заголовок чата */}
      <div className="flex items-center justify-between p-4 border-b border-white/10">
        <div className="flex items-center space-x-3">
          <Avatar className="h-10 w-10">
            {counterparty.users?.[0]?.avatar ? (
              <AvatarImage
                src={counterparty.users[0].avatar}
                alt="Аватар организации"
                className="w-full h-full object-cover"
              />
            ) : null}
            <AvatarFallback className="bg-purple-500 text-white text-sm">{getInitials(counterparty)}</AvatarFallback>
          </Avatar>
          <div>
            <div className="flex items-center space-x-2">
              <h3 className="font-semibold text-white">{getOrganizationName(counterparty)}</h3>
              <Badge className={`${getTypeColor(counterparty.type)} text-xs`}>{getTypeLabel(counterparty.type)}</Badge>
            </div>
            <p className="text-white/60 text-xs">{getShortCompanyName(counterparty.fullName || '')}</p>
          </div>
        </div>

        {/* Переключатель между чатом и вложениями */}
        <div className="flex items-center space-x-2">
          <Button
            variant={currentView === 'chat' ? 'secondary' : 'ghost'}
            size="sm"
            onClick={() => setCurrentView('chat')}
            className="text-xs"
          >
            <MessageCircle className="h-4 w-4 mr-1" />
            Чат
          </Button>
          <Button
            variant={currentView === 'attachments' ? 'secondary' : 'ghost'}
            size="sm"
            onClick={() => setCurrentView('attachments')}
            className="text-xs"
          >
            <FileText className="h-4 w-4 mr-1" />
            Вложения
          </Button>
        </div>
      </div>

      {/* Основное содержимое */}
      {currentView === 'chat' ? (
        <>
          {/* Сообщения */}
          <div className="flex-1 overflow-y-auto p-4 space-y-4">
            {loading ? (
              <div className="flex items-center justify-center h-32">
                <div className="text-white/60">Загрузка сообщений...</div>
              </div>
            ) : messages.length === 0 ? (
              <div className="flex items-center justify-center h-32">
                <div className="text-center">
                  <div className="w-16 h-16 bg-white/10 rounded-full flex items-center justify-center mx-auto mb-4">
                    <MessageCircle className="h-8 w-8 text-white/40" />
                  </div>
                  <p className="text-white/60 text-lg mb-2">Пока нет сообщений</p>
                  <p className="text-white/40 text-sm">Начните беседу с {getOrganizationName(counterparty)}</p>
                </div>
              </div>
            ) : (
              messages.map((msg: Message, index: number) => {
                const isCurrentUser = msg.senderOrganization?.id === user?.organization?.id
                const showDate = index === 0 || formatDate(messages[index - 1].createdAt) !== formatDate(msg.createdAt)

                return (
                  <div key={msg.id}>
                    {showDate && (
                      <div className="flex justify-center mb-4">
                        <div className="bg-white/10 rounded-full px-3 py-1">
                          <span className="text-white/60 text-xs">{formatDate(msg.createdAt)}</span>
                        </div>
                      </div>
                    )}

                    <div className={`flex ${isCurrentUser ? 'justify-end' : 'justify-start'} mb-3`}>
                      <div className={`max-w-xs lg:max-w-md xl:max-w-lg ${isCurrentUser ? 'mr-2' : 'ml-2'}`}>
                        <div className="space-y-2">
                          {msg.type === 'VOICE' && msg.voiceUrl ? (
                            <VoicePlayer
                              audioUrl={msg.voiceUrl}
                              duration={msg.voiceDuration || 0}
                              isCurrentUser={isCurrentUser}
                            />
                          ) : msg.type === 'IMAGE' && msg.fileUrl ? (
                            <ImageMessage
                              imageUrl={msg.fileUrl}
                              fileName={msg.fileName || 'image'}
                              fileSize={msg.fileSize}
                              isCurrentUser={isCurrentUser}
                            />
                          ) : msg.type === 'FILE' && msg.fileUrl ? (
                            <FileMessage
                              fileUrl={msg.fileUrl}
                              fileName={msg.fileName || 'file'}
                              fileSize={msg.fileSize}
                              fileType={msg.fileType}
                              isCurrentUser={isCurrentUser}
                            />
                          ) : msg.content ? (
                            <div
                              className={`px-4 py-2 rounded-lg break-words ${
                                isCurrentUser
                                  ? 'bg-blue-500/20 text-white border border-blue-500/30'
                                  : 'bg-white/10 text-white border border-white/20'
                              }`}
                            >
                              <p className="text-sm leading-relaxed whitespace-pre-wrap break-words">{msg.content}</p>
                            </div>
                          ) : null}

                          <p className={`text-xs ${isCurrentUser ? 'text-blue-300/70' : 'text-white/50'}`}>
                            {formatTime(msg.createdAt)}
                          </p>
                        </div>
                      </div>
                    </div>
                  </div>
                )
              })
            )}
            <div ref={messagesEndRef} />
          </div>

          {/* Поле ввода сообщения */}
          <div className="px-4 py-3 border-t border-white/10">
            <div className="flex items-center space-x-2">
              <div className="flex-1">
                <textarea
                  ref={messageInputRef}
                  value={message}
                  onChange={(e) => setMessage(e.target.value)}
                  onKeyPress={handleKeyPress}
                  placeholder="Введите сообщение..."
                  className="glass-input text-white placeholder:text-white/40 w-full resize-none overflow-y-auto rounded-lg py-2 px-3"
                  rows={1}
                  onInput={(e) => {
                    const target = e.target as HTMLTextAreaElement
                    target.style.height = 'auto'
                    target.style.height = Math.min(target.scrollHeight, 120) + 'px'
                  }}
                />
              </div>

              <div className="flex items-center space-x-1">
                <EmojiPickerComponent onEmojiSelect={handleEmojiSelect} />
                <VoiceRecorder onSendVoice={handleSendVoice} />
                <FileUploader onSendFile={handleSendFile} />
                <Button
                  onClick={handleSendMessage}
                  disabled={!message.trim()}
                  size="icon"
                  className="bg-blue-500 hover:bg-blue-600 text-white"
                >
                  <Send className="h-4 w-4" />
                </Button>
              </div>
            </div>
          </div>
        </>
      ) : (
        /* Вложения */
        <div className="flex-1 overflow-hidden">
          <MessengerAttachments
            counterparty={counterparty}
            onViewChange={() => {
              // Принудительно обновляем сообщения при переходе на вложения
              refetch()
            }}
          />
        </div>
      )}
    </div>
  )
}
