'use client';

/**
 * Discord-style main chat panel.
 * Layout: header + message list + input + member sidebar
 */

import type { RoomMemberResponse, RoomMessageResponse, RoomResponse, RoomThreadResponse } from '@/client';
import type { MessageWithMeta } from '@/contexts';
import { cn } from '@/lib/utils';
import {
  Hash, Lock, Users, Search, ChevronLeft,
  AtSign, Pin, Settings, PanelLeft,
} from 'lucide-react';
import {
  useCallback,
  useEffect,
  useRef,
  useState,
} from 'react';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { MessageList } from './message/MessageList';
import { MessageInput, type MessageInputHandle } from './message/MessageInput';
import { RoomMessageEditDialog } from './RoomMessageEditDialog';
import { RoomMessageEditHistoryDialog } from './RoomMessageEditHistoryDialog';
import { RoomMentionPanel } from './RoomMentionPanel';
import { RoomThreadPanel } from './RoomThreadPanel';
import { RoomSettingsPanel } from './RoomSettingsPanel';
import { DiscordMemberList } from './DiscordMemberList';
import { RoomMessageSearch } from './RoomMessageSearch';
import { RoomPinPanel } from './RoomPinPanel';
import { useRoom } from '@/contexts';

// ─── Main Panel ──────────────────────────────────────────────────────────

interface DiscordChatPanelProps {
  room: RoomResponse;
  isAdmin: boolean;
  onClose: () => void;
  onDelete: () => void;
  onToggleChannelSidebar: () => void;
  channelSidebarOpen: boolean;
}

export function DiscordChatPanel({ room, isAdmin, onClose, onDelete, onToggleChannelSidebar, channelSidebarOpen }: DiscordChatPanelProps) {
  const {
    messages,
    members,
    membersLoading,
    sendMessage,
    editMessage,
    revokeMessage,
    updateRoom,
    wsStatus,
    wsError,
    wsClient,
    threads,
    refreshThreads,
    roomAiConfigs,
    presence,
  } = useRoom();

  const messagesEndRef = useRef<HTMLDivElement>(null);
  const messageInputRef = useRef<MessageInputHandle | null>(null);

  const [replyingTo, setReplyingTo] = useState<MessageWithMeta | null>(null);
  const [editingMessage, setEditingMessage] = useState<MessageWithMeta | null>(null);
  const [editDialogOpen, setEditDialogOpen] = useState(false);
  const [editHistoryDialogOpen, setEditHistoryDialogOpen] = useState(false);
  const [selectedMessageForHistory, setSelectedMessageForHistory] = useState<string>('');
  const [showSettings, setShowSettings] = useState(false);
  const [showMentions, setShowMentions] = useState(false);
  const [showMemberList, setShowMemberList] = useState(false);
  const [showSearch, setShowSearch] = useState(false);
  const [showPins, setShowPins] = useState(false);
  const [activeThread, setActiveThread] = useState<{ thread: RoomThreadResponse; parentMessage: MessageWithMeta } | null>(null);
  const [isUpdatingRoom, setIsUpdatingRoom] = useState(false);

  const wsDotClass =
    wsStatus === 'open' ? 'connected'
    : wsStatus === 'connecting' ? 'connecting'
    : 'disconnected';

  const handleSend = useCallback(
    (content: string) => {
      const attachmentIds = messageInputRef.current?.getAttachmentIds() ?? [];
      sendMessage(content, 'text', replyingTo?.id ?? undefined, attachmentIds.length > 0 ? attachmentIds : undefined);
      setReplyingTo(null);
      messageInputRef.current?.clearContent();
    },
    [sendMessage, replyingTo],
  );

  const handleCancelReply = useCallback(() => {
    setReplyingTo(null);
  }, []);

  const handleOpenUserCard = useCallback(
    (payload: { username: string; displayName?: string | null; avatarUrl?: string | null; userId: string; point: { x: number; y: number } }) => {
      messageInputRef.current?.insertMention('user', payload.userId, payload.username);
      messageInputRef.current?.focus();
    },
    [],
  );

  const handleMemberClick = useCallback(
    (member: RoomMemberResponse) => {
      const label = member.user_info?.username ?? member.user;
      const type = member.role === 'ai' ? 'ai' : 'user';
      messageInputRef.current?.insertMention(type, member.user, label);
      messageInputRef.current?.focus();
    },
    [],
  );

  const handleEdit = useCallback((message: MessageWithMeta) => {
    setEditingMessage(message);
    setEditDialogOpen(true);
  }, []);

  const handleViewEditHistory = useCallback((message: MessageWithMeta) => {
    setSelectedMessageForHistory(message.id);
    setEditHistoryDialogOpen(true);
  }, []);

  const handleEditConfirm = useCallback(
    (newContent: string) => {
      if (!editingMessage) return;
      editMessage(editingMessage.id, newContent);
      setEditDialogOpen(false);
      setEditingMessage(null);
      toast.success('Message updated');
    },
    [editingMessage?.id, editMessage],
  );

  const handleRevoke = useCallback(
    (message: MessageWithMeta) => {
      revokeMessage(message.id);
      toast.success('Message deleted');
    },
    [revokeMessage],
  );

  const handleOpenThread = useCallback((message: MessageWithMeta) => {
    if (!message.thread_id) return;
    const thread = threads.find(t => t.id === message.thread_id);
    if (thread) setActiveThread({ thread, parentMessage: message });
  }, [threads]);

  const handleCreateThread = useCallback(async (message: MessageWithMeta) => {
    if (!wsClient || message.thread_id) return;
    try {
      const thread = await wsClient.threadCreate(room.id, message.seq);
      setActiveThread({ thread, parentMessage: message });
      refreshThreads();
    } catch (err) {
      console.error('Failed to create thread:', err);
      toast.error('Failed to create thread');
    }
  }, [wsClient, room.id, refreshThreads]);

  const handleMentionSelect = useCallback((mention: { room_name: string }) => {
    toast.info(`Navigate to message in ${mention.room_name}`);
    setShowMentions(false);
  }, []);

  const handleSearchSelect = useCallback((message: RoomMessageResponse) => {
    const el = document.getElementById(`msg-${message.id}`);
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
    setShowSearch(false);
  }, []);

  const handleJumpToMessage = useCallback((messageId: string) => {
    const el = document.getElementById(`msg-${messageId}`);
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
    setShowPins(false);
  }, []);

  const handleUpdateRoom = useCallback(
    async (name: string, isPublic: boolean) => {
      setIsUpdatingRoom(true);
      try {
        await updateRoom(room.id, name, isPublic);
        toast.success('Room updated');
        setShowSettings(false);
      } catch {
        toast.error('Failed to update room');
      } finally {
        setIsUpdatingRoom(false);
      }
    },
    [room.id, updateRoom],
  );

  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages.length]);

  useEffect(() => {
    setReplyingTo(null);
    setEditingMessage(null);
    setEditDialogOpen(false);
    setShowSettings(false);
    setShowMentions(false);
    setShowSearch(false);
    setShowPins(false);
    setActiveThread(null);
  }, [room.id]);

  return (
    <div
      className="flex flex-1 min-w-0 flex-col"
      style={{ background: 'var(--room-bg)', color: 'var(--room-text)' }}
    >
      {/* ── Header ─────────────────────────────────────────────── */}
      <header
        className="flex h-12 items-center border-b px-4 gap-2 shrink-0"
        style={{ borderColor: 'var(--room-border)', background: 'var(--room-sidebar)' }}
      >
        <div className="flex items-center gap-2 flex-1 min-w-0">
          {room.public
            ? <Hash className="h-5 w-5 shrink-0" style={{ color: 'var(--room-text-muted)' }} />
            : <Lock className="h-4 w-4 shrink-0" style={{ color: 'var(--room-text-muted)' }} />
          }
          <h1 className="text-base font-semibold truncate" style={{ color: 'var(--room-text)' }}>{room.room_name}</h1>
          <div className="discord-ws-status ml-1">
            <span className={cn('discord-ws-dot', wsDotClass)} />
            {wsStatus !== 'open' && wsStatus !== 'idle' && (
              <span className="text-xs" style={{ color: 'var(--room-text-muted)' }}>
                {wsStatus === 'connecting' ? 'Connecting...' : wsError ?? 'Disconnected'}
              </span>
            )}
          </div>
        </div>

        <div className="flex items-center gap-0.5 shrink-0">
          <button
            className="flex h-8 w-8 items-center justify-center rounded-md transition-colors"
            style={{
              color: showMentions ? 'var(--room-accent)' : 'var(--room-text-muted)',
              background: showMentions ? 'var(--room-channel-active)' : 'transparent',
            }}
            onClick={() => { setShowMentions(v => !v); setShowSettings(false); }}
            title="@ Mentions"
          >
            <AtSign className="h-4 w-4" />
          </button>

          <button
            className="flex h-8 w-8 items-center justify-center rounded-md transition-colors"
            style={{
              color: showSearch ? 'var(--room-accent)' : 'var(--room-text-muted)',
              background: showSearch ? 'var(--room-channel-active)' : 'transparent',
            }}
            onClick={() => { setShowSearch(v => !v); setShowSettings(false); }}
            title="Search messages"
          >
            <Search className="h-4 w-4" />
          </button>

          <button
            className="flex h-8 w-8 items-center justify-center rounded-md transition-colors"
            style={{
              color: showMemberList ? 'var(--room-accent)' : 'var(--room-text-muted)',
              background: showMemberList ? 'var(--room-channel-active)' : 'transparent',
            }}
            onClick={() => { setShowMemberList(v => !v); setShowSettings(false); }}
            title="Member list"
          >
            <Users className="h-4 w-4" />
          </button>

          <button
            className="flex h-8 w-8 items-center justify-center rounded-md transition-colors"
            style={{
              color: showPins ? 'var(--room-accent)' : 'var(--room-text-muted)',
              background: showPins ? 'var(--room-channel-active)' : 'transparent',
            }}
            onClick={() => { setShowPins(v => !v); setShowSettings(false); setShowMentions(false); setShowMemberList(false); }}
            title="Pinned messages"
          >
            <Pin className="h-4 w-4" />
          </button>

          {/* Settings — opens Room Settings */}
          {isAdmin && (
            <button
              className="flex h-8 w-8 items-center justify-center rounded-md transition-colors"
              style={{
                color: showSettings ? 'var(--room-accent)' : 'var(--room-text-muted)',
                background: showSettings ? 'var(--room-channel-active)' : 'transparent',
              }}
              onClick={() => { setShowSettings(v => !v); setShowMentions(false); setShowMemberList(false); }}
              title="Room Settings"
            >
              <Settings className="h-4 w-4" />
            </button>
          )}

          {isAdmin && (
            <button
              className="flex h-8 w-8 items-center justify-center rounded-md transition-colors"
              style={{ color: 'var(--room-text-muted)' }}
              onClick={onDelete}
              title="Delete channel"
            >
              <span className="text-xs">🗑</span>
            </button>
          )}

          <button
            className="flex h-8 w-8 items-center justify-center rounded-md transition-colors"
            style={{
              color: channelSidebarOpen ? 'var(--room-accent)' : 'var(--room-text-muted)',
              background: channelSidebarOpen ? 'var(--room-channel-active)' : 'transparent',
            }}
            onClick={onToggleChannelSidebar}
            title={channelSidebarOpen ? 'Hide channels' : 'Show channels'}
          >
            <PanelLeft className="h-4 w-4" />
          </button>

          <Button
            variant="ghost"
            size="sm"
            className="h-8 md:hidden"
            style={{ color: 'var(--room-text-muted)' }}
            onClick={onClose}
          >
            <ChevronLeft className="mr-1 h-4 w-4" />
            Back
          </Button>
        </div>
      </header>

      {/* ── Body ──────────────────────────────────────────────── */}
      <div className="flex min-h-0 flex-1 overflow-hidden">
        <div className="flex min-h-0 flex-1 flex-col">
          <MessageList
            roomId={room.id}
            messages={messages}
            messagesEndRef={messagesEndRef}
            onInlineEdit={handleEdit}
            onViewHistory={handleViewEditHistory}
            onRevoke={handleRevoke}
            onReply={setReplyingTo}
            onMention={undefined}
            onOpenUserCard={handleOpenUserCard}
            onOpenThread={handleOpenThread}
            onCreateThread={handleCreateThread}
          />

          <MessageInput
            ref={messageInputRef}
            roomName={room.room_name ?? 'room'}
            onSend={handleSend}
            replyingTo={replyingTo ? { id: replyingTo.id, display_name: replyingTo.display_name ?? undefined, content: replyingTo.content } : null}
            onCancelReply={handleCancelReply}
          />
        </div>

        {showMemberList && (
          <DiscordMemberList
            members={members}
            membersLoading={membersLoading}
            onMemberClick={handleMemberClick}
            aiConfigs={roomAiConfigs}
            presence={presence}
          />
        )}
      </div>

      {/* ── Slide Panels ──────────────────────────────────────── */}
      {showSettings && (
        <aside
          className="absolute right-0 top-12 bottom-0 w-[360px] border-l z-20 flex flex-col animate-in slide-in-from-right duration-200"
          style={{
            borderColor: 'var(--room-border)',
            background: 'var(--room-bg)',
          }}
        >
          <RoomSettingsPanel
            room={room}
            onUpdate={handleUpdateRoom}
            onClose={() => setShowSettings(false)}
            isPending={isUpdatingRoom}
          />
        </aside>
      )}

      {showMentions && (
        <aside
          className="absolute right-0 top-12 bottom-0 w-[380px] border-l z-20 flex flex-col animate-in slide-in-from-right duration-200"
          style={{ borderColor: 'var(--room-border)', background: 'var(--room-bg)' }}
        >
          <RoomMentionPanel
            onClose={() => setShowMentions(false)}
            onSelectNotification={handleMentionSelect}
          />
        </aside>
      )}

      {showSearch && (
        <aside
          className="absolute right-0 top-12 bottom-0 w-[420px] border-l z-20 flex flex-col animate-in slide-in-from-right duration-200"
          style={{ borderColor: 'var(--room-border)', background: 'var(--room-bg)' }}
        >
          <RoomMessageSearch
            roomId={room.id}
            onSelectMessage={handleSearchSelect}
            onClose={() => setShowSearch(false)}
          />
        </aside>
      )}

      {activeThread && (
        <RoomThreadPanel
          roomId={room.id}
          thread={activeThread.thread}
          parentMessage={activeThread.parentMessage}
          onClose={() => setActiveThread(null)}
        />
      )}

      {showPins && (
        <RoomPinPanel
          roomId={room.id}
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          messages={messages as any}
          members={members}
          onClose={() => setShowPins(false)}
          onJumpToMessage={handleJumpToMessage}
        />
      )}

      <RoomMessageEditDialog
        open={editDialogOpen}
        onOpenChange={setEditDialogOpen}
        originalContent={editingMessage?.content ?? ''}
        onConfirm={handleEditConfirm}
      />

      <RoomMessageEditHistoryDialog
        open={editHistoryDialogOpen}
        onOpenChange={setEditHistoryDialogOpen}
        messageId={selectedMessageForHistory}
        roomId={room.id}
      />
    </div>
  );
}
