import { useParams, useNavigate, useSearchParams } from 'react-router-dom';
import { useQuery, useMutation } from '@apollo/client/react';
import { useState, useRef, useEffect } from 'react';
import { GET_CHAT_SUMMARY_QUERY } from '../api/operations/queries';
import { DISCONNECT_FROM_CHAT_MUTATION, CHAT_ACTIVATE_MUTATION } from '../api/operations/mutations';
import { useChannel, useStreamChat } from '../context/StreamChatContext';
import type { StreamMessage } from '../context/StreamChatContext';
import { LoadingPage } from '../components/ui/Loading';

// Proxy cloudinary images through our server to avoid CORS
function proxyImageUrl(url: string | undefined): string | undefined {
  if (!url) return undefined;
  if (url.includes('cloudinary.com')) {
    return url.replace('https://res.cloudinary.com', '/api/images');
  }
  if (url.includes('fldcdn.com')) {
    return url.replace('https://prod.fldcdn.com', '/api/fldcdn');
  }
  return url;
}

function formatTime(dateString: string | undefined): string {
  if (!dateString) return '';
  const date = new Date(dateString);
  return date.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });
}

function formatDate(dateString: string | undefined): string {
  if (!dateString) return '';
  const date = new Date(dateString);
  const today = new Date();
  const yesterday = new Date(today);
  yesterday.setDate(yesterday.getDate() - 1);

  if (date.toDateString() === today.toDateString()) {
    return 'Today';
  } else if (date.toDateString() === yesterday.toDateString()) {
    return 'Yesterday';
  } else {
    return date.toLocaleDateString([], { weekday: 'short', month: 'short', day: 'numeric' });
  }
}

interface MessageBubbleProps {
  message: StreamMessage;
  isOwn: boolean;
  showDate?: boolean;
  showAvatar?: boolean;
  isFirstInGroup?: boolean;
  isLastInGroup?: boolean;
}

function MessageBubble({ message, isOwn, showDate, showAvatar, isFirstInGroup, isLastInGroup }: MessageBubbleProps) {
  const [imageLoaded, setImageLoaded] = useState(false);
  const [imageError, setImageError] = useState(false);

  // Get border radius based on position in group
  const getBorderRadius = () => {
    if (isOwn) {
      if (isFirstInGroup && isLastInGroup) return 'rounded-[20px] rounded-br-md';
      if (isFirstInGroup) return 'rounded-[20px] rounded-br-md rounded-br-md';
      if (isLastInGroup) return 'rounded-[20px] rounded-tr-md rounded-br-md';
      return 'rounded-[20px] rounded-r-md';
    } else {
      if (isFirstInGroup && isLastInGroup) return 'rounded-[20px] rounded-bl-md';
      if (isFirstInGroup) return 'rounded-[20px] rounded-bl-md';
      if (isLastInGroup) return 'rounded-[20px] rounded-tl-md rounded-bl-md';
      return 'rounded-[20px] rounded-l-md';
    }
  };

  return (
    <>
      {showDate && (
        <div className="flex justify-center my-6">
          <span className="
            text-[11px] font-medium tracking-wide uppercase
            text-[var(--color-text-muted)]/70
            bg-white/[0.03] backdrop-blur-sm
            px-4 py-1.5 rounded-full
            border border-white/[0.04]
          ">
            {formatDate(message.created_at)}
          </span>
        </div>
      )}
      <div className={`
        flex ${isOwn ? 'justify-end' : 'justify-start'}
        ${isLastInGroup ? 'mb-3' : 'mb-0.5'}
        animate-fade-up
      `}>
        <div className={`
          flex items-end gap-2
          ${isOwn ? 'flex-row-reverse' : 'flex-row'}
          max-w-[80%] md:max-w-[65%]
        `}>
          {/* Avatar placeholder for alignment */}
          {!isOwn && (
            <div className="w-8 h-8 flex-shrink-0">
              {showAvatar && message.user?.image && (
                <img
                  src={proxyImageUrl(message.user.image)}
                  alt=""
                  className="w-8 h-8 rounded-full object-cover ring-2 ring-white/5"
                />
              )}
            </div>
          )}

          <div className="flex flex-col">
            <div className={`
              px-4 py-2.5
              ${getBorderRadius()}
              ${isOwn
                ? 'bg-gradient-to-br from-[#E85F5C] to-[#D64550] text-white'
                : 'bg-white/[0.07] text-[var(--color-text-primary)] border border-white/[0.05]'
              }
              shadow-lg
              ${isOwn ? 'shadow-[#E85F5C]/10' : 'shadow-black/20'}
            `}>
              {/* Attachments */}
              {message.attachments?.map((att, i) => {
                const imageUrl = proxyImageUrl(att.image_url || att.thumb_url);
                if (!imageUrl) return null;
                return (
                  <div key={i} className="relative mb-2 -mx-1 -mt-1 first:-mt-1">
                    {!imageLoaded && !imageError && (
                      <div className="w-48 h-48 bg-white/5 rounded-xl animate-pulse flex items-center justify-center">
                        <svg className="w-8 h-8 text-white/20" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1} d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
                        </svg>
                      </div>
                    )}
                    {imageError ? (
                      <div className="w-48 h-32 bg-white/5 rounded-xl flex items-center justify-center">
                        <span className="text-sm text-white/40">Image unavailable</span>
                      </div>
                    ) : (
                      <img
                        src={imageUrl}
                        alt="attachment"
                        className={`max-w-[200px] rounded-xl ${imageLoaded ? 'block' : 'hidden'}`}
                        onLoad={() => setImageLoaded(true)}
                        onError={() => setImageError(true)}
                      />
                    )}
                  </div>
                );
              })}

              {/* Message text */}
              {message.text && (
                <p className="text-[15px] leading-relaxed whitespace-pre-wrap break-words">
                  {message.text}
                </p>
              )}
            </div>

            {/* Timestamp - only show for last message in group */}
            {isLastInGroup && (
              <p className={`
                text-[10px] text-[var(--color-text-muted)]/60 mt-1 px-1
                ${isOwn ? 'text-right' : 'text-left'}
              `}>
                {formatTime(message.created_at)}
              </p>
            )}
          </div>
        </div>
      </div>
    </>
  );
}

export function ChatPage() {
  const { channelId } = useParams<{ channelId: string }>();
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();
  const chatName = searchParams.get('name') || 'Chat';
  const chatAvatar = searchParams.get('avatar') || undefined;

  const [inputText, setInputText] = useState('');
  const [isSending, setIsSending] = useState(false);
  const [showMenu, setShowMenu] = useState(false);
  const [showDisconnectConfirm, setShowDisconnectConfirm] = useState(false);
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);
  const menuRef = useRef<HTMLDivElement>(null);

  // Stream Chat connection
  const { isConnected, isConnecting: streamConnecting, error: streamError, userId } = useStreamChat();

  // Channel and messages
  const {
    messages,
    loading: channelLoading,
    error: channelError,
    sendMessage,
  } = useChannel(channelId || '');

  // Get chat summary for additional info
  const { data: summaryData, loading: summaryLoading } = useQuery(GET_CHAT_SUMMARY_QUERY, {
    variables: { streamChatId: channelId },
    skip: !channelId,
  });

  const summary = summaryData?.summary;
  const displayName = summary?.name || chatName;
  const displayAvatar = proxyImageUrl(summary?.avatarSet?.[0] || chatAvatar);
  const chatStatus = summary?.status;

  // Chat mutations
  const [disconnectFromChat, { loading: disconnecting }] = useMutation(DISCONNECT_FROM_CHAT_MUTATION);
  const [chatActivate, { loading: activating }] = useMutation(CHAT_ACTIVATE_MUTATION);

  const handleDisconnect = async () => {
    try {
      await disconnectFromChat({
        variables: { input: { chatId: summary?.id || channelId } },
      });
      navigate('/messages');
    } catch (err) {
      console.error('Failed to disconnect:', err);
    }
  };

  const handleReactivate = async () => {
    try {
      await chatActivate({
        variables: { input: { chatId: summary?.id || channelId } },
      });
      setShowMenu(false);
    } catch (err) {
      console.error('Failed to reactivate chat:', err);
    }
  };

  // Close menu when clicking outside
  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
        setShowMenu(false);
        setShowDisconnectConfirm(false);
      }
    };
    if (showMenu) {
      document.addEventListener('mousedown', handleClickOutside);
      return () => document.removeEventListener('mousedown', handleClickOutside);
    }
  }, [showMenu]);

  // Scroll to bottom on new messages
  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages]);

  const handleSend = async () => {
    if (!inputText.trim() || isSending) return;

    try {
      setIsSending(true);
      await sendMessage(inputText.trim());
      setInputText('');
      inputRef.current?.focus();
    } catch (err) {
      console.error('Failed to send message:', err);
    } finally {
      setIsSending(false);
    }
  };

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

  // Loading states
  if (summaryLoading || streamConnecting) {
    return <LoadingPage message="Connecting to chat..." />;
  }

  // Stream connection error
  if (streamError || channelError) {
    return (
      <div className="flex flex-col items-center justify-center py-20 animate-fade-up">
        <div className="
          w-20 h-20 rounded-full
          bg-gradient-to-br from-red-500/20 to-red-600/10
          flex items-center justify-center mb-6
          border border-red-500/20
        ">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="w-10 h-10 text-red-400">
            <path strokeLinecap="round" strokeLinejoin="round" d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z" />
          </svg>
        </div>
        <h2 className="font-display text-xl font-semibold text-[var(--color-text-primary)] mb-2">
          Connection Lost
        </h2>
        <p className="text-[var(--color-text-muted)] text-sm max-w-xs text-center mb-6">
          {streamError || channelError}
        </p>
        <button
          onClick={() => navigate('/messages')}
          className="
            px-6 py-2.5 rounded-full
            bg-white/10 hover:bg-white/15
            text-white font-medium
            transition-all duration-200
            border border-white/10
          "
        >
          Back to Messages
        </button>
      </div>
    );
  }

  // Process messages for grouping
  let lastDate = '';
  let lastUserId = '';
  const processedMessages = messages.map((msg, index) => {
    const msgDate = msg.created_at ? formatDate(msg.created_at) : '';
    const showDate = msgDate !== lastDate;
    lastDate = msgDate;

    const currentUserId = msg.user?.id || '';
    const nextMsg = messages[index + 1];
    const nextUserId = nextMsg?.user?.id || '';

    const isFirstInGroup = showDate || currentUserId !== lastUserId;
    const isLastInGroup = !nextMsg || nextUserId !== currentUserId ||
      (nextMsg.created_at && msg.created_at &&
        new Date(nextMsg.created_at).getTime() - new Date(msg.created_at).getTime() > 60000);

    lastUserId = currentUserId;

    return {
      ...msg,
      showDate,
      showAvatar: isLastInGroup && msg.user?.id !== userId,
      isFirstInGroup,
      isLastInGroup,
    };
  });

  return (
    <div className="flex flex-col h-[calc(100vh-80px)] max-w-4xl mx-auto -mx-4 md:mx-auto">
      {/* Header */}
      <div className="
        flex items-center gap-4 px-4 py-3
        bg-gradient-to-b from-[var(--color-surface)] to-transparent
        backdrop-blur-xl
        sticky top-0 z-10
      ">
        <button
          onClick={() => navigate('/messages')}
          className="
            w-10 h-10 rounded-full
            bg-white/[0.05] hover:bg-white/[0.08]
            flex items-center justify-center
            transition-all duration-200
            border border-white/[0.06]
            hover:scale-105 active:scale-95
          "
        >
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" className="w-5 h-5 text-white/70">
            <path strokeLinecap="round" strokeLinejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" />
          </svg>
        </button>

        <div className="flex items-center gap-3 flex-1 min-w-0">
          {/* Avatar with glow effect */}
          <div className="relative">
            {displayAvatar ? (
              <img
                src={displayAvatar}
                alt=""
                className="w-11 h-11 rounded-full object-cover ring-2 ring-white/10"
              />
            ) : (
              <div className="w-11 h-11 rounded-full bg-gradient-to-br from-[var(--color-primary)]/30 to-[var(--color-primary)]/10 flex items-center justify-center ring-2 ring-white/10">
                <span className="text-lg font-semibold text-white/70">
                  {displayName.charAt(0)}
                </span>
              </div>
            )}
            {/* Online indicator */}
            <div className={`
              absolute -bottom-0.5 -right-0.5
              w-3.5 h-3.5 rounded-full
              ${isConnected ? 'bg-emerald-400' : 'bg-amber-400'}
              border-2 border-[var(--color-void)]
            `} />
          </div>

          <div className="flex-1 min-w-0">
            <h2 className="font-semibold text-[var(--color-text-primary)] truncate text-lg">
              {displayName}
            </h2>
            {summary?.targetProfile && (
              <p className="text-sm text-[var(--color-text-muted)]/70">
                {summary.targetProfile.age} · {summary.targetProfile.gender?.toLowerCase()}
              </p>
            )}
          </div>
        </div>

        {/* More options */}
        <div className="relative" ref={menuRef}>
          <button
            onClick={() => { setShowMenu(!showMenu); setShowDisconnectConfirm(false); }}
            className="
              w-10 h-10 rounded-full
              hover:bg-white/[0.05]
              flex items-center justify-center
              transition-colors
            "
          >
            <svg viewBox="0 0 24 24" fill="currentColor" className="w-5 h-5 text-white/50">
              <path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" />
            </svg>
          </button>

          {showMenu && (
            <div className="
              absolute right-0 top-12 z-50
              w-56 py-1.5
              bg-[var(--color-surface-elevated)] backdrop-blur-xl
              border border-white/[0.08]
              rounded-xl shadow-xl shadow-black/40
              animate-fade-up
            ">
              {showDisconnectConfirm ? (
                <div className="px-4 py-3">
                  <p className="text-sm text-[var(--color-text-primary)] mb-3 font-body">
                    Disconnect from {displayName}?
                  </p>
                  <div className="flex gap-2">
                    <button
                      onClick={() => setShowDisconnectConfirm(false)}
                      className="
                        flex-1 px-3 py-2 rounded-lg
                        bg-white/[0.06] hover:bg-white/[0.1]
                        text-sm text-[var(--color-text-muted)]
                        transition-colors font-body
                      "
                    >
                      Cancel
                    </button>
                    <button
                      onClick={handleDisconnect}
                      disabled={disconnecting}
                      className="
                        flex-1 px-3 py-2 rounded-lg
                        bg-red-500/20 hover:bg-red-500/30
                        text-sm text-red-400 font-medium
                        transition-colors font-body
                        disabled:opacity-50
                      "
                    >
                      {disconnecting ? 'Disconnecting...' : 'Disconnect'}
                    </button>
                  </div>
                </div>
              ) : (
                <>
                  {chatStatus === 'INACTIVE' && (
                    <button
                      onClick={handleReactivate}
                      disabled={activating}
                      className="
                        w-full flex items-center gap-3 px-4 py-2.5
                        hover:bg-white/[0.05] transition-colors
                        text-left
                      "
                    >
                      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="w-5 h-5 text-emerald-400 flex-shrink-0">
                        <path strokeLinecap="round" strokeLinejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182M2.985 19.644l3.182-3.182" />
                      </svg>
                      <span className="text-sm text-[var(--color-text-primary)] font-body">
                        {activating ? 'Reactivating...' : 'Reactivate Chat'}
                      </span>
                    </button>
                  )}
                  <button
                    onClick={() => setShowDisconnectConfirm(true)}
                    className="
                      w-full flex items-center gap-3 px-4 py-2.5
                      hover:bg-white/[0.05] transition-colors
                      text-left
                    "
                  >
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="w-5 h-5 text-red-400 flex-shrink-0">
                      <path strokeLinecap="round" strokeLinejoin="round" d="M13.181 8.68l-4.503 4.504M8.678 8.68l4.503 4.504M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                    </svg>
                    <span className="text-sm text-red-400 font-body">Disconnect</span>
                  </button>
                </>
              )}
            </div>
          )}
        </div>
      </div>

      {/* Messages area */}
      <div className="
        flex-1 overflow-y-auto
        px-4 py-4
        scrollbar-thin scrollbar-thumb-white/10 scrollbar-track-transparent
      ">
        {channelLoading ? (
          <div className="flex items-center justify-center py-20">
            <div className="flex flex-col items-center gap-4">
              <div className="
                w-12 h-12 rounded-full
                border-2 border-[var(--color-primary)]/30 border-t-[var(--color-primary)]
                animate-spin
              " />
              <p className="text-[var(--color-text-muted)]/60 text-sm">Loading messages...</p>
            </div>
          </div>
        ) : messages.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-20 animate-fade-up">
            <div className="
              w-24 h-24 rounded-full
              bg-gradient-to-br from-white/[0.05] to-white/[0.02]
              flex items-center justify-center mb-6
              border border-white/[0.05]
            ">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1" className="w-12 h-12 text-[var(--color-text-muted)]/30">
                <path strokeLinecap="round" strokeLinejoin="round" d="M8.625 12a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H8.25m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H12m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0h-.375M21 12c0 4.556-4.03 8.25-9 8.25a9.764 9.764 0 01-2.555-.337A5.972 5.972 0 015.41 20.97a5.969 5.969 0 01-.474-.065 4.48 4.48 0 00.978-2.025c.09-.457-.133-.901-.467-1.226C3.93 16.178 3 14.189 3 12c0-4.556 4.03-8.25 9-8.25s9 3.694 9 8.25z" />
              </svg>
            </div>
            <h3 className="text-lg font-medium text-[var(--color-text-primary)] mb-2">
              Start the conversation
            </h3>
            <p className="text-[var(--color-text-muted)]/60 text-sm text-center max-w-xs">
              Send a message to begin chatting with {displayName}
            </p>
          </div>
        ) : (
          <>
            {processedMessages.map((msg) => (
              <MessageBubble
                key={msg.id}
                message={msg}
                isOwn={msg.user?.id === userId}
                showDate={msg.showDate}
                showAvatar={msg.showAvatar}
                isFirstInGroup={msg.isFirstInGroup}
                isLastInGroup={msg.isLastInGroup}
              />
            ))}
          </>
        )}
        <div ref={messagesEndRef} />
      </div>

      {/* Input area */}
      <div className="
        px-4 py-3
        bg-gradient-to-t from-[var(--color-void)] via-[var(--color-void)] to-transparent
        border-t border-white/[0.04]
      ">
        <div className="flex items-end gap-3">
          {/* Attachment button */}
          <button className="
            w-11 h-11 rounded-full
            bg-white/[0.05] hover:bg-white/[0.08]
            flex items-center justify-center
            transition-all duration-200
            border border-white/[0.06]
            flex-shrink-0
          ">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="w-5 h-5 text-white/50">
              <path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
            </svg>
          </button>

          {/* Input field */}
          <div className="flex-1 relative">
            <input
              ref={inputRef}
              type="text"
              value={inputText}
              onChange={(e) => setInputText(e.target.value)}
              onKeyDown={handleKeyPress}
              placeholder="Type a message..."
              disabled={!isConnected}
              className="
                w-full px-5 py-3
                bg-white/[0.05]
                border border-white/[0.08]
                rounded-full
                text-[var(--color-text-primary)] text-[15px]
                placeholder-[var(--color-text-muted)]/50
                focus:outline-none focus:border-[var(--color-primary)]/40 focus:bg-white/[0.07]
                transition-all duration-200
                disabled:opacity-50 disabled:cursor-not-allowed
              "
            />
          </div>

          {/* Send button */}
          <button
            onClick={handleSend}
            disabled={!inputText.trim() || isSending || !isConnected}
            className={`
              w-11 h-11 rounded-full
              flex items-center justify-center
              transition-all duration-200
              flex-shrink-0
              ${inputText.trim() && !isSending && isConnected
                ? 'bg-gradient-to-br from-[#E85F5C] to-[#D64550] text-white shadow-lg shadow-[#E85F5C]/25 hover:shadow-[#E85F5C]/40 hover:scale-105 active:scale-95'
                : 'bg-white/[0.05] text-white/30 border border-white/[0.06] cursor-not-allowed'
              }
            `}
          >
            {isSending ? (
              <div className="w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin" />
            ) : (
              <svg viewBox="0 0 24 24" fill="currentColor" className="w-5 h-5 translate-x-0.5">
                <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" />
              </svg>
            )}
          </button>
        </div>
      </div>
    </div>
  );
}
