'use client';

import React, { useState, useEffect, useRef, useCallback } from 'react';
import { X, MessageChatSquare } from '@untitledui/icons';
import { Avatar } from '../elements/avatar/avatar';
import { cx } from '../../utils/cx';

interface Message {
  id: string;
  body: string;
  sender_type: 'contact' | 'agent' | 'human';
  sender_display_name: string;
  created_at: string;
}

interface TeamMember {
  id: number;
  name: string;
  position?: string;
  photo_url?: string;
}

interface ChatWidgetProps {
  position?: 'bottom-right' | 'bottom-left';
  primaryColor?: string;
  sessionId?: string;
  displayName?: string;
  teamMembers?: TeamMember[];
}

// Format timestamp to display format
const formatTime = (isoString: string) => {
  const date = new Date(isoString);
  const now = new Date();
  const diffMs = now.getTime() - date.getTime();
  const diffMins = Math.floor(diffMs / 60000);
  
  if (diffMins < 1) return 'Just now';
  if (diffMins < 60) return `${diffMins}m ago`;
  
  const diffHours = Math.floor(diffMins / 60);
  if (diffHours < 24) return `${diffHours}h ago`;
  
  // Format as time if today, date if older
  const isToday = date.toDateString() === now.toDateString();
  if (isToday) {
    return date.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' });
  }
  
  return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
};

export function ChatWidget({
  position = 'bottom-right',
  primaryColor,
  sessionId: providedSessionId,
  displayName: providedDisplayName,
  teamMembers = []
}: ChatWidgetProps) {
  const [isOpen, setIsOpen] = useState(false);
  const [messages, setMessages] = useState<Message[]>([]);
  const [inputValue, setInputValue] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [sessionId, setSessionId] = useState<string>('');
  const [waitingForReply, setWaitingForReply] = useState(false);
  const messagesEndRef = useRef<HTMLDivElement>(null);

  // Generate or retrieve session ID
  useEffect(() => {
    if (providedSessionId) {
      setSessionId(providedSessionId);
    } else {
      const stored = localStorage.getItem('keystone_chat_session_id');
      if (stored) {
        setSessionId(stored);
      } else {
        const newId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
        localStorage.setItem('keystone_chat_session_id', newId);
        setSessionId(newId);
      }
    }
  }, [providedSessionId]);

  const loadMessages = useCallback(async () => {
    try {
      const response = await fetch(`/api/chat?identifier=${encodeURIComponent(sessionId)}`);
      
      if (response.ok) {
        const result = await response.json();
        const newMessages = result.data || [];
        setMessages(newMessages);
        return newMessages;
      }
    } catch (error) {
      console.error('Failed to load messages:', error);
    }
    return [];
  }, [sessionId]);

  // Load message history when opened
  useEffect(() => {
    if (isOpen && sessionId) {
      loadMessages();
    }
  }, [isOpen, sessionId, loadMessages]);

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

  // Poll for agent reply (simpler than WebSockets for public widget)
  const pollForAgentReply = () => {
    setWaitingForReply(true);
    
    const initialCount = messages.length;
    let attempts = 0;
    const maxAttempts = 30; // 30 seconds max
    
    console.log(`[ChatWidget] Starting poll for agent reply (initial count: ${initialCount})`);
    
    const pollInterval = setInterval(async () => {
      attempts++;
      
      try {
        const newMessages = await loadMessages();
        console.log(`[ChatWidget] Poll attempt ${attempts}: got ${newMessages.length} messages (initial: ${initialCount})`);
        
        // Check if we got a new agent message
        if (newMessages.length > initialCount) {
          const latestMessage = newMessages[newMessages.length - 1];
          console.log(`[ChatWidget] New message detected: sender_type=${latestMessage.sender_type}, body=${latestMessage.body?.substring(0, 50)}`);
          
          if (latestMessage.sender_type === 'agent') {
            console.log('[ChatWidget] ✓ Received agent reply!');
            clearInterval(pollInterval);
            setWaitingForReply(false);
            setIsLoading(false);
          }
        }
        
        // Stop polling after max attempts
        if (attempts >= maxAttempts) {
          console.warn('[ChatWidget] ⚠ Polling timeout - no reply received after 30s');
          clearInterval(pollInterval);
          setWaitingForReply(false);
          setIsLoading(false);
        }
      } catch (error) {
        console.error('[ChatWidget] Error polling for messages:', error);
      }
    }, 1000); // Poll every second
  };

  const sendMessage = async () => {
    if (!inputValue.trim() || !sessionId) return;

    const messageText = inputValue.trim();
    setInputValue('');
    setIsLoading(true);

    // Optimistically add user message
    const tempMessage: Message = {
      id: `temp_${Date.now()}`,
      body: messageText,
      sender_type: 'contact',
      sender_display_name: providedDisplayName || 'You',
      created_at: new Date().toISOString()
    };
    setMessages(prev => [...prev, tempMessage]);

    try {
      const response = await fetch('/api/chat', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          identifier: sessionId,
          body: messageText,
          display_name: providedDisplayName,
          page_url: window.location.href
        })
      });

      if (response.ok) {
        const result = await response.json();
        
        // Message sent successfully
        if (result.data?.job_id) {
          // Job is processing - poll for the reply
          pollForAgentReply();
        } else if (result.data?.status === 'agent_unavailable' || result.data?.status === 'no_auto_reply') {
          // No agent reply expected
          setIsLoading(false);
        } else {
          // Reload messages to get the actual stored message
          await loadMessages();
          setIsLoading(false);
        }
      } else {
        // Remove temp message on error
        setMessages(prev => prev.filter(m => m.id !== tempMessage.id));
        console.error('Failed to send message');
        setIsLoading(false);
      }
    } catch (error) {
      setMessages(prev => prev.filter(m => m.id !== tempMessage.id));
      console.error('Failed to send message:', error);
      setIsLoading(false);
    }
  };

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

  // Use CSS custom properties for dynamic brand color if provided
  const customColorVars = primaryColor ? {
    '--widget-primary': primaryColor,
    '--widget-primary-hover': `color-mix(in srgb, ${primaryColor} 90%, black)`
  } as React.CSSProperties : undefined;

  const widgetBrandClass = primaryColor ? 'bg-[var(--widget-primary)]' : 'bg-brand-solid';
  const widgetBrandHoverClass = primaryColor ? 'hover:bg-[var(--widget-primary-hover)]' : 'hover:bg-brand-solid_hover';

  return (
    <div 
      className={cx(
        "fixed z-[9999]",
        position === 'bottom-right' ? "bottom-5 right-5" : "bottom-5 left-5"
      )}
      style={customColorVars}
    >
      {/* Chat button */}
      {!isOpen && (
        <button
          onClick={() => setIsOpen(true)}
          className={cx(
            "flex size-15 items-center justify-center rounded-full border-none text-white shadow-xl transition-transform duration-200 hover:scale-105 focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand",
            widgetBrandClass
          )}
          aria-label="Open chat"
        >
          <MessageChatSquare className="size-6" />
        </button>
      )}

      {/* Chat window */}
      {isOpen && (
        <div className="flex h-[500px] w-[380px] flex-col overflow-hidden rounded-xl bg-primary shadow-2xl ring-1 ring-secondary ring-inset">
          {/* Header */}
          <div className={cx(
            "flex items-center justify-between gap-3 p-4 text-white",
            widgetBrandClass
          )}>
            <div className="flex min-w-0 flex-1 flex-col gap-2">
              <h3 className="m-0 text-lg font-semibold leading-tight">Chat with us</h3>
              
              {/* Team facepile - only show members with photos */}
              {(() => {
                const membersWithPhotos = teamMembers.filter(m => m.photo_url);
                if (membersWithPhotos.length === 0) return null;
                
                return (
                  <div className="flex -space-x-2">
                    {membersWithPhotos.slice(0, 5).map((member) => (
                      <Avatar
                        key={member.id}
                        size="xs"
                        src={member.photo_url}
                        alt={member.name}
                        className="bg-white ring-2 ring-white"
                      />
                    ))}
                    
                    {membersWithPhotos.length > 5 && (
                      <Avatar
                        size="xs"
                        className="bg-white ring-2 ring-white"
                        placeholder={
                          <span className="flex items-center justify-center text-xs font-semibold text-tertiary">
                            +{membersWithPhotos.length - 5}
                          </span>
                        }
                      />
                    )}
                  </div>
                );
              })()}
            </div>
            
            <button
              onClick={() => setIsOpen(false)}
              className="cursor-pointer rounded-md p-1 text-white outline-none transition-colors hover:bg-white/10 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
              aria-label="Close chat"
            >
              <X className="size-5" />
            </button>
          </div>

          {/* Messages */}
          <ul className="flex flex-1 flex-col gap-4 overflow-y-auto px-4 py-4">
            {messages.length === 0 && (
              <li className="mt-5 text-center text-sm text-quaternary">
                Start a conversation! We&apos;re here to help.
              </li>
            )}
            
            {messages.map((message, index) => {
              const isUser = message.sender_type === 'contact';
              const prevMessage = index > 0 ? messages[index - 1] : null;
              const showAvatar = !isUser && (!prevMessage || prevMessage.sender_type === 'contact');
              
              return (
                <li 
                  key={message.id}
                  className={cx(
                    "relative flex items-start gap-3",
                    isUser ? "self-end pl-10" : "pr-8"
                  )}
                >
                  {/* Avatar for agent messages */}
                  {!isUser && showAvatar && (
                    <Avatar 
                      size="sm"
                      className="shrink-0"
                      src={teamMembers[0]?.photo_url}
                      alt={teamMembers[0]?.name || message.sender_display_name}
                      initials={
                        teamMembers[0]?.photo_url ? undefined :
                        (teamMembers[0]?.name || message.sender_display_name)
                          .split(' ')
                          .map(n => n[0])
                          .join('')
                          .toUpperCase()
                          .slice(0, 2)
                      }
                    />
                  )}
                  {!isUser && !showAvatar && (
                    <div className="size-8 shrink-0" /> 
                  )}

                  {/* Message content */}
                  <article className="flex min-w-0 flex-1 flex-col gap-1">
                    {/* Sender name and timestamp */}
                    <header className="flex items-center gap-2 px-0.5">
                      <cite className="flex-1 truncate text-xs font-medium text-tertiary not-italic">
                        {isUser ? (providedDisplayName || 'You') : message.sender_display_name}
                      </cite>
                      <time className="text-xs text-quaternary" dateTime={message.created_at}>
                        {formatTime(message.created_at)}
                      </time>
                    </header>

                    {/* Message bubble */}
                    <div
                      className={cx(
                        "rounded-xl px-3.5 py-2.5 text-sm leading-relaxed ring-1 ring-inset",
                        isUser 
                          ? cx(
                              "rounded-tr-none text-white ring-transparent",
                              widgetBrandClass
                            )
                          : "rounded-tl-none bg-secondary text-primary ring-secondary"
                      )}
                    >
                      {message.body}
                    </div>
                  </article>
                </li>
              );
            })}
            
            {/* Typing indicator */}
            {waitingForReply && (
              <li className="relative flex items-start gap-3 pr-8">
                <Avatar size="sm" className="shrink-0" />
                <article className="flex min-w-0 flex-1 flex-col gap-1">
                  <div className="flex h-9 w-16 items-center justify-center gap-1 rounded-xl rounded-tl-none bg-secondary ring-1 ring-inset ring-secondary">
                    <div className="size-1.5 animate-bounce rounded-full bg-fg-tertiary [animation-delay:-0.3s]" />
                    <div className="size-1.5 animate-bounce rounded-full bg-fg-quaternary [animation-delay:-0.15s]" />
                    <div className="size-1.5 animate-bounce rounded-full bg-fg-tertiary" />
                  </div>
                </article>
              </li>
            )}
            
            <div ref={messagesEndRef} />
          </ul>

          {/* Input */}
          <div className="flex gap-2 border-t border-secondary p-3">
            <input
              type="text"
              value={inputValue}
              onChange={(e) => setInputValue(e.target.value)}
              onKeyPress={handleKeyPress}
              placeholder="Type a message..."
              disabled={isLoading}
              className="flex-1 rounded-lg border border-secondary bg-primary px-3 py-2.5 text-sm text-primary outline-none ring-brand transition-colors placeholder:text-placeholder focus:border-brand focus:ring-1 disabled:cursor-not-allowed disabled:bg-disabled"
            />
            <button
              onClick={sendMessage}
              disabled={isLoading || !inputValue.trim()}
              className={cx(
                "rounded-lg border-none px-4 py-2.5 text-sm font-medium text-white transition-opacity focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2",
                widgetBrandClass,
                widgetBrandHoverClass,
                (isLoading || !inputValue.trim())
                  ? "cursor-not-allowed opacity-50"
                  : "cursor-pointer focus-visible:outline-brand"
              )}
            >
              {isLoading ? '...' : 'Send'}
            </button>
          </div>
        </div>
      )}
    </div>
  );
}
