'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import type { ChatMessage } from '@/lib/api';
import { isSelectableMessage } from '@/lib/chat-message-utils';

export function useChatMessageSelection(messages: ChatMessage[]) {
  const [selectionMode, setSelectionMode] = useState(false);
  const [selectedMessageIds, setSelectedMessageIds] = useState<string[]>([]);
  const anchorIndexRef = useRef<number | null>(null);

  const exitSelectionMode = useCallback(() => {
    setSelectionMode(false);
    setSelectedMessageIds([]);
    anchorIndexRef.current = null;
  }, []);

  useEffect(() => {
    if (!selectionMode) return;
    const onKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        event.preventDefault();
        exitSelectionMode();
      }
    };
    window.addEventListener('keydown', onKeyDown);
    return () => window.removeEventListener('keydown', onKeyDown);
  }, [exitSelectionMode, selectionMode]);

  const enterSelectionMode = useCallback((messageId?: string) => {
    if (messageId) {
      const message = messages.find((item) => item.id === messageId);
      if (!message || !isSelectableMessage(message)) return;
    }
    setSelectionMode(true);
    setSelectedMessageIds(messageId ? [messageId] : []);
    anchorIndexRef.current = messageId ? messages.findIndex((item) => item.id === messageId) : null;
  }, [messages]);

  const addSelectedMessage = useCallback((messageId: string) => {
    const message = messages.find((item) => item.id === messageId);
    if (!message || !isSelectableMessage(message)) return;
    setSelectionMode(true);
    setSelectedMessageIds((current) => (current.includes(messageId) ? current : [...current, messageId]));
    anchorIndexRef.current = messages.findIndex((item) => item.id === messageId);
  }, [messages]);

  const toggleSelectedMessage = useCallback((messageId: string) => {
    setSelectedMessageIds((current) => {
      const next = current.includes(messageId) ? current.filter((id) => id !== messageId) : [...current, messageId];
      return next;
    });
    anchorIndexRef.current = messages.findIndex((item) => item.id === messageId);
  }, [messages]);

  const handleSelectionPointer = useCallback(
    (messageId: string, event: { ctrlKey?: boolean; metaKey?: boolean; shiftKey?: boolean }) => {
      const index = messages.findIndex((item) => item.id === messageId);
      if (index < 0) return false;

      const multiKey = Boolean(event.ctrlKey || event.metaKey);
      if (multiKey) {
        if (!selectionMode) {
          enterSelectionMode(messageId);
        } else {
          toggleSelectedMessage(messageId);
        }
        return true;
      }

      if (event.shiftKey) {
        if (!selectionMode) {
          enterSelectionMode(messageId);
        }
        const anchor = anchorIndexRef.current ?? index;
        const start = Math.min(anchor, index);
        const end = Math.max(anchor, index);
        const rangeIds = messages
          .slice(start, end + 1)
          .filter((item) => isSelectableMessage(item))
          .map((item) => item.id);
        setSelectedMessageIds(rangeIds);
        return true;
      }

      if (selectionMode) {
        toggleSelectedMessage(messageId);
        return true;
      }

      return false;
    },
    [enterSelectionMode, messages, selectionMode, toggleSelectedMessage]
  );

  return {
    selectionMode,
    selectedMessageIds,
    setSelectedMessageIds,
    enterSelectionMode,
    exitSelectionMode,
    toggleSelectedMessage,
    addSelectedMessage,
    handleSelectionPointer
  };
}
