"use client";
import { useEffect, useRef, useState } from "react";

import { createPendingChatPromotion } from "@/lib/navigation/chat_unlock_session";
import {
  useActiveCharacter,
  useActiveCharacterRoutes,
} from "@/providers/character-provider";
import { useChatDispatch } from "@/stores/chat/chat-context";
import { Logger } from "@/utils/logger";

import { useChatKeyboardAvoidance } from "../hooks/use-chat-keyboard-avoidance";
import { useChatKeyboardDiagnostics } from "../hooks/use-chat-keyboard-diagnostics";
import { ChatComposerActionMenu } from "./chat-composer-action-menu";
import { ChatInputTextField } from "./chat-input-text-field";
import { ChatSendButton } from "./chat-send-button";
import styles from "./chat-input-bar.module.css";

const log = new Logger("AppChatComponentsChatInputBar");
const POINTER_SEND_DEBOUNCE_MS = 300;
const CHAT_ACTION_MENU_ID = "chat-composer-action-menu";

export interface ChatInputBarProps {
  disabled?: boolean;
}

export function ChatInputBar({ disabled = false }: ChatInputBarProps) {
  const dispatch = useChatDispatch();
  const character = useActiveCharacter();
  const characterRoutes = useActiveCharacterRoutes();
  const [input, setInput] = useState("");
  const [isFocused, setIsFocused] = useState(false);
  const [isActionMenuOpen, setIsActionMenuOpen] = useState(false);
  const [previousDisabled, setPreviousDisabled] = useState(disabled);
  const barRef = useRef<HTMLDivElement>(null);
  const textareaRef = useRef<HTMLTextAreaElement>(null);
  const lastPointerSendAtRef = useRef(0);

  const hasContent = input.trim().length > 0;

  if (disabled !== previousDisabled) {
    setPreviousDisabled(disabled);
    if (disabled && isActionMenuOpen) setIsActionMenuOpen(false);
  }

  useChatKeyboardAvoidance({
    active: isFocused,
    containerRef: barRef,
  });
  useChatKeyboardDiagnostics({ containerRef: barRef });

  useEffect(() => {
    if (!isActionMenuOpen) return;

    const handlePointerDown = (event: PointerEvent) => {
      const target = event.target;
      if (target instanceof Node && barRef.current?.contains(target)) return;
      setIsActionMenuOpen(false);
    };
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === "Escape") setIsActionMenuOpen(false);
    };

    document.addEventListener("pointerdown", handlePointerDown);
    document.addEventListener("keydown", handleKeyDown);
    return () => {
      document.removeEventListener("pointerdown", handlePointerDown);
      document.removeEventListener("keydown", handleKeyDown);
    };
  }, [isActionMenuOpen]);

  const handleInputChange = (value: string) => {
    setInput(value);
    if (value.trim().length > 0) setIsActionMenuOpen(false);
  };

  const handleFocusChange = (focused: boolean) => {
    setIsFocused(focused);
    if (focused) setIsActionMenuOpen(false);
  };

  const handleSend = (source: "click" | "keyboard" | "pointerdown") => {
    if (source === "click") {
      const elapsed = Date.now() - lastPointerSendAtRef.current;
      if (elapsed >= 0 && elapsed < POINTER_SEND_DEBOUNCE_MS) {
        log.debug("[chat-input-bar] suppress duplicate click", {
          elapsed,
          contentLength: input.length,
          hasContent,
          disabled,
          isFocused,
        });
        return;
      }
    }
    if (disabled || !hasContent) return;
    log.debug("[chat-input-bar] handleSend", {
      source,
      contentLength: input.length,
      contentPreview: input.slice(0, 50),
      hasContent,
      disabled,
      isFocused,
    });
    dispatch({ type: "ChatSendMessage", content: input });
    setInput("");
    setIsActionMenuOpen(false);
    textareaRef.current?.focus();
  };

  const handlePointerDownSend = () => {
    lastPointerSendAtRef.current = Date.now();
    handleSend("pointerdown");
  };

  const handleMenuToggle = () => {
    if (disabled || hasContent) return;
    const elapsed = Date.now() - lastPointerSendAtRef.current;
    if (elapsed >= 0 && elapsed < POINTER_SEND_DEBOUNCE_MS) {
      log.debug("[chat-input-bar] suppress post-send menu toggle", {
        elapsed,
        disabled,
        isFocused,
      });
      return;
    }
    if (!isActionMenuOpen) textareaRef.current?.blur();
    setIsActionMenuOpen((open) => !open);
  };

  const handlePromotion = (promotionType: "image" | "voice") => {
    if (disabled) return;
    dispatch({
      type: "ChatPromotionInjected",
      promotion: createPendingChatPromotion(
        promotionType,
        character.id,
      ),
    });
    setIsActionMenuOpen(false);
  };

  return (
    <div ref={barRef} className={styles.bar}>
      <div className={styles.composer}>
        {isActionMenuOpen ? (
          <ChatComposerActionMenu
            id={CHAT_ACTION_MENU_ID}
            disabled={disabled}
            tipHref={characterRoutes.tip}
            onImage={() => handlePromotion("image")}
            onVoice={() => handlePromotion("voice")}
            onNavigate={() => setIsActionMenuOpen(false)}
          />
        ) : null}
        <div
          className={`${styles.row} ${isFocused ? styles.rowFocused : ""}`}
        >
          <ChatInputTextField
            ref={textareaRef}
            value={input}
            onChange={handleInputChange}
            onSubmit={() => handleSend("keyboard")}
            onFocusChange={handleFocusChange}
            disabled={disabled}
          />
          <ChatSendButton
            disabled={disabled}
            hasContent={hasContent}
            isMenuOpen={isActionMenuOpen}
            menuId={CHAT_ACTION_MENU_ID}
            onClick={() => handleSend("click")}
            onMenuToggle={handleMenuToggle}
            onPointerDownSend={handlePointerDownSend}
          />
        </div>
      </div>
    </div>
  );
}
