import { useState, useEffect, useRef, useCallback } from 'react';
import {
  Input,
  Button,
  Space,
  Typography,
  Tag,
  Alert,
  Spin,
  theme,
  Avatar,
} from 'antd';
import {
  SendOutlined,
  UserOutlined,
  WarningOutlined,
  CheckCircleOutlined,
  ArrowDownOutlined,
} from '@ant-design/icons';
import { useMediaAuth } from '@/contexts/MediaAuthContext';
import { mediaPublicApi } from '@/lib/media-public-api';
import { mediaApi } from '@/lib/media-api';
import axios from 'axios';

const { Text } = Typography;
const { TextArea } = Input;

interface Comment {
  id: number;
  type: 'comment';
  content: string;
  createdAt: string;
  safetyStatus?: string | null;
  safetyCategories?: any;
  user: {
    id: string;
    name: string;
  } | null;
}

interface Reaction {
  id: number;
  type: 'reaction';
  reactionType: string;
  emoji: string;
  videoTimestamp: number;
  formattedTime: string;
  createdAt: string;
  user: {
    id: string;
    name: string;
  } | null;
}

type TimelineItem = Comment | Reaction;

interface LiveChatProps {
  videoId: number;
  isOpen: boolean;
  onRequestLogin?: () => void;
  flexWidth?: boolean; // For vertical video side-by-side layout (future use)
}

export default function LiveChat({
  videoId,
  isOpen,
  onRequestLogin,
}: LiveChatProps) {
  const { token } = theme.useToken();
  const { isAuthenticated, isApproved } = useMediaAuth();

  // Timeline state
  const [timeline, setTimeline] = useState<TimelineItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // Input state
  const [commentInput, setCommentInput] = useState('');
  const [submitting, setSubmitting] = useState(false);

  // SSE state
  const [sseConnected, setSSEConnected] = useState(false);
  const eventSourceRef = useRef<EventSource | null>(null);

  // Scroll state
  const scrollContainerRef = useRef<HTMLDivElement>(null);
  const [isNearBottom, setIsNearBottom] = useState(true);
  const [showNewMessagesButton, setShowNewMessagesButton] = useState(false);

  // Auto-scroll to bottom
  const scrollToBottom = useCallback((smooth = true) => {
    if (scrollContainerRef.current) {
      scrollContainerRef.current.scrollTo({
        top: scrollContainerRef.current.scrollHeight,
        behavior: smooth ? 'smooth' : 'auto',
      });
      setShowNewMessagesButton(false);
    }
  }, []);

  // Check if user is near bottom (within 100px)
  const checkScrollPosition = useCallback(() => {
    if (!scrollContainerRef.current) return;

    const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current;
    const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
    const nearBottom = distanceFromBottom < 100;

    setIsNearBottom(nearBottom);

    if (!nearBottom && !showNewMessagesButton) {
      setShowNewMessagesButton(true);
    }
  }, [showNewMessagesButton]);

  // Fetch initial comments and reactions
  const fetchInitialTimeline = async () => {
    try {
      setLoading(true);
      setError(null);

      // Use relative URLs to go through nginx proxy instead of direct media API access
      // This avoids SSL certificate issues in production and works for both admin and public gallery
      const [commentsRes, reactionsRes] = await Promise.all([
        fetch(`/media/public/${videoId}/comments?limit=200`),
        fetch(`/media/reactions/${videoId}/chat?limit=500`),
      ]);

      if (!commentsRes.ok || !reactionsRes.ok) {
        throw new Error('Failed to fetch timeline');
      }

      const commentsData = await commentsRes.json();
      const reactionsData = await reactionsRes.json();

      const comments: Comment[] = commentsData.comments.map((c: any) => ({
        ...c,
        type: 'comment' as const,
      }));

      const reactions: Reaction[] = reactionsData.reactions.map((r: any) => ({
        ...r,
        type: 'reaction' as const,
      }));

      // Merge and sort by createdAt
      const merged = [...comments, ...reactions].sort(
        (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
      );

      setTimeline(merged);

      // Scroll to bottom after loading
      setTimeout(() => scrollToBottom(false), 100);
    } catch (err) {
      console.error('Failed to fetch timeline:', err);
      setError('Failed to load chat. Please refresh the page.');
    } finally {
      setLoading(false);
    }
  };

  // Setup SSE connection
  const setupSSE = useCallback(() => {
    if (!isOpen || eventSourceRef.current) return;

    // Use relative URL to go through nginx proxy
    const sseUrl = `/media/public/${videoId}/chat-stream`;

    const eventSource = new EventSource(sseUrl);

    eventSource.onopen = () => {
      console.log('SSE connected');
      setSSEConnected(true);
    };

    eventSource.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data);

        if (data.type === 'connected') {
          console.log('SSE connection confirmed for video', data.videoId);
          return;
        }

        if (data.type === 'new_comment') {
          const newComment: Comment = {
            ...data.comment,
            type: 'comment',
          };

          setTimeline((prev) => {
            // Check for duplicates
            if (prev.some((item) => item.type === 'comment' && item.id === newComment.id)) {
              return prev;
            }
            // Add to timeline (respecting max limit)
            const updated = [...prev, newComment];
            return updated.slice(-200); // Keep last 200 comments
          });

          // Auto-scroll if near bottom
          if (isNearBottom) {
            setTimeout(() => scrollToBottom(), 100);
          } else {
            setShowNewMessagesButton(true);
          }
        }

        if (data.type === 'new_reaction') {
          const newReaction: Reaction = {
            ...data.reaction,
            type: 'reaction',
          };

          setTimeline((prev) => {
            // Check for duplicates
            if (prev.some((item) => item.type === 'reaction' && item.id === newReaction.id)) {
              return prev;
            }
            // Add to timeline (respecting max limit)
            const updated = [...prev, newReaction];
            return updated.slice(-500); // Keep last 500 reactions
          });

          // Auto-scroll if near bottom
          if (isNearBottom) {
            setTimeout(() => scrollToBottom(), 100);
          } else {
            setShowNewMessagesButton(true);
          }
        }
      } catch (err) {
        console.error('Failed to parse SSE message:', err);
      }
    };

    eventSource.onerror = () => {
      console.error('SSE connection error');
      setSSEConnected(false);

      // Auto-reconnect after 3 seconds
      setTimeout(() => {
        if (eventSourceRef.current) {
          eventSourceRef.current.close();
          eventSourceRef.current = null;
        }
        setupSSE();
      }, 3000);
    };

    eventSourceRef.current = eventSource;
  }, [isOpen, videoId, isNearBottom, scrollToBottom]);

  // Cleanup SSE on unmount or when closed
  useEffect(() => {
    return () => {
      if (eventSourceRef.current) {
        eventSourceRef.current.close();
        eventSourceRef.current = null;
      }
    };
  }, []);

  // Mark thread as read when chat opens
  const markAsRead = useCallback(async () => {
    if (!isAuthenticated) return;
    try {
      await mediaApi.post(`/media/chat/threads/${videoId}/read`);
    } catch {
      // Non-critical
    }
  }, [videoId, isAuthenticated]);

  // Fetch timeline and setup SSE when component opens
  useEffect(() => {
    if (isOpen) {
      fetchInitialTimeline();
      setupSSE();
      markAsRead();
    }
  }, [isOpen, videoId, setupSSE, markAsRead]);

  // Handle comment submission
  const handleSubmitComment = async () => {
    if (!commentInput.trim() || submitting) return;

    if (!isAuthenticated) {
      if (onRequestLogin) {
        onRequestLogin();
      }
      return;
    }

    try {
      setSubmitting(true);

      await mediaPublicApi.post(`/public/${videoId}/comments`, {
        content: commentInput.trim(),
      });

      // Clear input
      setCommentInput('');

      // Note: New comment will appear via SSE broadcast
    } catch (err: unknown) {
      console.error('Failed to submit comment:', err);

      if (axios.isAxiosError(err) && err.response?.status === 429) {
        alert('Rate limit exceeded. Please wait a minute before commenting again.');
      } else if (axios.isAxiosError(err) && err.response?.status === 401) {
        alert('Please log in to comment.');
        if (onRequestLogin) {
          onRequestLogin();
        }
      } else {
        alert('Failed to submit comment. Please try again.');
      }
    } finally {
      setSubmitting(false);
    }
  };

  // Format relative time (e.g., "2m ago")
  const formatRelativeTime = (isoString: string) => {
    const now = new Date().getTime();
    const then = new Date(isoString).getTime();
    const diffSeconds = Math.floor((now - then) / 1000);

    if (diffSeconds < 60) return 'just now';
    if (diffSeconds < 3600) return `${Math.floor(diffSeconds / 60)}m ago`;
    if (diffSeconds < 86400) return `${Math.floor(diffSeconds / 3600)}h ago`;
    return `${Math.floor(diffSeconds / 86400)}d ago`;
  };

  // Render timeline item
  const renderTimelineItem = (item: TimelineItem) => {
    if (item.type === 'comment') {
      const isFlagged = item.safetyStatus === 'flagged';
      const isApproved = item.safetyStatus === 'approved';

      return (
        <div
          key={`comment-${item.id}`}
          style={{
            padding: '12px 16px',
            borderBottom: `1px solid ${token.colorBorderSecondary}`,
            opacity: isFlagged ? 0.7 : 1,
          }}
        >
          <Space direction="vertical" size={4} style={{ width: '100%' }}>
            {/* Header: User + Time + Badges */}
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <Avatar size="small" icon={<UserOutlined />} />
              <Text strong style={{ fontSize: 13 }}>
                {item.user?.name || 'Anonymous'}
              </Text>
              <Text type="secondary" style={{ fontSize: 12 }}>
                {formatRelativeTime(item.createdAt)}
              </Text>

              {/* Safety/Moderation Badges */}
              {isFlagged && (
                <Tag
                  color="warning"
                  icon={<WarningOutlined />}
                  style={{ fontSize: 11, marginLeft: 'auto' }}
                >
                  Flagged
                </Tag>
              )}
              {isApproved && (
                <Tag
                  color="success"
                  icon={<CheckCircleOutlined />}
                  style={{ fontSize: 11, marginLeft: isFlagged ? 0 : 'auto' }}
                >
                  Verified
                </Tag>
              )}
            </div>

            {/* Comment Content */}
            <Text style={{ fontSize: 14, whiteSpace: 'pre-wrap' }}>
              {item.content}
            </Text>

            {/* Safety Categories */}
            {isFlagged && item.safetyCategories && (
              <div style={{ marginTop: 4 }}>
                <Text type="warning" style={{ fontSize: 11 }}>
                  ⚠️ {JSON.stringify(item.safetyCategories)}
                </Text>
              </div>
            )}
          </Space>
        </div>
      );
    }

    if (item.type === 'reaction') {
      return (
        <div
          key={`reaction-${item.id}`}
          style={{
            padding: '8px 16px',
            borderBottom: `1px solid ${token.colorBorderSecondary}`,
            background: token.colorBgLayout,
          }}
        >
          <Space size={8}>
            <Text style={{ fontSize: 20 }}>{item.emoji}</Text>
            <Text style={{ fontSize: 12 }}>
              <Text strong>{item.user?.name || 'Anonymous'}</Text>
              {' reacted at '}
              <Text type="secondary">{item.formattedTime}</Text>
            </Text>
          </Space>
        </div>
      );
    }

    return null;
  };

  return (
    <div
      style={{
        display: 'flex',
        flexDirection: 'column',
        height: '100%',
        background: token.colorBgContainer,
      }}
    >
      {/* Header */}
      <div
        style={{
          padding: 16,
          borderBottom: `1px solid ${token.colorBorder}`,
          background: token.colorBgLayout,
        }}
      >
        <Space>
          <Text strong>Live Chat</Text>
          {sseConnected && (
            <Tag color="success" style={{ fontSize: 11 }}>
              Live
            </Tag>
          )}
          {!sseConnected && !loading && (
            <Tag color="default" style={{ fontSize: 11 }}>
              Connecting...
            </Tag>
          )}
        </Space>
      </div>

      {/* Timeline */}
      <div
        ref={scrollContainerRef}
        onScroll={checkScrollPosition}
        style={{
          flex: 1,
          overflowY: 'auto',
          position: 'relative',
        }}
      >
        {loading && (
          <div style={{ padding: 60, textAlign: 'center' }}>
            <Spin size="large" tip="Loading chat..." />
          </div>
        )}

        {error && (
          <div style={{ padding: 16 }}>
            <Alert message={error} type="error" showIcon />
          </div>
        )}

        {!loading && !error && timeline.length === 0 && (
          <div style={{ padding: 60, textAlign: 'center' }}>
            <Text type="secondary">No messages yet. Be the first to comment!</Text>
          </div>
        )}

        {!loading && !error && timeline.map(renderTimelineItem)}

        {/* New Messages Button */}
        {showNewMessagesButton && (
          <div
            style={{
              position: 'absolute',
              bottom: 16,
              left: '50%',
              transform: 'translateX(-50%)',
              zIndex: 10,
            }}
          >
            <Button
              type="primary"
              icon={<ArrowDownOutlined />}
              onClick={() => scrollToBottom()}
              size="small"
            >
              New messages ↓
            </Button>
          </div>
        )}
      </div>

      {/* Comment Input */}
      {!isApproved && isAuthenticated && (
        <div style={{ padding: 16, borderTop: `1px solid ${token.colorBorder}` }}>
          <Alert
            message="Account pending approval"
            description="Your account is pending approval. You'll be able to comment once approved."
            type="info"
            showIcon
            closable
          />
        </div>
      )}

      {!isAuthenticated && (
        <div style={{ padding: 16, borderTop: `1px solid ${token.colorBorder}` }}>
          <Alert
            message="Login required"
            description={
              <span>
                Please{' '}
                <Button type="link" size="small" onClick={onRequestLogin} style={{ padding: 0 }}>
                  log in
                </Button>{' '}
                to join the conversation.
              </span>
            }
            type="info"
            showIcon
          />
        </div>
      )}

      {isAuthenticated && isApproved && (
        <div
          style={{
            padding: 16,
            borderTop: `1px solid ${token.colorBorder}`,
            background: token.colorBgLayout,
          }}
        >
          <Space.Compact style={{ width: '100%' }}>
            <TextArea
              value={commentInput}
              onChange={(e) => setCommentInput(e.target.value)}
              onPressEnter={(e) => {
                if (!e.shiftKey) {
                  e.preventDefault();
                  handleSubmitComment();
                }
              }}
              placeholder="Type a message... (Shift+Enter for new line)"
              maxLength={1000}
              autoSize={{ minRows: 1, maxRows: 4 }}
              disabled={submitting}
            />
            <Button
              type="primary"
              icon={<SendOutlined />}
              onClick={handleSubmitComment}
              loading={submitting}
              disabled={!commentInput.trim()}
            >
              Send
            </Button>
          </Space.Compact>
          <Text type="secondary" style={{ fontSize: 11, marginTop: 4, display: 'block' }}>
            {commentInput.length}/1000
          </Text>
        </div>
      )}
    </div>
  );
}
