"use client";

import { useCallback, useState } from "react";
import { ListTodoIcon } from "lucide-react";

import { type PromptInputMessage } from "@/components/ai-elements/prompt-input";
import { Button } from "@/components/ui/button";
import {
  DevDialog,
  DevDialogContent,
  DevDialogFooter,
  DevDialogHeader,
  DevDialogTitle,
} from "@/components/ui/dev-dialog";
import { ArtifactTrigger } from "@/components/workspace/artifacts";
import {
  ChatBox,
  useSpecificChatMode,
  useThreadChat,
} from "@/components/workspace/chats";
import { DevTodoList } from "@/components/workspace/dev-todo-list";
import { InputBox } from "@/components/workspace/input-box";
import { MessageList } from "@/components/workspace/messages";
import { ThreadContext } from "@/components/workspace/messages/context";
import { ThreadTitle } from "@/components/workspace/thread-title";
import { Welcome } from "@/components/workspace/welcome";
import { useArtifacts } from "@/components/workspace/artifacts";
import { useI18n } from "@/core/i18n/hooks";
import { useNotification } from "@/core/notification/hooks";
import { useLocalSettings } from "@/core/settings";
import { useThreadStream } from "@/core/threads/hooks";
import { textOfMessage } from "@/core/threads/utils";
import { env } from "@/env";
import { cn } from "@/lib/utils";

export default function ChatPage() {
  const { t } = useI18n();
  const [settings, setSettings] = useLocalSettings();
  const [showExitDialog, setShowExitDialog] = useState(false);
  const { fullscreen } = useArtifacts();

  const { threadId, isNewThread, setIsNewThread, isMock } = useThreadChat();
  useSpecificChatMode();

  const { showNotification } = useNotification();

  const [thread, sendMessage] = useThreadStream({
    threadId: isNewThread ? undefined : threadId,
    context: settings.context,
    isMock,
    onStart: () => {
      setIsNewThread(false);
      // ! Important: Never use next.js router for navigation in this case, otherwise it will cause the thread to re-mount and lose all states. Use native history API instead.
      history.replaceState(null, "", `/workspace/chats/${threadId}`);
    },
    onFinish: (state) => {
      if (document.hidden || !document.hasFocus()) {
        let body = "Conversation finished";
        const lastMessage = state.messages.at(-1);
        if (lastMessage) {
          const textContent = textOfMessage(lastMessage);
          if (textContent) {
            body =
              textContent.length > 200
                ? textContent.substring(0, 200) + "..."
                : textContent;
          }
        }
        showNotification(state.title, { body });
      }
    },
  });

  const handleSubmit = useCallback(
    (message: PromptInputMessage) => {
      void sendMessage(threadId, message);
    },
    [sendMessage, threadId],
  );
  const handleStop = useCallback(async () => {
    await thread.stop();
  }, [thread]);

  return (
    <ThreadContext.Provider value={{ thread, isMock }}>
      <ChatBox threadId={threadId}>
        <div className="bg-background relative flex size-full min-h-0 justify-between">
          <header
            className={cn(
              "absolute top-0 right-0 left-0 z-30 mx-[20px] grid h-[58px] shrink-0 grid-cols-3 items-center rounded-t-[20px] border-b py-[15px]",
              isNewThread
                ? "bg-background/0 backdrop-blur-none"
                : "bg-background/80 backdrop-blur",
            )}
          >
            {/* 返回查看结果左箭头 */}
            <div className="flex h-full w-full items-center text-sm font-medium">
              <Button
                size="sm"
                variant="ghost"
                className="h-full px-[10px] py-[5px] text-sm font-medium"
                onClick={() => setShowExitDialog(true)}
              >
                <svg
                  width="20"
                  height="20"
                  viewBox="0 0 20 20"
                  fill="none"
                  xmlns="http://www.w3.org/2000/svg"
                >
                  <path
                    d="M3.5 10H13.25H15.6875H16.5M3.5 10L7.5625 6M3.5 10L7.5625 14"
                    stroke="#666666"
                    strokeWidth="1.5"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                  />
                </svg>
              </Button>
            </div>
            <div className="flex h-full w-full items-center justify-center overflow-hidden text-sm font-medium">
              <ThreadTitle threadId={threadId} thread={thread} />
            </div>
            <div className="flex items-center justify-end gap-2 overflow-hidden">
              <DevTodoList
                className="bg-white"
                todos={thread.values.todos ?? []}
                hidden={
                  !thread.values.todos || thread.values.todos.length === 0
                }
                trigger={
                  <Button
                    size="sm"
                    variant="ghost"
                    className="h-full px-[10px] py-[5px] text-sm font-medium"
                  >
                    <ListTodoIcon className="size-4" /> To-dos
                  </Button>
                }
              />
              <ArtifactTrigger />
            </div>
          </header>
          <main className="flex min-h-0 max-w-full grow flex-col">
            <div className="flex size-full justify-center">
              <MessageList
                className={cn("size-full", !isNewThread && "pt-10")}
                threadId={threadId}
                thread={thread}
              />
            </div>
          </main>
        </div>
        <div
          className={cn(
            "pointer-events-none fixed right-0 bottom-3 left-0 z-30 flex justify-center px-4",
            "transition-all duration-300 ease-in-out",
            fullscreen
              ? "pointer-events-none translate-y-4 opacity-0"
              : "translate-y-0 opacity-100",
          )}
        >
          <div
            className={cn(
              "pointer-events-auto relative w-full max-w-[720px]",
              isNewThread && "top-[-65px] -translate-y-[calc(50vh-96px)]",
            )}
          >
            <InputBox
              className={cn(
                "w-full -translate-y-4 rounded-[20px] bg-[#FBFAFC]",
              )}
              isNewThread={isNewThread}
              threadId={threadId}
              autoFocus={isNewThread}
              status={thread.isLoading ? "streaming" : "ready"}
              context={settings.context}
              extraHeader={
                isNewThread && <Welcome mode={settings.context.mode} />
              }
              disabled={env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true"}
              onContextChange={(context) => setSettings("context", context)}
              onSubmit={handleSubmit}
              onStop={handleStop}
            />
            {env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true" && (
              <div className="text-muted-foreground/67 w-full translate-y-12 text-center text-xs">
                {t.common.notAvailableInDemoMode}
              </div>
            )}
          </div>
        </div>
      </ChatBox>

      {/* 退出确认对话框 */}
      <DevDialog open={showExitDialog} onOpenChange={setShowExitDialog}>
        <DevDialogContent>
          <DevDialogHeader>
            <DevDialogTitle>提示</DevDialogTitle>
          </DevDialogHeader>
          <p className="text-muted-foreground text-sm">
            退出后，当前会话结束并销毁，请先下载保存当前结果！
          </p>
          <DevDialogFooter>
            <Button
              className="w-full bg-[#f9f8fa] hover:bg-[#8E47F0] hover:text-white"
              variant="ghost"
              onClick={() => setShowExitDialog(false)}
            >
              取消
            </Button>
            <Button
              className="w-full bg-[#f9f8fa] hover:bg-[#8E47F0] hover:text-white"
              variant="ghost"
              onClick={() => setShowExitDialog(false)}
            >
              确定
            </Button>
          </DevDialogFooter>
        </DevDialogContent>
      </DevDialog>
    </ThreadContext.Provider>
  );
}
