import { useState, useEffect, useRef, useCallback } from 'react';
import { createPortal } from 'react-dom';
import { ChatMessage } from './ChatMessage';
import { TypingIndicator } from './TypingIndicator';
import { MessageInput } from './MessageInput';
import { SuggestedQuestions } from './SuggestedQuestions';
import { ChatBubblePreview } from './ChatBubblePreview';
import { useChatWebSocket } from '../hooks/useChatWebSocket';
import { usePersonalization } from '../hooks/usePersonalization';
import { usePageTracker } from '../hooks/usePageTracker';
import { useAnalytics } from '../hooks/useAnalytics';

// Storage key for tracking if user has seen greeting (return visitor detection)
const GREETING_SEEN_KEY = 'kanji_greeting_seen';

// Raiko avatar URL
const RAIKO_AVATAR_URL = 'https://kanji.fra1.cdn.digitaloceanspaces.com/raiko-avatar-64-static.webp';

/**
 * Convert animated avatar URL to static version
 * e.g., "mete-avatar-64.webp" -> "mete-avatar-64-static.webp"
 */
function toStaticAvatar(url: string | undefined): string | undefined {
  if (!url) return url;
  // Already static
  if (url.includes('-static.')) return url;
  // Convert .webp to -static.webp
  return url.replace(/\.webp$/, '-static.webp');
}

/**
 * Chat Widget Component
 *
 * A floating chat button that expands into a chat panel.
 * Allows users to interact with Raiko AI assistant via WebSocket.
 *
 * Features:
 * - Floating action button (bottom-right corner)
 * - Expandable chat panel with smooth animations
 * - Real-time chat via WebSocket
 * - Mobile-responsive design
 * - Dark theme consistent with landing page
 * - Accessibility support with ARIA labels
 * - Notification badge for unread messages
 * - Auto-scroll to latest message
 * - Human takeover indicator
 *
 * Design principles:
 * - Non-intrusive when collapsed
 * - Easy to discover and access
 * - Smooth transitions
 * - Maintains visual hierarchy
 */

interface ChatWidgetProps {
  /**
   * Controlled open state
   * @default false
   */
  open?: boolean;

  /**
   * Optional callback when the chat opens/closes
   */
  onOpenChange?: (open: boolean) => void;

  /**
   * Number of unread messages to show badge
   * @default 0
   */
  unreadCount?: number;

  /**
   * Initial message to send when chat opens (used for "Ask Raiko" integration)
   */
  initialMessage?: string;

  /**
   * Callback to clear the initial message after it's been sent
   */
  onInitialMessageSent?: () => void;
}

export function ChatWidget({
  open: controlledOpen,
  onOpenChange,
  unreadCount = 0,
  initialMessage,
  onInitialMessageSent,
}: ChatWidgetProps) {
  // Support both controlled and uncontrolled usage
  const [internalOpen, setInternalOpen] = useState(false);
  const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;

  // Bubble preview state
  const [bubbleMessage, setBubbleMessage] = useState<string | null>(null);
  const [showBubble, setShowBubble] = useState(false);
  const [bubbleDismissed, setBubbleDismissed] = useState(false);
  const [bubbleSender, setBubbleSender] = useState<{
    name: string;
    avatar: string;
    isHuman: boolean;
  }>({ name: 'Raiko', avatar: RAIKO_AVATAR_URL, isHuman: false });

  // Track if this is a returning visitor
  const hasSeenGreeting = useRef<boolean>(false);

  // Check localStorage on mount for returning visitor detection
  useEffect(() => {
    try {
      hasSeenGreeting.current = localStorage.getItem(GREETING_SEEN_KEY) === 'true';
    } catch {
      // localStorage might be unavailable
      hasSeenGreeting.current = false;
    }
  }, []);

  // Personalization
  const { content: personalizedContent } = usePersonalization();

  // WebSocket connection
  const {
    messages,
    sendMessage,
    sendTypingIndicator,
    sendPageUpdate,
    isConnected,
    isLoading,
    isTyping,
    takenOverBy,
    error,
    clearError,
  } = useChatWebSocket({
    autoConnect: true, // Connect immediately on mount
  });

  // Track current page for admin dashboard
  usePageTracker({ sendPageUpdate, isConnected });

  // Analytics tracking
  const { trackEvent, startHeartbeat } = useAnalytics();
  const heartbeatStopRef = useRef<(() => void) | null>(null);

  // Ref for auto-scrolling to bottom
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const isFirstRender = useRef(true);

  // Track chat open/close and manage heartbeat
  useEffect(() => {
    if (isOpen) {
      trackEvent('chat_opened');
      // Start heartbeat for duration tracking
      heartbeatStopRef.current = startHeartbeat('chat');
    } else {
      // Only track close if it was previously open
      if (heartbeatStopRef.current) {
        trackEvent('chat_closed');
        heartbeatStopRef.current();
        heartbeatStopRef.current = null;
      }
    }

    return () => {
      // Cleanup heartbeat on unmount
      if (heartbeatStopRef.current) {
        heartbeatStopRef.current();
        heartbeatStopRef.current = null;
      }
    };
  }, [isOpen, trackEvent, startHeartbeat]);

  const handleToggle = () => {
    const newState = !isOpen;
    if (controlledOpen === undefined) {
      setInternalOpen(newState);
    }
    onOpenChange?.(newState);
  };

  const handleClose = (e?: React.MouseEvent) => {
    e?.preventDefault();
    e?.stopPropagation();
    if (controlledOpen === undefined) {
      setInternalOpen(false);
    }
    onOpenChange?.(false);
  };

  const handleSendMessage = (message: string) => {
    sendMessage(message);
  };

  const handleQuestionClick = (question: string) => {
    sendMessage(question);
  };

  // Auto-scroll to bottom when new messages arrive
  useEffect(() => {
    if (isOpen && messagesEndRef.current) {
      // Use instant scroll on first render, smooth scroll for new messages
      const behavior = isFirstRender.current ? 'instant' : 'smooth';
      messagesEndRef.current.scrollIntoView({ behavior });
      isFirstRender.current = false;
    }
  }, [messages, isOpen]);

  // Send initial message when chat opens with one (e.g., from "Ask Raiko" button)
  useEffect(() => {
    if (isOpen && initialMessage && isConnected) {
      sendMessage(initialMessage);
      onInitialMessageSent?.();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps -- Intentionally omit sendMessage and onInitialMessageSent to avoid re-triggering
  }, [isOpen, initialMessage, isConnected]);

  // Track previous message count to detect new messages
  const prevMessageCountRef = useRef(messages.length);

  // Show bubble preview when a NEW message arrives and chat is closed
  useEffect(() => {
    const prevCount = prevMessageCountRef.current;
    const currentCount = messages.length;

    // Update ref for next comparison
    prevMessageCountRef.current = currentCount;

    // Only react to NEW messages (not on initial load or when user closes)
    if (currentCount > prevCount && currentCount > 0 && !isOpen) {
      const lastMessage = messages[currentCount - 1];

      // Only show bubble for non-user messages
      if (lastMessage.role !== 'user') {
        const isHumanMessage = !!lastMessage.humanName;

        // For automated greetings (Raiko/AI), skip if user already seen greeting before
        // Always show bubble for human messages (founder takeover)
        if (!isHumanMessage && hasSeenGreeting.current) {
          // Return visitor - don't show automated greeting bubble
          return;
        }

        // Show the bubble - always show for human messages, respect bubbleDismissed for AI
        // Human takeover messages are important and should always show a notification
        if (!bubbleDismissed || isHumanMessage) {
          setBubbleMessage(lastMessage.content);
          setBubbleSender({
            name: isHumanMessage ? (lastMessage.humanName || 'Team Member') : 'Raiko',
            avatar: isHumanMessage
              ? toStaticAvatar(lastMessage.humanAvatar) || RAIKO_AVATAR_URL
              : RAIKO_AVATAR_URL,
            isHuman: isHumanMessage,
          });
          setShowBubble(true);

          // Reset bubbleDismissed for human messages so future human messages also show
          if (isHumanMessage && bubbleDismissed) {
            setBubbleDismissed(false);
          }

          // Mark greeting as seen for non-human messages (so return visitors don't see it again)
          if (!isHumanMessage) {
            try {
              localStorage.setItem(GREETING_SEEN_KEY, 'true');
              hasSeenGreeting.current = true;
            } catch {
              // localStorage unavailable
            }
          }
        }
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps -- Use messages.length to detect new messages, access messages array inside effect
  }, [messages.length, isOpen, bubbleDismissed]);

  // Hide bubble when chat opens
  useEffect(() => {
    if (isOpen) {
      setShowBubble(false);
    }
  }, [isOpen]);

  // Bubble dismiss handler
  const handleBubbleDismiss = useCallback(() => {
    setShowBubble(false);
    setBubbleDismissed(true);
  }, []);

  // Bubble click handler (opens chat)
  const handleBubbleClick = useCallback(() => {
    setShowBubble(false);
    if (controlledOpen === undefined) {
      setInternalOpen(true);
    }
    onOpenChange?.(true);
  }, [controlledOpen, onOpenChange]);

  // Determine who is responding (Raiko or human)
  const respondentName = takenOverBy.active ? takenOverBy.name || 'Team Member' : 'Raiko';
  const respondentRole = takenOverBy.active ? takenOverBy.role || 'Support' : 'AI Assistant';

  const content = (
    <>
      {/* Chat Panel - slides in from bottom-right */}
      <div
        className={`
          fixed bottom-24 left-4 right-4 sm:left-auto sm:right-4 md:right-6 lg:right-8 z-[200]
          sm:w-96 md:w-[28rem]
          transition-all duration-300 ease-out
          ${isOpen
            ? 'opacity-100 translate-y-0 pointer-events-auto'
            : 'opacity-0 translate-y-4 pointer-events-none'
          }
        `}
        role="dialog"
        aria-label="Chat with Raiko"
        aria-hidden={!isOpen}
      >
        <div className="bg-surface border border-bright-green/10 rounded-2xl shadow-2xl shadow-black/50 overflow-hidden flex flex-col h-[600px] max-h-[calc(100vh-8rem)]">
          {/* Chat Header - Compact */}
          <div className="flex items-center justify-between px-4 py-2 border-b border-bright-green/10 bg-surface-elevated">
            <div className="flex items-center gap-2">
              {/* Avatar */}
              <div className="relative">
                <div className="w-8 h-8 rounded-full bg-[#2b323a] border border-bright-green/40 flex items-center justify-center overflow-hidden">
                  {takenOverBy.active && takenOverBy.avatar ? (
                    <img
                      src={toStaticAvatar(takenOverBy.avatar)}
                      alt={respondentName}
                      className="w-full h-full rounded-full object-cover"
                    />
                  ) : (
                    <img
                      src="https://kanji.fra1.cdn.digitaloceanspaces.com/raiko-avatar-64-static.webp"
                      alt="Raiko"
                      className="w-full h-[102%] object-cover rounded-full"
                    />
                  )}
                </div>
                {/* Status indicator */}
                <span
                  className={`absolute -bottom-0.5 -right-0.5 w-2.5 h-2.5 rounded-full border-[1.5px] ${isConnected ? 'bg-bright-green' : 'bg-white-30'
                    }`}
                  style={{ borderColor: '#1a1f24' }}
                />
              </div>

              {/* Header Info - Stacked & Centered */}
              <div className="flex flex-col justify-center h-8 pt-4">
                <h3 className="text-sm font-semibold text-white-90 leading-tight">
                  {respondentName}
                </h3>
                <p className="text-[11px] text-white-40 leading-tight">{respondentRole}</p>
              </div>
            </div>

            {/* Close Button */}
            <button
              type="button"
              onClick={handleClose}
              className="w-7 h-7 rounded-md flex items-center justify-center hover:bg-bright-green/10 transition-colors cursor-pointer"
              aria-label="Close chat"
            >
              <svg
                className="w-4 h-4 text-white-40 hover:text-bright-green transition-colors"
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M6 18L18 6M6 6l12 12"
                />
              </svg>
            </button>
          </div>

          {/* Chat Messages Area */}
          <div className="flex-1 overflow-y-auto overflow-x-hidden px-6 py-4 space-y-4 bg-black-soft">
            {/* Loading state */}
            {isLoading && messages.length === 0 && (
              <div className="flex items-center justify-center h-full">
                <div className="text-center">
                  <div className="inline-block w-8 h-8 border-4 border-bright-green border-t-transparent rounded-full animate-spin mb-3"></div>
                  <p className="text-sm text-white-50">Connecting...</p>
                </div>
              </div>
            )}

            {/* Error state */}
            {error && (
              <div className="bg-bright-green/5 border border-bright-green/20 rounded-lg px-4 py-3 mb-4">
                <div className="flex items-start gap-3">
                  <svg
                    className="w-5 h-5 text-bright-green flex-shrink-0 mt-0.5"
                    fill="none"
                    viewBox="0 0 24 24"
                    stroke="currentColor"
                  >
                    <path
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      strokeWidth={2}
                      d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
                    />
                  </svg>
                  <div className="flex-1">
                    <p className="text-sm text-bright-green">{error}</p>
                  </div>
                  <button
                    onClick={clearError}
                    className="text-bright-green hover:text-bright-green-light transition-colors"
                    aria-label="Dismiss error"
                  >
                    <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth={2}
                        d="M6 18L18 6M6 6l12 12"
                      />
                    </svg>
                  </button>
                </div>
              </div>
            )}

            {/* Welcome message (shown when no messages yet) */}
            {!isLoading && messages.length === 0 && !error && (
              <>
                <div className="text-center py-12">
                  <div className="w-16 h-16 mx-auto mb-4 rounded-full bg-bright-green/10 border border-bright-green/20 flex items-center justify-center overflow-hidden">
                    <img
                      src="https://kanji.fra1.cdn.digitaloceanspaces.com/raiko-avatar-64-static.webp"
                      alt="Raiko"
                      className="w-12 h-[102%] object-cover rounded-full"
                    />
                  </div>
                  <h4 className="text-lg font-semibold text-white-90 mb-2">
                    Welcome to Kanji
                  </h4>
                  <p className="text-sm text-white-50 max-w-xs mx-auto mb-6">
                    Hi! I'm Raiko, your guide to the Kanji network. Ask me anything about
                    wallets, invites, or the upcoming $KANJI presale.
                  </p>
                </div>

                {/* Suggested Questions - Personalized based on traffic source */}
                <SuggestedQuestions
                  onQuestionClick={handleQuestionClick}
                  isVisible={true}
                  questions={personalizedContent.suggestedQuestions}
                />
              </>
            )}

            {/* Chat messages */}
            {messages.map((message) => (
              <ChatMessage
                key={message.id}
                role={message.role}
                content={message.content}
                timestamp={message.timestamp}
                humanName={message.humanName}
                humanRole={message.humanRole}
                avatarUrl={toStaticAvatar(message.humanAvatar)}
              />
            ))}

            {/* Typing indicator */}
            {isTyping && (
              <TypingIndicator
                type={takenOverBy.active ? 'human' : 'assistant'}
                name={takenOverBy.active ? takenOverBy.name : undefined}
                avatarUrl={takenOverBy.active ? toStaticAvatar(takenOverBy.avatar) : undefined}
              />
            )}

            {/* Auto-scroll anchor */}
            <div ref={messagesEndRef} />
          </div>

          {/* Chat Input Area - Compact */}
          <div className="px-3 py-2.5 border-t border-bright-green/10 bg-surface-elevated">
            <MessageInput
              onSend={handleSendMessage}
              onTyping={sendTypingIndicator}
              placeholder={
                !isConnected
                  ? 'Connecting...'
                  : takenOverBy.active
                    ? `Message ${respondentName}...`
                    : 'Ask Raiko anything...'
              }
              disabled={!isConnected || isLoading}
            />
          </div>
        </div>
      </div>

      {/* Bubble Preview - shows when message arrives and chat is closed */}
      {showBubble && !isOpen && bubbleMessage && (
        <ChatBubblePreview
          message={bubbleMessage}
          avatar={bubbleSender.avatar}
          name={bubbleSender.name}
          onDismiss={handleBubbleDismiss}
          onClick={handleBubbleClick}
        />
      )}

      {/* Breathing glow behind button */}
      {!isOpen && (
        <span
          className="fixed bottom-4 right-4 md:bottom-6 md:right-6 lg:bottom-8 lg:right-8 w-14 h-14 md:w-16 md:h-16 rounded-full bg-bright-green animate-breathe z-[198] pointer-events-none"
        />
      )}

      {/* Floating Action Button */}
      <button
        onClick={handleToggle}
        className={`
          fixed bottom-4 right-4 md:bottom-6 md:right-6 lg:bottom-8 lg:right-8 z-[199]
          w-14 h-14 md:w-16 md:h-16
          rounded-full overflow-hidden
          shadow-lg shadow-gold/10 hover:shadow-gold/20
          transition-all duration-200
          ${isOpen ? 'scale-100 pointer-events-auto' : 'animate-breathe-scale pointer-events-auto'}
        `}
        aria-label={isOpen ? 'Close chat' : `Open chat with ${respondentName}`}
        aria-expanded={isOpen}
      >
        {/* Avatar - Show admin avatar if taken over, otherwise Raiko */}
        {takenOverBy.active && takenOverBy.avatar ? (
          <img
            src={takenOverBy.avatar}
            alt={`Chat with ${respondentName}`}
            className="w-full h-full object-cover"
          />
        ) : (
          <img
            src="https://kanji.fra1.cdn.digitaloceanspaces.com/raiko-avatar-64.webp"
            alt="Chat with Raiko"
            className="w-full h-[105%] -mt-[3%] object-cover"
          />
        )}

        {/* Unread Badge */}
        {unreadCount > 0 && !isOpen && (
          <span className="absolute -top-1 -right-1 w-6 h-6 bg-bright-green rounded-full flex items-center justify-center text-xs font-bold text-black border-2 border-black">
            {unreadCount > 9 ? '9+' : unreadCount}
          </span>
        )}
      </button>
    </>
  );

  // Render via portal directly to body - this ensures chat widget
  // is always rendered after Radix Dialog portals in DOM order
  if (typeof document !== 'undefined') {
    return createPortal(content, document.body);
  }

  return content;
}
