import { useState } from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import {
  reviewCommentResolve,
  reviewCommentUnresolve,
  reviewCommentUpdate,
  reviewCommentDelete,
  reviewCommentReply,
  type ReviewCommentResponse,
} from "@/client";
import { Button } from "@/components/ui/button";
import { PRCommentInput } from "./PRCommentInput";
import {
  Bot,
  Check,
  MoreHorizontal,
  Pencil,
  Reply,
  Trash2,
  X,
} from "lucide-react";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { toast } from "sonner";

const NIL_UUID = "00000000-0000-0000-0000-000000000000";

interface PRInlineCommentProps {
  comment: ReviewCommentResponse;
  /** Namespace of the repo */
  namespace: string;
  /** Name of the repo */
  repoName: string;
  /** PR number */
  prNumber: number;
  /** Whether the current user is the author of this comment */
  isAuthor?: boolean;
  /** Whether the current user can modify this comment (author or admin) */
  canModify?: boolean;
  /** Called when comment is updated or deleted to refresh the list */
  onRefresh?: () => void;
}

const getRelativeTime = (dateString: string) => {
  const date = new Date(dateString);
  const now = new Date();
  const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
  if (diffInSeconds < 60) return "just now";
  if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
  if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
  if (diffInSeconds < 2592000) return `${Math.floor(diffInSeconds / 86400)}d ago`;
  return `${Math.floor(diffInSeconds / 2592000)}mo ago`;
};

/** True if this comment was authored by the AI bot (nil UUID). */
const isAiComment = (comment: ReviewCommentResponse): boolean =>
  comment.author === NIL_UUID;

export function PRInlineComment({
  comment,
  namespace,
  repoName,
  prNumber,
  isAuthor = false,
  canModify = false,
  onRefresh,
}: PRInlineCommentProps) {
  const queryClient = useQueryClient();
  const [isReplying, setIsReplying] = useState(false);
  const [isEditing, setIsEditing] = useState(false);
  const [editBody, setEditBody] = useState(comment.body);

  const updateMutation = useMutation({
    mutationFn: async (body: string) => {
      await reviewCommentUpdate({
        path: { namespace, repo: repoName, pr_number: prNumber, comment_id: comment.id },
        body: { body },
      });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["pr-comments", namespace, repoName, prNumber] });
      setIsEditing(false);
      toast.success("Comment updated");
      onRefresh?.();
    },
    onError: () => toast.error("Failed to update comment"),
  });

  const deleteMutation = useMutation({
    mutationFn: async () => {
      await reviewCommentDelete({
        path: { namespace, repo: repoName, pr_number: prNumber, comment_id: comment.id },
      });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["pr-comments", namespace, repoName, prNumber] });
      toast.success("Comment deleted");
      onRefresh?.();
    },
    onError: () => toast.error("Failed to delete comment"),
  });

  const resolveMutation = useMutation({
    mutationFn: async () => {
      await reviewCommentResolve({
        path: { namespace, repo: repoName, pr_number: prNumber, comment_id: comment.id },
      });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["pr-comments", namespace, repoName, prNumber] });
      toast.success("Comment resolved");
      onRefresh?.();
    },
    onError: () => toast.error("Failed to resolve comment"),
  });

  const unresolveMutation = useMutation({
    mutationFn: async () => {
      await reviewCommentUnresolve({
        path: { namespace, repo: repoName, pr_number: prNumber, comment_id: comment.id },
      });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["pr-comments", namespace, repoName, prNumber] });
      toast.success("Comment unresolved");
      onRefresh?.();
    },
    onError: () => toast.error("Failed to unresolve comment"),
  });

  const replyMutation = useMutation({
    mutationFn: async (body: string) => {
      await reviewCommentReply({
        path: { namespace, repo: repoName, pr_number: prNumber, comment_id: comment.id },
        body: { body },
      });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["pr-comments", namespace, repoName, prNumber] });
      setIsReplying(false);
      toast.success("Reply posted");
      onRefresh?.();
    },
    onError: () => toast.error("Failed to post reply"),
  });

  const ai = isAiComment(comment);

  return (
    <div
      className={`flex gap-2 group ${
        comment.resolved ? "opacity-60" : ""
      } ${ai ? "rounded-md border border-blue-200 dark:border-blue-800 bg-blue-50 dark:bg-blue-950/20 p-2 -mx-1" : ""}`}
    >
      {/* Avatar placeholder */}
      <div
        className={`flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center text-xs font-medium ${
          ai ? "bg-blue-200 dark:bg-blue-800 text-blue-700 dark:text-blue-300" : "bg-muted text-muted-foreground"
        }`}
      >
        {ai ? (
          <Bot className="h-4 w-4" />
        ) : (
          comment.author_username?.[0]?.toUpperCase() ?? "?"
        )}
      </div>

      <div className="flex-1 min-w-0">
        {/* Header */}
        <div className="flex items-center gap-2 mb-1">
          <span className={`text-sm font-medium ${ai ? "text-blue-700 dark:text-blue-300" : ""}`}>
            {ai ? "AI Reviewer" : comment.author_username ?? comment.author}
          </span>
          {ai && (
            <span className="text-xs bg-blue-200 dark:bg-blue-800 text-blue-700 dark:text-blue-300 px-1.5 py-0.5 rounded font-medium">
              AI
            </span>
          )}
          <span className="text-xs text-muted-foreground">
            {getRelativeTime(comment.created_at)}
          </span>
          {comment.resolved && (
            <span className="text-xs bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400 px-1.5 py-0.5 rounded">
              resolved
            </span>
          )}
          {comment.in_reply_to && (
            <span className="text-xs text-muted-foreground italic">reply</span>
          )}
        </div>

        {/* File location for root comments */}
        {!comment.in_reply_to && comment.path && (
          <div className="flex items-center gap-1 mb-1 text-xs text-muted-foreground">
            <span className="font-mono">{comment.path}</span>
            {comment.line && <span>:{comment.line}</span>}
          </div>
        )}

        {/* Body */}
        {isEditing ? (
          <PRCommentInput
            initialValue={editBody}
            buttonLabel="Update"
            onSubmit={async (body) => {
              await updateMutation.mutateAsync(body);
            }}
            onCancel={() => {
              setEditBody(comment.body);
              setIsEditing(false);
            }}
            autoFocus
          />
        ) : (
          <div className="text-sm whitespace-pre-wrap">{comment.body}</div>
        )}

        {/* Actions */}
        {!isEditing && (
          <div className="flex items-center gap-1 mt-1">
            {!ai && (
              <Button
                variant="ghost"
                size="sm"
                className="h-6 px-1.5 text-xs text-muted-foreground hover:text-foreground"
                onClick={() => setIsReplying(!isReplying)}
              >
                <Reply className="h-3 w-3 mr-1" />
                Reply
              </Button>
            )}

            {canModify && !ai && !comment.in_reply_to && (
              <>
                {comment.resolved ? (
                  <Button
                    variant="ghost"
                    size="sm"
                    className="h-6 px-1.5 text-xs text-muted-foreground hover:text-foreground"
                    onClick={() => unresolveMutation.mutate()}
                    disabled={unresolveMutation.isPending}
                  >
                    <X className="h-3 w-3 mr-1" />
                    Unresolve
                  </Button>
                ) : (
                  <Button
                    variant="ghost"
                    size="sm"
                    className="h-6 px-1.5 text-xs text-muted-foreground hover:text-green-600"
                    onClick={() => resolveMutation.mutate()}
                    disabled={resolveMutation.isPending}
                  >
                    <Check className="h-3 w-3 mr-1" />
                    Resolve
                  </Button>
                )}
              </>
            )}

            {(canModify || isAuthor) && !ai && (
              <DropdownMenu>
                <DropdownMenuTrigger className="h-6 px-1.5 text-xs text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity inline-flex items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground">
                  <MoreHorizontal className="h-3 w-3" />
                </DropdownMenuTrigger>
                <DropdownMenuContent align="start">
                  {canModify && (
                    <DropdownMenuItem
                      onClick={() => setIsEditing(true)}
                      className="text-sm"
                    >
                      <Pencil className="h-4 w-4 mr-2" />
                      Edit
                    </DropdownMenuItem>
                  )}
                  {(canModify || isAuthor) && (
                    <>
                      <DropdownMenuSeparator />
                      <DropdownMenuItem
                        onClick={() => {
                          if (confirm("Delete this comment?")) {
                            deleteMutation.mutate();
                          }
                        }}
                        className="text-red-600 text-sm"
                      >
                        <Trash2 className="h-4 w-4 mr-2" />
                        Delete
                      </DropdownMenuItem>
                    </>
                  )}
                </DropdownMenuContent>
              </DropdownMenu>
            )}
          </div>
        )}

        {/* Reply input */}
        {isReplying && (
          <div className="mt-2">
            <PRCommentInput
              placeholder="Reply..."
              buttonLabel="Reply"
              onSubmit={async (body) => {
                await replyMutation.mutateAsync(body);
              }}
              onCancel={() => setIsReplying(false)}
              autoFocus
            />
          </div>
        )}
      </div>
    </div>
  );
}
