import { useCallback, useEffect, useRef, useState } from "react";
import { Reply, Send, X } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { cn } from "@/lib/utils";
import FileUploadButton from "./file-upload";
import type { MessageNewService } from "@/socket";

type Props = {
  roomName: string;
  replyTarget?: MessageNewService | null;
  onSend: (content: string) => Promise<void>;
  onCancelReply?: () => void;
  onTyping?: (typing: boolean) => void;
  disabled?: boolean;
};

export default function MessageComposer({
  roomName,
  replyTarget,
  onSend,
  onCancelReply,
  onTyping,
  disabled,
}: Props) {
  const [content, setContent] = useState("");
  const [sending, setSending] = useState(false);
  const typingTimeout = useRef<number | undefined>(undefined);
  const textareaRef = useRef<HTMLTextAreaElement | null>(null);

  // Focus textarea when entering reply mode
  useEffect(() => {
    if (replyTarget) {
      textareaRef.current?.focus();
    }
  }, [replyTarget?.id]);

  const handleInput = useCallback(
    (value: string) => {
      setContent(value);
      if (onTyping) {
        onTyping(true);
        clearTimeout(typingTimeout.current);
        typingTimeout.current = window.setTimeout(() => onTyping(false), 5000);
      }
    },
    [onTyping],
  );

  const handleSubmit = useCallback(async () => {
    const text = content.trim();
    if (!text || sending) return;

    setSending(true);
    try {
      await onSend(text);
      setContent("");
      onTyping?.(false);
      clearTimeout(typingTimeout.current);
    } finally {
      setSending(false);
    }
  }, [content, sending, onSend, onTyping]);

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (e.key === "Enter" && !e.shiftKey) {
        e.preventDefault();
        handleSubmit();
      }
    },
    [handleSubmit],
  );

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

  const replyAuthorName =
    replyTarget?.sender.display_name ??
    replyTarget?.sender.username ??
    "Unknown";
  const replyPreview =
    replyTarget?.content.slice(0, 100) ?? "";

  return (
    <div className="shrink-0 px-4 pb-4 pt-1">
      {/* Reply indicator */}
      {replyTarget && (
        <div className="mb-2 flex items-center gap-2 rounded-lg border border-primary/[0.08] bg-primary/[0.03] px-3 py-2">
          <Reply className="size-4 shrink-0 text-primary/50" />
          <div className="min-w-0 flex-1">
            <p className="truncate text-[12px] font-medium text-primary/70">
              Replying to {replyAuthorName}
            </p>
            <p className="truncate text-[11px] text-muted-foreground/50">
              {replyPreview}
            </p>
          </div>
          <Button
            aria-label="Cancel reply"
            className="size-8 shrink-0 cursor-pointer text-muted-foreground/30 hover:text-foreground"
            onClick={onCancelReply}
            size="icon"
            variant="ghost"
          >
            <X className="size-3.5" />
          </Button>
        </div>
      )}

      <div
        className={cn(
          "relative rounded-2xl border bg-card/80 shadow-sm transition-[background-color,border-color,box-shadow] duration-200",
          "focus-within:border-primary/20 focus-within:shadow-md focus-within:ring-1 focus-within:ring-primary/[0.06] focus-within:bg-card",
          replyTarget ? "border-primary/[0.12]" : "border-border/40",
        )}
      >
        <Textarea
          aria-label={`Message #${roomName}`}
          className={cn(
            "min-h-[52px] max-h-48 resize-none border-0 bg-transparent px-5 py-3.5 pr-28 text-[13px] leading-relaxed shadow-none focus-visible:ring-0",
            "placeholder:text-muted-foreground/35",
          )}
          disabled={disabled || sending}
          onChange={(e) => handleInput(e.target.value)}
          onKeyDown={handleKeyDown}
          placeholder={
            replyTarget
              ? `Reply to ${replyAuthorName}…`
              : `Send a message in #${roomName}`
          }
          ref={textareaRef}
          value={content}
        />
        <div className="absolute right-2 bottom-2 flex items-center gap-1">
          <FileUploadButton disabled={disabled || sending} />
          <Button
            aria-label="Send message"
            className={cn(
              "size-9 rounded-lg transition-[opacity,transform,background-color,color] duration-200",
              hasContent
                ? "scale-100 opacity-100"
                : "scale-90 opacity-40",
            )}
            disabled={!hasContent || sending}
            onClick={handleSubmit}
            size="icon"
            variant={hasContent ? "default" : "ghost"}
          >
            <Send className="size-[15px]" />
          </Button>
        </div>
      </div>
    </div>
  );
}
