import { useState } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { Input } from "@/components/ui/input";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Separator } from "@/components/ui/separator";
import { ThumbsUp, ThumbsDown, ChevronDown, ChevronUp, ArrowUpDown } from "lucide-react";
import { formatTimeAgo } from "@/lib/utils";
import { apiRequest } from "@/lib/queryClient";
import AvatarPreviewDialog from "@/components/AvatarPreviewDialog";

interface Comment {
  id: string;
  content: string;
  nickname: string;
  avatar?: string;
  createdAt: string;
  likesCount: number;
  dislikesCount: number;
  repliesCount: number;
  parentId?: string;
}

interface CommentSectionProps {
  articleId: string;
}

function getUserIdentifier() {
  let userId = localStorage.getItem('commentUserId');
  if (!userId) {
    userId = 'user_' + Math.random().toString(36).substring(2, 15);
    localStorage.setItem('commentUserId', userId);
  }
  return userId;
}

function CommentForm({ 
  articleId, 
  parentId, 
  onSuccess, 
  placeholder = "Add comment...",
  buttonText = "Comment"
}: {
  articleId: string;
  parentId?: string;
  onSuccess?: () => void;
  placeholder?: string;
  buttonText?: string;
}) {
  const [content, setContent] = useState("");
  const [nickname, setNickname] = useState(() => 
    localStorage.getItem('commentNickname') || ""
  );
  const [showForm, setShowForm] = useState(false);
  const [isFocused, setIsFocused] = useState(false);
  const queryClient = useQueryClient();

  const createComment = useMutation({
    mutationFn: async (data: { content: string; nickname: string; parentId?: string }) => {
      const response = await apiRequest('POST', `/api/articles/${articleId}/comments`, data);
      return response.json();
    },
    onSuccess: () => {
      setContent("");
      setShowForm(false);
      setIsFocused(false);
      localStorage.setItem('commentNickname', nickname);
      queryClient.invalidateQueries({ queryKey: ['/api/articles', articleId, 'comments'] });
      if (parentId) {
        queryClient.invalidateQueries({ queryKey: ['/api/comments', parentId, 'replies'] });
      }
      onSuccess?.();
    },
  });

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (!content.trim() || !nickname.trim()) return;
    
    createComment.mutate({
      content: content.trim(),
      nickname: nickname.trim(),
      parentId
    });
  };

  if (!showForm && parentId) {
    return (
      <Button
        variant="ghost"
        size="sm"
        onClick={() => setShowForm(true)}
        className="text-sm font-normal p-0 h-auto hover:bg-transparent text-muted-foreground hover:text-foreground"
        data-testid="button-reply"
      >
        Reply
      </Button>
    );
  }

  if (!showForm && !parentId) {
    return (
      <div className="mb-6">
        <div 
          className="flex items-start gap-3"
          onClick={() => setShowForm(true)}
          data-testid="button-add-comment"
        >
          <Avatar className="w-10 h-10 flex-shrink-0">
            <AvatarFallback>👤</AvatarFallback>
          </Avatar>
          <div className="flex-1">
            <div className="border-b-2 border-muted hover:border-foreground transition-colors cursor-text py-2">
              <span className="text-muted-foreground text-sm">{placeholder}</span>
            </div>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="mb-6">
      <form onSubmit={handleSubmit} className="space-y-3">
        <div className="flex items-start gap-3">
          <Avatar className="w-10 h-10 flex-shrink-0">
            <AvatarFallback>👤</AvatarFallback>
          </Avatar>
          <div className="flex-1 space-y-3">
            {!localStorage.getItem('commentNickname') && (
              <Input
                placeholder="Enter your nickname"
                value={nickname}
                onChange={(e) => setNickname(e.target.value)}
                className="border-0 border-b-2 border-muted rounded-none bg-transparent px-0 focus-visible:ring-0 focus-visible:border-foreground"
                data-testid="input-nickname"
                required
              />
            )}
            <Textarea
              placeholder={placeholder}
              value={content}
              onChange={(e) => setContent(e.target.value)}
              onFocus={() => setIsFocused(true)}
              className="min-h-[60px] border-0 border-b-2 border-muted rounded-none bg-transparent px-0 resize-none focus-visible:ring-0 focus-visible:border-foreground"
              data-testid="textarea-comment"
              required
            />
            {(isFocused || content) && (
              <div className="flex justify-end gap-2 pt-2">
                <Button
                  type="button"
                  variant="ghost"
                  size="sm"
                  onClick={() => {
                    setShowForm(false);
                    setContent("");
                    setIsFocused(false);
                  }}
                  data-testid="button-cancel-comment"
                  className="h-9 px-4 rounded-full"
                >
                  Cancel
                </Button>
                <Button
                  type="submit"
                  size="sm"
                  disabled={!content.trim() || !nickname.trim() || createComment.isPending}
                  data-testid="button-submit-comment"
                  className="h-9 px-4 rounded-full"
                >
                  {createComment.isPending ? "Posting..." : buttonText}
                </Button>
              </div>
            )}
          </div>
        </div>
      </form>
    </div>
  );
}

function CommentItem({ comment, articleId, level = 0 }: { 
  comment: Comment; 
  articleId: string; 
  level?: number;
}) {
  const [showReplies, setShowReplies] = useState(false);
  const [showReplyForm, setShowReplyForm] = useState(false);
  const [userReaction, setUserReaction] = useState<'like' | 'dislike' | null>(null);
  const queryClient = useQueryClient();
  const userIdentifier = getUserIdentifier();

  const { data: reactionData } = useQuery({
    queryKey: ['/api/comments', comment.id, 'reactions', userIdentifier],
    queryFn: async () => {
      const response = await apiRequest('GET', `/api/comments/${comment.id}/reactions/${userIdentifier}`);
      return response.json();
    },
  });

  const { data: repliesData } = useQuery({
    queryKey: ['/api/comments', comment.id, 'replies'],
    queryFn: async () => {
      const response = await apiRequest('GET', `/api/comments/${comment.id}/replies`);
      return response.json();
    },
    enabled: showReplies && comment.repliesCount > 0,
  });

  const toggleReaction = useMutation({
    mutationFn: async (reactionType: 'like' | 'dislike') => {
      const response = await apiRequest('POST', `/api/comments/${comment.id}/reactions`, {
        reactionType, 
        userIdentifier
      });
      return response.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['/api/articles', articleId, 'comments'] });
      queryClient.invalidateQueries({ queryKey: ['/api/comments', comment.id, 'reactions', userIdentifier] });
    },
  });

  const currentReaction = reactionData?.reactionType || userReaction;

  const handleReaction = (reactionType: 'like' | 'dislike') => {
    setUserReaction(currentReaction === reactionType ? null : reactionType);
    toggleReaction.mutate(reactionType);
  };

  return (
    <div className={`${level > 0 ? 'ml-10 pl-6 border-l border-muted' : ''} py-3`}>
      <div className="flex gap-3">
        {comment.avatar ? (
          <AvatarPreviewDialog
            avatarSrc={comment.avatar}
            avatarAlt={comment.nickname}
            fallbackText={comment.nickname.charAt(0).toUpperCase()}
            title={`${comment.nickname} profile picture`}
          >
            <Avatar className="w-10 h-10 flex-shrink-0 cursor-pointer hover:ring-2 hover:ring-primary/20 transition-all">
              <AvatarImage src={comment.avatar} alt={comment.nickname} />
              <AvatarFallback>{comment.nickname.charAt(0).toUpperCase()}</AvatarFallback>
            </Avatar>
          </AvatarPreviewDialog>
        ) : (
          <Avatar className="w-10 h-10 flex-shrink-0">
            <AvatarFallback>👤</AvatarFallback>
          </Avatar>
        )}
        
        <div className="flex-1 space-y-2">
          <div className="flex items-center gap-2 text-sm">
            <span className="font-semibold" data-testid={`text-comment-author-${comment.id}`}>
              {comment.nickname}
            </span>
            <span className="text-muted-foreground text-xs" data-testid={`text-comment-time-${comment.id}`}>
              {formatTimeAgo(comment.createdAt)}
            </span>
          </div>
          
          <div className="text-sm leading-relaxed whitespace-pre-wrap" data-testid={`text-comment-content-${comment.id}`}>
            {comment.content}
          </div>
          
          <div className="flex items-center gap-4 pt-1">
            <div className="flex items-center gap-1">
              <Button
                variant="ghost"
                size="sm"
                className={`h-8 px-3 rounded-full text-xs font-medium hover:bg-muted transition-colors ${
                  currentReaction === 'like' 
                    ? 'bg-blue-50 text-blue-600 hover:bg-blue-100' 
                    : 'text-muted-foreground hover:text-foreground'
                }`}
                onClick={() => handleReaction('like')}
                data-testid={`button-like-${comment.id}`}
              >
                <ThumbsUp className="h-3 w-3 mr-1" />
                {comment.likesCount || 0}
              </Button>
              
              <Button
                variant="ghost"
                size="sm"
                className={`h-8 px-3 rounded-full text-xs font-medium hover:bg-muted transition-colors ${
                  currentReaction === 'dislike' 
                    ? 'bg-red-50 text-red-600 hover:bg-red-100' 
                    : 'text-muted-foreground hover:text-foreground'
                }`}
                onClick={() => handleReaction('dislike')}
                data-testid={`button-dislike-${comment.id}`}
              >
                <ThumbsDown className="h-3 w-3 mr-1" />
                {comment.dislikesCount || 0}
              </Button>
            </div>
            
            {level < 2 && (
              <CommentForm
                articleId={articleId}
                parentId={comment.id}
                placeholder="Add reply..."
                buttonText="Reply"
                onSuccess={() => setShowReplyForm(false)}
              />
            )}
          </div>
          
          {comment.repliesCount > 0 && (
            <Button
              variant="ghost"
              size="sm"
              onClick={() => setShowReplies(!showReplies)}
              className="text-blue-600 hover:text-blue-700 h-8 px-0 font-medium text-xs rounded-full hover:bg-blue-50 transition-colors"
              data-testid={`button-toggle-replies-${comment.id}`}
            >
              {showReplies ? (
                <>
                  <ChevronUp className="h-3 w-3 mr-1" />
                  Hide replies
                </>
              ) : (
                <>
                  <ChevronDown className="h-3 w-3 mr-1" />
                  View {comment.repliesCount} replies
                </>
              )}
            </Button>
          )}
          
          {showReplies && repliesData?.comments && (
            <div className="mt-4 space-y-3">
              {repliesData.comments.map((reply: Comment) => (
                <CommentItem 
                  key={reply.id} 
                  comment={reply} 
                  articleId={articleId}
                  level={level + 1}
                />
              ))}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

export default function CommentSection({ articleId }: CommentSectionProps) {
  const [sortBy, setSortBy] = useState<'newest' | 'popular'>('newest');
  const { data, isLoading } = useQuery({
    queryKey: ['/api/articles', articleId, 'comments', sortBy],
    queryFn: async () => {
      const response = await apiRequest('GET', `/api/articles/${articleId}/comments?limit=20&sort=${sortBy}`);
      return response.json();
    },
  });

  if (isLoading) {
    return (
      <div className="bg-background p-6">
        <h3 className="text-xl font-bold mb-4">Comments</h3>
        <div className="space-y-6">
          {[...Array(3)].map((_, i) => (
            <div key={i} className="animate-pulse flex gap-3">
              <div className="w-10 h-10 bg-muted rounded-full"></div>
              <div className="flex-1 space-y-2">
                <div className="h-4 bg-muted rounded w-32"></div>
                <div className="h-12 bg-muted rounded"></div>
              </div>
            </div>
          ))}
        </div>
      </div>
    );
  }

  const comments = data?.comments || [];
  const total = data?.total || 0;

  return (
    <div className="bg-background pb-6" data-testid="section-comments">
      {/* Comments Header */}
      <div className="px-6 py-4 border-b">
        <div className="flex items-center justify-between mb-4">
          <h3 className="text-xl font-bold">{total} Comments</h3>
          <Select value={sortBy} onValueChange={(value) => setSortBy(value as 'newest' | 'popular')}>
            <SelectTrigger className="w-[140px] h-8 text-sm border-none bg-transparent hover:bg-muted/50">
              <ArrowUpDown className="h-4 w-4 mr-2" />
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="newest">Newest</SelectItem>
              <SelectItem value="popular">Popular</SelectItem>
            </SelectContent>
          </Select>
        </div>
      </div>
      
      {/* Comment Form */}
      <div className="px-6 pt-6">
        <CommentForm articleId={articleId} />
      </div>
      
      {/* Comments List */}
      <div className="px-6">
        {comments.length === 0 ? (
          <div className="text-center text-muted-foreground py-12">
            <div className="w-16 h-16 mx-auto mb-4 bg-muted rounded-full flex items-center justify-center">
              <span className="text-2xl">💬</span>
            </div>
            <p className="text-lg mb-2">No comments yet</p>
            <p className="text-sm">Be the first to leave a comment!</p>
          </div>
        ) : (
          <div className="divide-y divide-muted/30">
            {comments.map((comment: Comment, index: number) => (
              <CommentItem key={comment.id} comment={comment} articleId={articleId} />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}