import React, { useState, useEffect, useRef, useCallback } from 'react';
import { formatTime } from '@/utils/date';
import { ResizablePanel } from '@/components/ui/ResizablePanel';
import { useUIStore } from '@/store/uiStore';
import { useCommStore } from '@/store/commStore';
import { useTranslation } from 'react-i18next';
import { useUsers, useGroups } from '@/api/hooks';
import { Avatar } from '@/components/ui/Avatar';
import {
  listConversations,
  getMessages,
  sendMessage,
  markRead,
  createConversation,
} from '@/api/comm';
import { useCommWebSocket } from '@/hooks/useCommWebSocket';
import type { Conversation, Message } from '@/store/commStore';
import { BlockRenderer } from '@/components/comm/blocks';
import { Bell, Bookmark, Bot, ChevronLeft, ChevronRight, Lightbulb, MessageSquare, Send, Users } from 'lucide-react';

// ─── Icons (identical to AISidebar) ───

const robotIcon = (className: string) => (
  <Bot className={className} aria-hidden="true" strokeWidth={2} />
);

const bellIcon = (className: string) => (
  <Bell className={className} aria-hidden="true" strokeWidth={2} />
);

const bulbIcon = (className: string) => (
  <Lightbulb className={className} aria-hidden="true" strokeWidth={2} />
);

const teamIcon = (className: string) => (
  <Users className={className} aria-hidden="true" strokeWidth={2} />
);

const chatBubbleIcon = (className: string) => (
  <MessageSquare className={className} aria-hidden="true" strokeWidth={2} />
);

const chevronRightIcon = (
  <ChevronRight className="w-4 h-4" aria-hidden="true" strokeWidth={2} />
);

const sendIcon = (
  <Send className="w-4 h-4" aria-hidden="true" strokeWidth={2} />
);

const pinIcon = (
  <Bookmark className="w-3.5 h-3.5" aria-hidden="true" strokeWidth={2} />
);

// ─── Types ───

type SidebarView = 'conversations' | 'team';

interface QuickAccessDef {
  key: string;
  label: string;
  icon: (cls: string) => React.ReactNode;
  testId: string;
  view: SidebarView;
  filterPinned?: string;
}

// ─── Team Panel (reused from AISidebar) ───

function TeamPanel({ onStartDirectChat }: { onStartDirectChat: (userId: string, userName: string) => void }) {
  const { data: usersData, isLoading: usersLoading } = useUsers();
  const { data: groupsData, isLoading: groupsLoading } = useGroups();
  const users: any[] = usersData?.items || [];
  const groups: any[] = groupsData?.items || [];

  return (
    <div className="flex flex-col h-full overflow-y-auto p-3 gap-3" data-testid="team-panel">
      <div>
        <h3 className="text-xs font-semibold text-secondary-500 uppercase tracking-wide mb-2">Mitarbeiter</h3>
        {usersLoading ? (
          <p className="text-sm text-secondary-400">Laden...</p>
        ) : users.length === 0 ? (
          <p className="text-sm text-secondary-400">Keine Mitarbeiter</p>
        ) : (
          <div className="space-y-1">
            {users.map((u) => (
              <button
                key={u.id}
                onClick={() => onStartDirectChat(u.id, u.name)}
                className="flex items-center gap-2 px-2 py-1.5 rounded-lg hover:bg-secondary-50 transition-colors w-full text-left"
              >
                <div className="relative flex-shrink-0">
                  <Avatar name={u.name} size="sm" />
                  <span className="absolute bottom-0 right-0 w-2.5 h-2.5 rounded-full border-2 border-white bg-secondary-300" aria-label="offline" />
                </div>
                <div className="flex-1 min-w-0">
                  <p className="text-sm font-medium text-secondary-700 truncate">{u.name}</p>
                  <p className="text-xs text-secondary-400 truncate">{u.email}</p>
                </div>
                <span className="text-xs text-secondary-400">{u.role}</span>
              </button>
            ))}
          </div>
        )}
      </div>
      <div>
        <h3 className="text-xs font-semibold text-secondary-500 uppercase tracking-wide mb-2">Gruppen</h3>
        {groupsLoading ? (
          <p className="text-sm text-secondary-400">Laden...</p>
        ) : groups.length === 0 ? (
          <p className="text-sm text-secondary-400">Keine Gruppen</p>
        ) : (
          <div className="space-y-1">
            {groups.map((g) => (
              <div key={g.id} className="flex items-center gap-2 px-2 py-1.5 rounded-lg hover:bg-secondary-50 transition-colors">
                <div className="w-8 h-8 rounded-full bg-secondary-200 flex items-center justify-center flex-shrink-0">
                  <Users className="w-4 h-4 text-secondary-500" aria-hidden="true" strokeWidth={2} />
                </div>
                <div className="flex-1 min-w-0">
                  <p className="text-sm font-medium text-secondary-700 truncate">{g.name}</p>
                  {g.description && <p className="text-xs text-secondary-400 truncate">{g.description}</p>}
                </div>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

// ─── Conversation List Item ───

function ConversationListItem({
  conv,
  isActive,
  onClick,
}: {
  conv: Conversation;
  isActive: boolean;
  onClick: () => void;
}) {
  const senderIcon =
    conv.last_msg_sender_type === 'ai' ? '🤖' : conv.last_msg_sender_type === 'system' ? '🔔' : '👤';

  return (
    <button
      onClick={onClick}
      className={`flex items-start gap-2 px-3 py-2 rounded-lg transition-colors w-full text-left ${
        isActive
          ? 'bg-primary-100 text-primary-700'
          : 'hover:bg-secondary-50 text-secondary-700'
      }`}
      data-testid={`conv-item-${conv.id}`}
    >
      <div className="flex-1 min-w-0">
        <div className="flex items-center gap-1">
          {conv.is_pinned && <span className="text-secondary-400 flex-shrink-0">📌</span>}
          <p className="text-sm font-medium truncate flex-1">
            {conv.title || 'Ohne Titel'}
          </p>
          {conv.unread_count > 0 && (
            <span className="flex-shrink-0 w-5 h-5 bg-danger-500 text-white text-[10px] font-bold rounded-full flex items-center justify-center">
              {conv.unread_count}
            </span>
          )}
        </div>
        {conv.last_msg_preview && (
          <p className="text-xs text-secondary-400 truncate mt-0.5">
            <span className="mr-1">{senderIcon}</span>
            {conv.last_msg_preview}
          </p>
        )}
      </div>
    </button>
  );
}

// ─── Message Feed ───

function MessageFeed({
  messages,
  loading,
}: {
  messages: Message[];
  loading: boolean;
}) {
  const scrollRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [messages]);

  if (loading) {
    return (
      <div className="flex items-center justify-center h-full text-sm text-secondary-400">
        Laden...
      </div>
    );
  }

  if (messages.length === 0) {
    return (
      <div className="flex items-center justify-center h-full text-sm text-secondary-400">
        Keine Nachrichten
      </div>
    );
  }

  return (
    <div ref={scrollRef} className="flex-1 overflow-y-auto p-3 space-y-2">
      {messages.map((msg) => {
        const isAI = msg.sender_type === 'ai';
        const isSystem = msg.sender_type === 'system';
        const senderIcon = isAI ? '🤖' : isSystem ? '🔔' : '👤';
        const senderName = isAI ? 'KI' : isSystem ? 'System' : 'Benutzer';

        return (
          <div
            key={msg.id}
            className={`flex flex-col ${msg.sender_type === 'user' ? 'items-end' : 'items-start'}`}
          >
            <div
              className={`max-w-[85%] rounded-lg px-3 py-2 ${
                msg.sender_type === 'user'
                  ? 'bg-primary-500 text-white'
                  : 'bg-secondary-100 text-secondary-800'
              }`}
            >
              <div className="flex items-center gap-1 mb-0.5">
                <span className="text-xs">{senderIcon}</span>
                <span className="text-xs font-medium opacity-70">{senderName}</span>
              </div>
              <div className="text-sm whitespace-pre-wrap break-words">{msg.content}</div>
              {/* Render rich content blocks via BlockRenderer */}
              {msg.blocks && msg.blocks.length > 0 && (
                <div className="mt-2">
                  <BlockRenderer blocks={msg.blocks} />
                </div>
              )}
              {msg.created_at && (
                <span className="text-[10px] opacity-50 mt-0.5 block">
                  {formatTime(msg.created_at)}
                </span>
              )}
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ─── Message Input ───

function MessageInput({
  onSend,
  disabled,
}: {
  onSend: (text: string) => void;
  disabled: boolean;
}) {
  const [text, setText] = useState('');

  const handleSend = () => {
    if (!text.trim() || disabled) return;
    onSend(text.trim());
    setText('');
  };

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

  return (
    <div className="flex items-center gap-2 p-3 border-t border-secondary-200">
      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
        onKeyDown={handleKeyDown}
        disabled={disabled}
        placeholder={disabled ? 'Schreibgeschützt' : 'Nachricht eingeben...'}
        className="flex-1 px-3 py-2 text-sm rounded-lg border border-secondary-200 bg-white text-secondary-800 placeholder-secondary-400 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent disabled:bg-secondary-50 disabled:text-secondary-400"
        data-testid="message-input"
      />
      <button
        onClick={handleSend}
        disabled={disabled || !text.trim()}
        className="p-2 rounded-lg bg-primary-500 text-white hover:bg-primary-600 disabled:bg-secondary-200 disabled:text-secondary-400 transition-colors min-h-touch min-w-touch flex items-center justify-center"
        aria-label="Senden"
        data-testid="message-send-btn"
      >
        {sendIcon}
      </button>
    </div>
  );
}

// ─── Main MessageSidebar Component ───

export function MessageSidebar() {
  const { t } = useTranslation();
  const {
    messageSidebarCollapsed,
    toggleMessageSidebar,
  } = useUIStore();

  const {
    conversations,
    activeConversationId,
    messages,
    loading,
    setConversations,
    setActiveConversation,
    setMessages,
    setLoading,
    setUnread,
  } = useCommStore();

  const [currentView, setCurrentView] = useState<SidebarView>('conversations');
  const [messagesLoading, setMessagesLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Connect WebSocket
  useCommWebSocket();

  // Load conversations on mount
  useEffect(() => {
    loadConversations();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const loadConversations = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const res = await listConversations();
      const convs = res.items || [];
      setConversations(convs);
      // Auto-select first pinned conversation or first conversation
      if (convs.length > 0 && !activeConversationId) {
        const pinned = convs.find((c) => c.is_pinned);
        const first = pinned || convs[0];
        setActiveConversation(first.id);
        loadMessages(first.id);
      }
    } catch (e) {
      console.error('Failed to load conversations:', e);
      setError('Konversationen konnten nicht geladen werden');
    } finally {
      setLoading(false);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const loadMessages = useCallback(async (convId: string) => {
    setMessagesLoading(true);
    try {
      const res = await getMessages(convId);
      setMessages(convId, res.items || []);
      // Mark as read
      await markRead(convId);
      setUnread(convId, 0);
    } catch (e) {
      console.error('Failed to load messages:', e);
      setMessages(convId, []);
    } finally {
      setMessagesLoading(false);
    }
  }, []);

  const handleSelectConversation = useCallback(
    (convId: string) => {
      setActiveConversation(convId);
      loadMessages(convId);
    },
    [loadMessages],
  );

  const handleSendMessage = useCallback(
    async (text: string) => {
      if (!activeConversationId) return;
      try {
        await sendMessage(activeConversationId, {
          content: text,
          content_format: 'text',
        });
        // The message will arrive via WebSocket, but also reload to be safe
        loadMessages(activeConversationId);
      } catch (e) {
        console.error('Failed to send message:', e);
        setError('Nachricht konnte nicht gesendet werden');
      }
    },
    [activeConversationId, loadMessages],
  );

  const handleStartDirectChat = useCallback(
    async (userId: string, userName: string) => {
      try {
        const conv = await createConversation({
          title: userName,
          participant_ids: [userId],
          is_direct: true,
        });
        // Reload conversations to include the new one
        await loadConversations();
        if (conv && conv.id) {
          handleSelectConversation(conv.id);
        }
      } catch (e) {
        console.error('Failed to start direct chat:', e);
        setError('Direkt-Chat konnte nicht gestartet werden');
      }
    },
    [loadConversations, handleSelectConversation],
  );

  // Quick access buttons (same icons as AISidebar tabs)
  const quickAccess: QuickAccessDef[] = [
    { key: 'assistant', label: 'Assistent', icon: robotIcon, testId: 'msg-sidebar-qa-assistant', view: 'conversations', filterPinned: 'assistant' },
    { key: 'liveai', label: 'Live KI', icon: bulbIcon, testId: 'msg-sidebar-qa-liveai', view: 'conversations', filterPinned: 'liveai' },
    { key: 'system', label: t('topbar.notifications'), icon: bellIcon, testId: 'msg-sidebar-qa-system', view: 'conversations', filterPinned: 'system' },
    { key: 'team', label: 'Team', icon: teamIcon, testId: 'msg-sidebar-qa-team', view: 'team' },
    { key: 'all', label: 'Chat', icon: chatBubbleIcon, testId: 'msg-sidebar-qa-all', view: 'conversations' },
  ];

  // Pinned conversations (system rooms)
  const pinnedConversations = conversations.filter((c) => c.is_pinned);
  const normalConversations = conversations.filter((c) => !c.is_pinned);

  // Active conversation object
  const activeConv = conversations.find((c) => c.id === activeConversationId) || null;
  const activeMessages = activeConversationId ? messages[activeConversationId] || [] : [];
  const isSystemLocked =
    activeConv?.is_locked && activeConv?.locked_by === 'system_notif';

  // Determine which pinned conv to select when a quick-access button is clicked
  const handleQuickAccess = (qa: QuickAccessDef) => {
    setCurrentView(qa.view);
    if (qa.view === 'conversations' && qa.filterPinned) {
      // Find pinned conversation matching the filter by title
      const filter = qa.filterPinned;
      const titleMap: Record<string, string[]> = {
        assistant: ['Assistent', 'assistent', 'assistant'],
        liveai: ['Live KI', 'live ki', 'liveai', 'proactive'],
        system: ['System', 'system'],
      };
      const matchTitles = titleMap[filter] || [filter];
      const match = pinnedConversations.find((c) =>
        matchTitles.some((t) => c.title?.toLowerCase() === t.toLowerCase()),
      );
      if (match) {
        handleSelectConversation(match.id);
        return;
      }
      // Fallback: if no pinned match, just show conversations list
    }
    if (qa.view === 'conversations' && !qa.filterPinned) {
      // 'all' — just show the list, select first if none active
      if (!activeConversationId && conversations.length > 0) {
        handleSelectConversation(conversations[0].id);
      }
    }
  };

  // ─── Collapsed: narrow icon strip (desktop only) ───
  if (messageSidebarCollapsed) {
    return (
      <div
        className="hidden md:flex flex-shrink-0 w-12 flex-col items-center border-l border-secondary-200 bg-white py-3 gap-2"
        data-testid="message-sidebar-collapsed"
      >
        {quickAccess.map((qa) => (
          <button
            key={qa.key}
            onClick={() => {
              handleQuickAccess(qa);
              toggleMessageSidebar();
            }}
            className="p-2 rounded-md hover:bg-secondary-100 min-h-touch min-w-touch flex items-center justify-center focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 relative"
            aria-label={qa.label}
            title={qa.label}
            data-testid={qa.testId}
          >
            {qa.icon('w-5 h-5 text-secondary-600')}
            {qa.key === 'system' &&
              pinnedConversations.some((c) => c.unread_count > 0) && (
                <span className="absolute -top-0.5 -right-0.5 w-4 h-4 bg-danger-500 text-white text-[10px] font-bold rounded-full flex items-center justify-center">
                  {pinnedConversations.reduce((sum, c) => sum + c.unread_count, 0)}
                </span>
              )}
          </button>
        ))}
      </div>
    );
  }

  // ─── Icon Strip (expanded) ───
  const iconStrip = (
    <div className="flex items-center gap-1 px-2 h-[58px] border-b border-secondary-200" role="tablist">
      {quickAccess.map((qa) => {
        const isActive =
          (qa.view === 'conversations' && currentView === 'conversations') ||
          (qa.view === 'team' && currentView === 'team');
        return (
          <button
            key={qa.key}
            onClick={() => handleQuickAccess(qa)}
            className={`p-2 rounded-md min-h-touch min-w-touch flex items-center justify-center transition-colors relative ${
              isActive
                ? 'bg-primary-100 text-primary-600'
                : 'text-secondary-500 hover:bg-secondary-100 hover:text-secondary-700'
            }`}
            role="tab"
            aria-selected={isActive}
            aria-label={qa.label}
            data-testid={qa.testId}
          >
            {qa.icon('w-5 h-5')}
            {qa.key === 'system' &&
              pinnedConversations.some((c) => c.unread_count > 0) && (
                <span className="absolute -top-0.5 -right-0.5 w-4 h-4 bg-danger-500 text-white text-[10px] font-bold rounded-full flex items-center justify-center">
                  {pinnedConversations.reduce((sum, c) => sum + c.unread_count, 0)}
                </span>
              )}
          </button>
        );
      })}
      <div className="flex-1" />
      <button
        onClick={toggleMessageSidebar}
        className="p-1.5 rounded-md text-secondary-400 hover:text-secondary-600 hover:bg-secondary-100 min-h-touch min-w-touch flex items-center justify-center"
        title="Einklappen"
        aria-label="Messaging einklappen"
      >
        {chevronRightIcon}
      </button>
    </div>
  );

  // ─── Conversation List Panel ───
  const renderConversationList = () => (
    <div className="flex flex-col h-full overflow-y-auto p-2 gap-1" data-testid="conversation-list">
      {loading && (
        <p className="text-sm text-secondary-400 text-center py-4">Laden...</p>
      )}
      {error && (
        <p className="text-sm text-red-500 text-center py-2">{error}</p>
      )}
      {!loading && conversations.length === 0 && !error && (
        <p className="text-sm text-secondary-400 text-center py-4">Keine Konversationen</p>
      )}
      {/* Pinned conversations */}
      {pinnedConversations.length > 0 && (
        <>
          <h3 className="text-xs font-semibold text-secondary-500 uppercase tracking-wide px-1 py-1 flex items-center gap-1">
            {pinIcon} Angespinnt
          </h3>
          {pinnedConversations.map((conv) => (
            <ConversationListItem
              key={conv.id}
              conv={conv}
              isActive={conv.id === activeConversationId}
              onClick={() => handleSelectConversation(conv.id)}
            />
          ))}
        </>
      )}
      {/* Normal conversations */}
      {normalConversations.length > 0 && (
        <>
          <h3 className="text-xs font-semibold text-secondary-500 uppercase tracking-wide px-1 py-1">
            Konversationen
          </h3>
          {normalConversations.map((conv) => (
            <ConversationListItem
              key={conv.id}
              conv={conv}
              isActive={conv.id === activeConversationId}
              onClick={() => handleSelectConversation(conv.id)}
            />
          ))}
        </>
      )}
    </div>
  );

  // ─── Main Content Area ───
  const renderContent = () => {
    if (currentView === 'team') {
      return <TeamPanel onStartDirectChat={handleStartDirectChat} />;
    }
    // conversations view: show conversation list + message feed + input
    return (
      <div className="flex flex-col h-full">
        {/* Conversation list (narrow, top section within panel) */}
        <div className="border-b border-secondary-200 max-h-[40%] overflow-y-auto">
          {renderConversationList()}
        </div>
        {/* Message feed */}
        <div className="flex-1 overflow-hidden flex flex-col">
          {activeConv && (
            <div className="px-3 py-2 border-b border-secondary-200 flex items-center gap-2">
              {activeConv.is_pinned && <span className="text-secondary-400">📌</span>}
              <span className="text-sm font-medium text-secondary-700 truncate">
                {activeConv.title || 'Ohne Titel'}
              </span>
            </div>
          )}
          <MessageFeed messages={activeMessages} loading={messagesLoading} />
          {/* Message input (hidden for system-locked conversations) */}
          {activeConv && !isSystemLocked && (
            <MessageInput onSend={handleSendMessage} disabled={false} />
          )}
          {isSystemLocked && (
            <div className="p-3 border-t border-secondary-200 text-center">
              <span className="text-xs text-secondary-400">System-Konversation (schreibgeschützt)</span>
            </div>
          )}
        </div>
      </div>
    );
  };

  // ─── Expanded: Mobile = full width overlay, Desktop = resizable panel ───
  return (
    <>
      {/* Mobile: full width overlay with back button */}
      <div
        className="md:hidden fixed inset-0 z-50 bg-white flex flex-col"
        data-testid="message-sidebar-mobile"
      >
        <div className="h-14 flex items-center gap-2 px-3 border-b border-secondary-200">
          <button
            onClick={toggleMessageSidebar}
            className="inline-flex items-center gap-1 px-2 py-1 rounded text-sm text-secondary-700 hover:bg-secondary-100 min-h-touch"
            aria-label="Zurück"
            data-testid="message-sidebar-back"
          >
            <ChevronLeft className="w-5 h-5" aria-hidden="true" strokeWidth={2} />
            <span className="text-sm font-medium">Zurück</span>
          </button>
        </div>
        {iconStrip}
        <div className="flex-1 overflow-hidden">{renderContent()}</div>
      </div>

      {/* Desktop: resizable panel */}
      <ResizablePanel
        initialWidth={320}
        minWidth={240}
        maxWidth={600}
        handleSide="left"
        className="hidden md:flex border-l border-secondary-200 bg-white"
        data-testid="message-sidebar-pane"
      >
        <div className="h-full flex flex-col">
          {iconStrip}
          <div className="flex-1 overflow-hidden">{renderContent()}</div>
        </div>
      </ResizablePanel>
    </>
  );
}
