import React, { useState, useEffect } from "react";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { MessageSquare, Send, Trash, Loader2, ArrowDownUp, Clock, Calendar, Search, X } from "lucide-react";
import { commentsApi, Comment } from "@/services/commentsApi";
import { useAuth } from "@/lib/auth-context";
import { toast } from "sonner";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { Employee, employeeApi } from "@/services/employeeApi";
import { formatDistanceToNow, format, parseISO } from "date-fns";
import { SlateRichTextEditor } from "@/components/custom/SlateRichTextEditor";

interface TaskCommentSectionProps {
  taskId: number;
  entityType?: "Task" | "Issue" | "Project";
}

const TaskCommentSection: React.FC<TaskCommentSectionProps> = ({ 
  taskId, 
  entityType = "Task" 
}) => {
  const [newComment, setNewComment] = useState("");
  const [sortOrder, setSortOrder] = useState<"desc" | "asc">("desc"); // Newest first by default
  const [searchQuery, setSearchQuery] = useState("");
  const { userData } = useAuth();
  const queryClient = useQueryClient();

  // Fetch employees for avatar display
  const { data: employees = [] } = useQuery({
    queryKey: ["employees"],
    queryFn: () => employeeApi.getAll(),
  });

  // Fetch comments for this entity
  const {
    data: comments = [],
    isLoading,
    isError,
  } = useQuery({
    queryKey: ["comments", entityType, taskId],
    queryFn: () => commentsApi.getByEntity(entityType, taskId),
  });

  // Add comment mutation
  const addCommentMutation = useMutation({
    mutationFn: (commentText: string) => 
      commentsApi.create({
        entityId: taskId,
        entityType: entityType,
        commentText,
        userId: userData?.userId || 0,
        createdBy: null,
        createdAt: new Date().toISOString(),
        updatedBy: null,
        updatedAt: null
      }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["comments", entityType, taskId] });
      toast.success("Comment added successfully");
      setNewComment("");
    },
    onError: (error) => {
      toast.error(`Failed to add comment: ${error}`);
    }
  });

  // Delete comment mutation
  const deleteCommentMutation = useMutation({
    mutationFn: (commentId: number) => commentsApi.delete(commentId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["comments", entityType, taskId] });
      toast.success("Comment deleted successfully");
    },
    onError: (error) => {
      toast.error(`Failed to delete comment: ${error}`);
    }
  });

  const handleSubmit = () => {
    if (!hasValidContent(newComment)) return;
    if (!userData?.userId) {
      toast.error("You must be logged in to add comments");
      return;
    }
    
    addCommentMutation.mutate(newComment);
  };

  // Helper function to check if HTML content has meaningful text
  const hasValidContent = (htmlContent: string): boolean => {
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = htmlContent;
    const textContent = tempDiv.textContent || tempDiv.innerText || '';
    return textContent.trim().length > 0;
  };

  // Handle keyboard submission with Ctrl+Enter or Cmd+Enter
  const handleKeyDown = (e: React.KeyboardEvent) => {
    if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
      e.preventDefault();
      handleSubmit();
    }
  };

  const handleDeleteComment = (commentId: number) => {
    if (confirm("Are you sure you want to delete this comment?")) {
      deleteCommentMutation.mutate(commentId);
    }
  };

  // Format comment date
  const formatCommentDate = (dateString: string): string => {
    try {
      const date = parseISO(dateString);
      const now = new Date();
      const diffInHours = Math.abs(now.getTime() - date.getTime()) / 36e5;
      
      // If less than 24 hours ago, show relative time
      if (diffInHours < 24) {
        return formatDistanceToNow(date, { addSuffix: true });
      }
      
      // Otherwise show the actual date
      return format(date, 'MMM d, yyyy • h:mm a');
    } catch (error) {
      return 'Unknown date';
    }
  };

  // Utility to strip HTML tags from text
  const stripHtmlTags = (html: string): string => {
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = html;
    return tempDiv.textContent || tempDiv.innerText || '';
  };

  // Get user initials for avatar
  const getUserInitials = (userId: number): string => {
    const employee = employees.find(emp => emp.userId === userId);
    if (employee) {
      return `${employee.firstName.charAt(0)}${employee.lastName.charAt(0)}`.toUpperCase();
    }
    return "U";
  };

  // Get user name for display
  const getUserName = (userId: number): string => {
    const employee = employees.find(emp => emp.userId === userId);
    if (employee) {
      return `${employee.firstName} ${employee.lastName}`;
    }
    return `User ${userId}`;
  };

  // Filter comments based on search query
  const filteredComments = comments.filter((comment) => {
    if (!searchQuery.trim()) return true;
    
    const searchTerm = searchQuery.toLowerCase();
    
    // Extract text content from HTML for searching
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = comment.commentText;
    const commentText = (tempDiv.textContent || tempDiv.innerText || '').toLowerCase();
    
    const authorName = getUserName(comment.userId).toLowerCase();
    
    return commentText.includes(searchTerm) || authorName.includes(searchTerm);
  });

  // Sort filtered comments by date
  const sortedComments = [...filteredComments].sort((a, b) => {
    const dateA = new Date(a.createdAt).getTime();
    const dateB = new Date(b.createdAt).getTime();
    return sortOrder === "desc" ? dateB - dateA : dateA - dateB;
  });

  return (
    <Card className="border border-gray-200 shadow-sm overflow-visible">
      <div className="bg-white border-b border-gray-200 p-5 relative">
        <div className="flex flex-wrap justify-between items-center gap-3">
          <div className="flex items-center gap-2">
            <div className="bg-indigo-100 p-2 rounded-full">
              <MessageSquare className="h-4 w-4 text-indigo-600" />
            </div>
            <div>
              <CardTitle className="text-base sm:text-lg text-gray-900">
                {entityType} Discussion
              </CardTitle>
              <CardDescription className="text-sm text-gray-500 mt-0.5">
                {comments.length === 0 
                  ? "No comments yet" 
                  : searchQuery.trim() 
                    ? `${filteredComments.length} of ${comments.length} comments`
                    : comments.length === 1 
                      ? "1 comment" 
                      : `${comments.length} comments`}
              </CardDescription>
            </div>
          </div>
          <div className="flex items-center gap-2">
            <Button 
              variant="outline" 
              size="sm" 
              className={`flex items-center gap-1 text-xs sm:text-sm h-8 ${sortOrder === "desc" ? "bg-indigo-50 text-indigo-600 border-indigo-200" : ""}`}
              onClick={() => setSortOrder(sortOrder === "desc" ? "asc" : "desc")}
            >
              <ArrowDownUp className="h-3 w-3 sm:h-3.5 sm:w-3.5 mr-1" />
              {sortOrder === "desc" ? "Newest first" : "Oldest first"}
            </Button>
            <div className="h-6 border-r border-gray-200"></div>
            <Button 
              variant="outline" 
              size="sm" 
              className="text-xs sm:text-sm h-8"
              onClick={() => setNewComment("")}
              disabled={!hasValidContent(newComment)}
            >
              Clear
            </Button>
          </div>
        </div>
      </div>
      
      {/* Search input */}
      {comments.length > 0 && (
        <div className="px-5 py-3 bg-gray-50 border-b border-gray-200">
          <div className="relative">
            <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" />
            <Input
              placeholder="Search comments..."
              className="pl-9 pr-9 text-sm border-gray-200 focus:border-indigo-300 bg-white"
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
            />
            {searchQuery && (
              <Button
                variant="ghost"
                size="sm"
                className="absolute right-1 top-1/2 transform -translate-y-1/2 h-6 w-6 p-0 hover:bg-gray-100"
                onClick={() => setSearchQuery("")}
              >
                <X className="h-3 w-3 text-gray-400" />
              </Button>
            )}
          </div>
        </div>
      )}
      
      <CardContent className="p-0">
        {/* Comment input */}
        <div className="p-5 bg-white border-b border-gray-200">
          <div className="flex items-start gap-3">
            <Avatar className="h-8 w-8 sm:h-9 sm:w-9 mt-0.5 border-2 border-white ring-1 ring-gray-200">
              <AvatarFallback className="bg-indigo-600 text-white text-xs sm:text-sm font-medium">
                {userData?.userId ? getUserInitials(userData.userId) : "U"}
              </AvatarFallback>
            </Avatar>
            
            <div className="flex-1" onKeyDown={handleKeyDown}>
              <SlateRichTextEditor
                placeholder="Add your comment..."
                className="text-sm border-gray-200 focus:border-indigo-300 rounded-md shadow-none"
                minHeight="70px"
                initialValue={newComment}
                onChange={(htmlContent) => setNewComment(htmlContent)}
              />
              
              <div className="flex items-center justify-between mt-3">
                <p className="text-xs text-gray-500">Press Ctrl+Enter to post</p>
                <Button 
                  className="bg-indigo-600 hover:bg-indigo-700 transition-colors shadow-none text-white" 
                  size="sm"
                  onClick={handleSubmit}
                  disabled={!hasValidContent(newComment) || addCommentMutation.isPending}
                >
                  {addCommentMutation.isPending ? (
                    <div className="flex items-center gap-1.5">
                      <Loader2 className="h-3 w-3 animate-spin" />
                      <span>Posting...</span>
                    </div>
                  ) : (
                    <div className="flex items-center gap-1.5">
                      <Send className="h-3 w-3" />
                      <span>Post</span>
                    </div>
                  )}
                </Button>
              </div>
            </div>
          </div>
        </div>

        {/* Comments list */}
        <div className="p-5 bg-gray-50 max-h-[400px] overflow-y-auto relative z-0">
          {isLoading ? (
            <div className="flex items-center justify-center py-6">
              <div className="flex flex-col items-center gap-2">
                <Loader2 className="h-6 w-6 animate-spin text-indigo-600" />
                <span className="text-sm text-gray-600">Loading comments...</span>
              </div>
            </div>
          ) : isError ? (
            <div className="text-center bg-red-50 text-red-700 py-4 px-4 rounded-md border border-red-100">
              <p className="text-sm font-medium">Unable to load comments</p>
            </div>
          ) : comments.length > 0 ? (
            <div className="space-y-0.5">
              <div className="flex items-center justify-between mb-3 pb-2 border-b border-gray-200">
                <div className="flex items-center gap-2">
                  <h3 className="text-xs sm:text-sm font-medium text-gray-500">
                    {searchQuery.trim() ? "Search Results" : "Comments"}
                  </h3>
                  <span className="inline-flex items-center justify-center rounded-full bg-indigo-100 text-indigo-700 font-medium text-xs px-2 py-0.5">
                    {searchQuery.trim() ? filteredComments.length : comments.length}
                  </span>
                </div>
                <div className="flex items-center gap-1.5 text-xs font-medium text-indigo-600 bg-indigo-50 px-2 py-1 rounded-full">
                  <span>{sortOrder === "desc" ? "Newest first" : "Oldest first"}</span>
                  <ArrowDownUp className="h-3 w-3" />
                </div>
              </div>
              {filteredComments.length === 0 && searchQuery.trim() ? (
                <div className="bg-white rounded-md p-6 text-center border border-gray-200">
                  <div className="mx-auto w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center mb-3">
                    <Search className="h-6 w-6 text-gray-400" />
                  </div>
                  <h3 className="text-sm font-medium text-gray-900 mb-1">No comments found</h3>
                  <p className="text-sm text-gray-500 max-w-xs mx-auto mb-4">
                    No comments match your search for "{searchQuery}". Try adjusting your search terms.
                  </p>
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => setSearchQuery("")}
                    className="text-xs"
                  >
                    Clear search
                  </Button>
                </div>
              ) : (
                sortedComments.map((comment, index) => (
                  <div key={comment.commentId} className="mb-4 last:mb-0">
                    <div className="flex gap-3">
                      <Avatar className="h-8 w-8 sm:h-9 sm:w-9 mt-0.5 border-2 border-white ring-1 ring-gray-200">
                        <AvatarFallback className="bg-indigo-600 text-white text-xs sm:text-sm font-medium">
                          {getUserInitials(comment.userId)}
                        </AvatarFallback>
                      </Avatar>
                      
                      <div className="flex-1">
                        <div className="bg-white p-3 sm:p-4 rounded-md relative group shadow-sm border border-gray-200">
                          <div className="flex items-center justify-between gap-2 mb-2">
                            <span className="font-semibold text-sm text-gray-900">{getUserName(comment.userId)}</span>
                            <span className="text-xs text-gray-500">
                              {formatCommentDate(comment.createdAt)}
                            </span>
                          </div>
                          <div 
                            className="text-sm text-gray-700 leading-relaxed prose prose-sm max-w-none"
                            dangerouslySetInnerHTML={{ __html: comment.commentText }}
                          />
                          
                          {/* Delete button - only visible for the comment author */}
                          {userData?.userId === comment.userId && (
                            <Button
                              variant="ghost"
                              size="sm"
                              className="absolute top-2 right-2 h-6 w-6 p-0 opacity-0 group-hover:opacity-100 transition-opacity bg-white hover:bg-red-50 hover:text-red-600"
                              onClick={() => handleDeleteComment(comment.commentId)}
                              disabled={deleteCommentMutation.isPending}
                            >
                              <Trash className="h-3 w-3" />
                              <span className="sr-only">Delete comment</span>
                            </Button>
                          )}
                        </div>
                      </div>
                    </div>
                  </div>
                ))
              )}
            </div>
          ) : (
            <div className="bg-white rounded-md p-6 text-center border border-gray-200">
              <div className="mx-auto w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center mb-3">
                <MessageSquare className="h-6 w-6 text-gray-400" />
              </div>
              <h3 className="text-sm font-medium text-gray-900 mb-1">No comments yet</h3>
              <p className="text-sm text-gray-500 max-w-xs mx-auto">
                Start the conversation by adding the first comment to this task.
              </p>
            </div>
          )}
        </div>
      </CardContent>
    </Card>
  );
};

export default TaskCommentSection; 