import { useState, useRef, useEffect, useCallback } from "react";
import type { MessageType } from "@/types/MessageType";
import type { User } from "@/types/User";
import { postMessage, getUsers } from "@/api";
import { cn } from "@/lib/utils";

interface Props {
  channelId: string;
  replyTo: string | null;
  onClearReply: () => void;
  onMessageSent: () => void;
}

const TYPE_META: Record<MessageType, { prefix: string; color: string; key: string }> = {
  text: { prefix: ">", color: "text-muted-foreground", key: "1" },
  code: { prefix: "//", color: "text-[var(--color-msg-code)]", key: "2" },
  result: { prefix: "=>", color: "text-[var(--color-msg-result)]", key: "3" },
  error: { prefix: "!!", color: "text-[var(--color-msg-error)]", key: "4" },
  plan: { prefix: "::", color: "text-[var(--color-msg-plan)]", key: "5" },
};

export function ComposeBox({
  channelId,
  replyTo,
  onClearReply,
  onMessageSent,
}: Props) {
  const [content, setContent] = useState("");
  const [msgType, setMsgType] = useState<MessageType>("text");
  const [sending, setSending] = useState(false);
  const [focused, setFocused] = useState(false);
  const [users, setUsers] = useState<User[]>([]);
  const [mentionOpen, setMentionOpen] = useState(false);
  const [mentionQuery, setMentionQuery] = useState("");
  const [mentionIdx, setMentionIdx] = useState(0);
  const inputRef = useRef<HTMLTextAreaElement>(null);
  const meta = TYPE_META[msgType];

  // Load users for mention autocomplete
  useEffect(() => {
    getUsers().then(setUsers).catch(() => {});
  }, []);

  // Auto-resize textarea
  useEffect(() => {
    if (inputRef.current) {
      inputRef.current.style.height = "0";
      inputRef.current.style.height = `${Math.min(inputRef.current.scrollHeight, 120)}px`;
    }
  }, [content]);

  // Auto-focus on mount
  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  // Detect @mention typing
  const checkMention = useCallback((text: string, cursorPos: number) => {
    const before = text.slice(0, cursorPos);
    const match = before.match(/@(\w*)$/);
    if (match) {
      setMentionOpen(true);
      setMentionQuery(match[1].toLowerCase());
      setMentionIdx(0);
    } else {
      setMentionOpen(false);
    }
  }, []);

  const filteredUsers = users.filter((u) =>
    u.username.toLowerCase().includes(mentionQuery) ||
    u.display_name.toLowerCase().includes(mentionQuery)
  );

  function insertMention(username: string) {
    const textarea = inputRef.current;
    if (!textarea) return;
    const pos = textarea.selectionStart;
    const before = content.slice(0, pos);
    const after = content.slice(pos);
    const mentionStart = before.lastIndexOf("@");
    const newContent = before.slice(0, mentionStart) + `@${username} ` + after;
    setContent(newContent);
    setMentionOpen(false);
    textarea.focus();
  }

  async function handleSend() {
    if (!content.trim() || sending) return;
    setSending(true);
    try {
      await postMessage(channelId, {
        content: content.trim(),
        type: msgType,
        reply_to: replyTo ?? undefined,
      });
      setContent("");
      setMsgType("text");
      onClearReply();
      onMessageSent();
    } finally {
      setSending(false);
    }
  }

  function cycleType(direction: 1 | -1) {
    const types: MessageType[] = ["text", "code", "result", "error", "plan"];
    const idx = types.indexOf(msgType);
    const next = (idx + direction + types.length) % types.length;
    setMsgType(types[next]);
  }

  return (
    <div className={cn(
      "transition-colors px-4 py-4 md:px-6 md:py-5 pb-[env(safe-area-inset-bottom,16px)]",
      focused ? "bg-card" : "bg-background",
    )}>
      {/* Reply chip */}
      {replyTo && (
        <div className="flex items-center gap-1.5 mb-1.5 text-[10px] font-mono">
          <span className="text-primary">^</span>
          <span className="text-muted-foreground">#{replyTo.slice(0, 8)}</span>
          <button
            type="button"
            onClick={onClearReply}
            className="text-muted-foreground hover:text-primary ml-1"
          >
            x
          </button>
        </div>
      )}

      {/* Mention autocomplete */}
      {mentionOpen && filteredUsers.length > 0 && (
        <div className="mb-2 border-2 border-border bg-card">
          {filteredUsers.map((u, i) => (
            <button
              type="button"
              key={u.id}
              onMouseDown={(e) => { e.preventDefault(); insertMention(u.username); }}
              className={cn(
                "w-full text-left px-3 py-2 text-xs font-mono flex items-center gap-2 transition-colors",
                i === mentionIdx ? "bg-primary/15 text-primary" : "text-foreground hover:bg-muted",
              )}
            >
              <span className="font-bold">@{u.username}</span>
              <span className="text-muted-foreground">{u.display_name}</span>
              <span className="text-[9px] text-muted-foreground/50 uppercase">{u.role}</span>
            </button>
          ))}
        </div>
      )}

      {/* Floating input container */}
      <div className={cn(
        "border-2 transition-colors px-4 py-3 md:px-5 md:py-4",
        focused ? "border-primary/40 bg-muted/30" : "border-border bg-muted/10",
      )}>
        {/* Textarea */}
        <textarea
          ref={inputRef}
          value={content}
          onChange={(e) => {
            setContent(e.target.value);
            checkMention(e.target.value, e.target.selectionStart);
          }}
          onFocus={() => setFocused(true)}
          onBlur={() => { setFocused(false); setTimeout(() => setMentionOpen(false), 200); }}
          onKeyDown={(e) => {
            // Mention navigation
            if (mentionOpen && filteredUsers.length > 0) {
              if (e.key === "ArrowDown") {
                e.preventDefault();
                setMentionIdx((i) => Math.min(i + 1, filteredUsers.length - 1));
                return;
              }
              if (e.key === "ArrowUp") {
                e.preventDefault();
                setMentionIdx((i) => Math.max(i - 1, 0));
                return;
              }
              if (e.key === "Enter" || e.key === "Tab") {
                e.preventDefault();
                insertMention(filteredUsers[mentionIdx].username);
                return;
              }
              if (e.key === "Escape") {
                setMentionOpen(false);
                return;
              }
            }

            if (e.key === "Enter" && !e.shiftKey) {
              e.preventDefault();
              handleSend();
            }
            if (e.key === "Tab" && !e.shiftKey) {
              e.preventDefault();
              cycleType(1);
            }
            if (e.key === "Tab" && e.shiftKey) {
              e.preventDefault();
              cycleType(-1);
            }
            if (e.ctrlKey && e.key >= "1" && e.key <= "5") {
              e.preventDefault();
              const types: MessageType[] = ["text", "code", "result", "error", "plan"];
              setMsgType(types[parseInt(e.key) - 1]);
            }
          }}
          placeholder="message"
          disabled={sending}
          rows={1}
          className={cn(
            "w-full bg-transparent text-sm font-mono text-foreground placeholder:text-muted-foreground/30 resize-none focus:outline-none leading-relaxed",
            sending && "opacity-30",
          )}
        />

        {/* Bottom bar — prefix + type indicator */}
        <div className="flex items-center justify-between mt-3 pt-2">
          <button
            type="button"
            onClick={() => cycleType(1)}
            className={cn(
              "font-mono text-xs font-bold transition-colors select-none",
              meta.color,
            )}
            title={`${msgType} (Tab to cycle)`}
          >
            {meta.prefix}
          </button>

          <span className={cn(
            "text-[9px] font-mono uppercase tracking-[0.2em] transition-opacity",
            meta.color,
            content ? "opacity-60" : "opacity-25",
          )}>
            {msgType} · enter to send
          </span>
        </div>
      </div>
    </div>
  );
}
