import { ConnectError } from "@connectrpc/connect";
import { ArrowUpLeftFromCircleIcon, MessageCircleIcon, User2Icon } from "lucide-react";
import { useEffect, useState } from "react";
import { toast } from "react-hot-toast";
import { Link, useLocation, useParams } from "react-router-dom";
import { MemoDetailSidebar, MemoDetailSidebarDrawer } from "@/components/MemoDetailSidebar";
import MemoEditor from "@/components/MemoEditor";
import MemoView from "@/components/MemoView";
import MobileHeader from "@/components/MobileHeader";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { memoNamePrefix } from "@/helpers/resource-names";
import useCurrentUser from "@/hooks/useCurrentUser";
import useMediaQuery from "@/hooks/useMediaQuery";
import { useMemo, useMemoComments } from "@/hooks/useMemoQueries";
import useNavigateTo from "@/hooks/useNavigateTo";
import { Routes } from "@/router";
import { cn } from "@/lib/utils";
import { useTranslate } from "@/utils/i18n";

const ANONYMOUS_ID_KEY = "anonymous_id";

const MemoDetail = () => {
  const t = useTranslate();
  const md = useMediaQuery("md");
  const params = useParams();
  const navigateTo = useNavigateTo();
  const { state: locationState } = useLocation();
  const currentUser = useCurrentUser();
  const uid = params.uid;
  const memoName = `${memoNamePrefix}${uid}`;
  const [showCommentEditor, setShowCommentEditor] = useState(false);
  const [anonymousId, setAnonymousId] = useState<string | null>(null);
  const [anonymousDisplayName, setAnonymousDisplayName] = useState<string>("");

  // Initialize anonymous session ID when not logged in
  useEffect(() => {
    if (!currentUser) {
      let id = localStorage.getItem(ANONYMOUS_ID_KEY);
      if (!id) {
        // Generate new anonymous ID: anonymous_<randomString>
        const randomString = Math.random().toString(36).substring(2, 10);
        id = `anonymous_${randomString}`;
        localStorage.setItem(ANONYMOUS_ID_KEY, id);
      }
      setAnonymousId(id);
    } else {
      // Clear anonymous ID when user logs in
      setAnonymousId(null);
    }
  }, [currentUser]);

  // Fetch main memo with React Query
  const { data: memo, error, isLoading } = useMemo(memoName, { enabled: !!memoName });

  // Fetch parent memo if exists
  const { data: parentMemo } = useMemo(memo?.parent || "", {
    enabled: !!memo?.parent,
  });

  // Fetch all comments for this memo in a single query
  const { data: commentsResponse } = useMemoComments(memoName, {
    enabled: !!memo,
    anonymousId: anonymousId || undefined,
  });
  const comments = commentsResponse?.memos || [];

  const showCreateCommentButton = currentUser && !showCommentEditor;

  // Handle loading state
  if (isLoading) {
    return (
      <section className="@container w-full max-w-5xl min-h-full flex flex-col justify-start items-center sm:pt-3 md:pt-6 pb-8">
        <div className="w-full px-4 sm:px-6 flex flex-col items-center justify-center min-h-[50vh]">
          <p className="text-muted-foreground">Loading memo...</p>
        </div>
      </section>
    );
  }

  // Handle errors - show 404 if memo not found, 403 if access denied
  if (error) {
    const errorMessage = (error as ConnectError).message || "";
    if (errorMessage.includes("not found") || errorMessage.includes("404")) {
      navigateTo("/404");
      return null;
    }
    if (errorMessage.includes("Access denied") || errorMessage.includes("403")) {
      navigateTo("/403");
      return null;
    }
    toast.error(errorMessage);
    navigateTo("/404");
    return null;
  }

  // If memo not found after loading
  if (!memo) {
    navigateTo("/404");
    return null;
  }

  const handleShowCommentEditor = () => {
    setShowCommentEditor(true);
  };

  const handleCommentCreated = async (_memoCommentName: string) => {
    // React Query will auto-refetch due to invalidation in the mutation
    setShowCommentEditor(false);
  };

  return (
    <section className="@container w-full max-w-5xl mx-auto min-h-full flex flex-col justify-start items-center sm:pt-3 md:pt-6 pb-8">
      {!md && (
        <MobileHeader>
          <MemoDetailSidebarDrawer memo={memo} parentPage={locationState?.from} />
        </MobileHeader>
      )}
      <div className={cn("w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4")}>
        <div className={cn("w-full max-w-3xl mx-auto md:w-[calc(100%-15rem)]")}>
          {parentMemo && (
            <div className="w-auto inline-block mb-2">
              <Link
                className="px-3 py-1 border border-border rounded-lg max-w-xs w-auto text-sm flex flex-row justify-start items-center flex-nowrap text-muted-foreground hover:shadow hover:opacity-80"
                to={`/${parentMemo.name}`}
                state={locationState}
                viewTransition
              >
                <ArrowUpLeftFromCircleIcon className="w-4 h-auto shrink-0 opacity-60 mr-2" />
                <span className="truncate">{parentMemo.content}</span>
              </Link>
            </div>
          )}
          <MemoView
            key={`${memo.name}-${memo.displayTime}`}
            className="shadow hover:shadow-md transition-all"
            memo={memo}
            compact={false}
            parentPage={locationState?.from}
            showCreator
            showVisibility
            showPinned
            showNsfwContent
          />
          <div className="pt-8 pb-16 w-full">
            <h2 id="comments" className="sr-only">
              {t("memo.comment.self")}
            </h2>
            <div className="relative mx-auto grow w-full min-h-full flex flex-col justify-start items-start gap-y-1">
              {comments.length === 0 ? (
                // Empty state: Show button for logged-in users or anonymous comment UI
                currentUser ? (
                  showCommentEditor ? (
                    <div className="w-full flex flex-col gap-3 py-6">
                      <div className="flex flex-col gap-2">
                        <label htmlFor="comment-name-empty" className="text-sm text-muted-foreground">
                          {t("memo.comment.your-name") || "Your name (optional)"}
                        </label>
                        <Input
                          id="comment-name-empty"
                          placeholder={t("memo.comment.name-placeholder") || "Anonymous"}
                          value={anonymousDisplayName}
                          onChange={(e) => setAnonymousDisplayName(e.target.value)}
                          className="max-w-xs"
                        />
                      </div>
                      <MemoEditor
                        cacheKey={`${memo.name}-${memo.updateTime}-comment-empty`}
                        placeholder={t("editor.add-your-comment-here")}
                        parentMemoName={memo.name}
                        anonymousId={anonymousId || undefined}
                        anonymousName={anonymousDisplayName || undefined}
                        autoFocus
                        onConfirm={handleCommentCreated}
                        onCancel={() => {
                          setShowCommentEditor(false);
                          setAnonymousDisplayName("");
                        }}
                      />
                    </div>
                  ) : (
                    <div className="w-full flex flex-row justify-center items-center py-6">
                      <Button variant="ghost" onClick={handleShowCommentEditor}>
                        <span className="text-muted-foreground">{t("memo.comment.write-a-comment")}</span>
                        <MessageCircleIcon className="ml-2 w-5 h-auto text-muted-foreground" />
                      </Button>
                    </div>
                  )
                ) : (
                  showCommentEditor ? (
                    <div className="w-full flex flex-col gap-3 py-6">
                      <div className="flex flex-col gap-2">
                        <label htmlFor="anonymous-name-empty" className="text-sm text-muted-foreground">
                          {t("memo.comment.your-name") || "Your name (optional)"}
                        </label>
                        <Input
                          id="anonymous-name-empty"
                          placeholder={t("memo.comment.name-placeholder") || "Anonymous"}
                          value={anonymousDisplayName}
                          onChange={(e) => setAnonymousDisplayName(e.target.value)}
                          className="max-w-xs"
                        />
                      </div>
                      <MemoEditor
                        cacheKey={`${memo.name}-${memo.updateTime}-comment-anonymous-empty`}
                        placeholder={t("editor.add-your-comment-here")}
                        parentMemoName={memo.name}
                        anonymousId={anonymousId || undefined}
                        anonymousName={anonymousDisplayName || undefined}
                        autoFocus
                        onConfirm={handleCommentCreated}
                        onCancel={() => {
                          setShowCommentEditor(false);
                          setAnonymousDisplayName("");
                        }}
                      />
                    </div>
                  ) : (
                    <div className="w-full flex flex-row justify-center items-center py-6">
                      <Button variant="ghost" onClick={handleShowCommentEditor}>
                        <span className="text-muted-foreground">{t("memo.comment.write-a-comment")}</span>
                        <MessageCircleIcon className="ml-2 w-5 h-auto text-muted-foreground" />
                      </Button>
                    </div>
                  )
                )
              ) : (
                // Has comments
                <>
                  <div className="w-full flex flex-row justify-between items-center h-8 pl-3 mb-2">
                    <div className="flex flex-row justify-start items-center">
                      <MessageCircleIcon className="w-5 h-auto text-muted-foreground mr-1" />
                      <span className="text-muted-foreground text-sm">{t("memo.comment.self")}</span>
                      <span className="text-muted-foreground text-sm ml-1">({comments.length})</span>
                    </div>
                    {showCreateCommentButton && (
                      <Button variant="ghost" className="text-muted-foreground" onClick={handleShowCommentEditor}>
                        {t("memo.comment.write-a-comment")}
                      </Button>
                    )}
                  </div>
                  {comments.map((comment) => (
                    <MemoView
                      key={`${comment.name}-${comment.displayTime}`}
                      memo={comment}
                      parentPage={locationState?.from}
                      showCreator
                      compact
                    />
                  ))}
                  {/* Show comment editor or anonymous comment UI after comments */}
                  {!currentUser ? (
                    <div className="w-full mt-4 pt-4 border-t border-border">
                      {showCommentEditor ? (
                        <div className="flex flex-col gap-3">
                          <div className="flex flex-col gap-2">
                            <label htmlFor="anonymous-name" className="text-sm text-muted-foreground">
                              {t("memo.comment.your-name") || "Your name (optional)"}
                            </label>
                            <Input
                              id="anonymous-name"
                              placeholder={t("memo.comment.name-placeholder") || "Anonymous"}
                              value={anonymousDisplayName}
                              onChange={(e) => setAnonymousDisplayName(e.target.value)}
                              className="max-w-xs"
                            />
                          </div>
                          <MemoEditor
                            cacheKey={`${memo.name}-${memo.updateTime}-comment-anonymous`}
                            placeholder={t("editor.add-your-comment-here")}
                            parentMemoName={memo.name}
                            anonymousId={anonymousId || undefined}
                            anonymousName={anonymousDisplayName || undefined}
                            autoFocus
                            onConfirm={handleCommentCreated}
                            onCancel={() => {
                              setShowCommentEditor(false);
                              setAnonymousDisplayName("");
                            }}
                          />
                        </div>
                      ) : (
                        <div className="flex flex-col items-center justify-center py-4">
                          <p className="text-sm text-muted-foreground mb-3 text-center">
                            {t("memo.comment.want-to-comment") || "Want to add a comment?"}
                          </p>
                          <div className="flex flex-row gap-2">
                            <Button
                              variant="outline"
                              onClick={handleShowCommentEditor}
                              className="gap-2"
                            >
                              <MessageCircleIcon className="w-4 h-4" />
                              {t("memo.comment.write-a-comment") || "Write a comment"}
                            </Button>
                            <Button
                              variant="ghost"
                              onClick={() => {
                                const currentUrl = window.location.pathname + window.location.search;
                                navigateTo(`${Routes.AUTH}?redirect=${encodeURIComponent(currentUrl)}`);
                              }}
                              className="gap-2"
                            >
                              <User2Icon className="w-4 h-4" />
                              {t("common.sign-in") || "Sign In"}
                            </Button>
                          </div>
                        </div>
                      )}
                    </div>
                  ) : showCommentEditor ? (
                    <div className="w-full mt-4 pt-4 border-t border-border">
                      <div className="flex flex-col gap-3">
                        <div className="flex flex-col gap-2">
                          <label htmlFor="comment-name" className="text-sm text-muted-foreground">
                            {t("memo.comment.your-name") || "Your name (optional)"}
                          </label>
                          <Input
                            id="comment-name"
                            placeholder={t("memo.comment.name-placeholder") || "Anonymous"}
                            value={anonymousDisplayName}
                            onChange={(e) => setAnonymousDisplayName(e.target.value)}
                            className="max-w-xs"
                          />
                        </div>
                        <MemoEditor
                          cacheKey={`${memo.name}-${memo.updateTime}-comment`}
                          placeholder={t("editor.add-your-comment-here")}
                          parentMemoName={memo.name}
                          anonymousId={anonymousId || undefined}
                          anonymousName={anonymousDisplayName || undefined}
                          autoFocus
                          onConfirm={handleCommentCreated}
                          onCancel={() => {
                            setShowCommentEditor(false);
                            setAnonymousDisplayName("");
                          }}
                        />
                      </div>
                    </div>
                  ) : showCreateCommentButton ? (
                    <div className="w-full mt-4 pt-4 border-t border-border">
                      <div className="flex flex-row justify-center items-center py-2">
                        <Button variant="ghost" onClick={handleShowCommentEditor} className="gap-2">
                          <MessageCircleIcon className="w-4 h-4" />
                          {t("memo.comment.write-a-comment")}
                        </Button>
                      </div>
                    </div>
                  ) : null}
                </>
              )}
            </div>
          </div>
        </div>
        {md && (
          <div className="sticky top-0 left-0 shrink-0 -mt-6 w-56 h-full">
            <MemoDetailSidebar className="py-6" memo={memo} parentPage={locationState?.from} />
          </div>
        )}
      </div>
    </section>
  );
};

export default MemoDetail;
