import { fireEvent, render, screen } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { useStore } from '../store/useStore';
import { resetStore } from '../test/storeTestUtils';
import { ToolsPalette } from './ToolsPalette';

describe('ToolsPalette', () => {
  beforeEach(() => {
    resetStore();
  });

  it('switches workspace editing tools without showing AI prompt or duplicate undo tools', () => {
    const setActiveTool = vi.fn();

    render(
      <ToolsPalette
        activeTool="move"
        setActiveTool={setActiveTool}
      />,
    );

    fireEvent.click(screen.getByTitle('创建多边形 (P)'));
    fireEvent.click(screen.getByTitle('调整多边形 (E)'));
    fireEvent.click(screen.getByTitle('画笔 (B)'));
    fireEvent.click(screen.getByTitle('橡皮擦 (X)'));

    expect(setActiveTool).toHaveBeenNthCalledWith(1, 'create_polygon');
    expect(setActiveTool).toHaveBeenNthCalledWith(2, 'edit_polygon');
    expect(setActiveTool).toHaveBeenNthCalledWith(3, 'brush');
    expect(setActiveTool).toHaveBeenNthCalledWith(4, 'eraser');
    expect(screen.queryByTitle('正向选点 (SAM)')).not.toBeInTheDocument();
    expect(screen.queryByTitle('反向选点 (SAM)')).not.toBeInTheDocument();
    expect(screen.queryByTitle('边界框选 (SAM)')).not.toBeInTheDocument();
    expect(screen.queryByTitle('撤销操作 (Ctrl+Z)')).not.toBeInTheDocument();
    expect(screen.queryByTitle('重做操作 (Ctrl+Shift+Z)')).not.toBeInTheDocument();
    expect(screen.queryByTitle('创建点 (C)')).not.toBeInTheDocument();
    expect(screen.queryByTitle('创建线段 (L)')).not.toBeInTheDocument();
  });

  it('shows size controls for brush and eraser tools', () => {
    const { rerender } = render(<ToolsPalette activeTool="brush" setActiveTool={vi.fn()} />);
    const brushSize = screen.getByLabelText('画笔大小');
    fireEvent.change(brushSize, { target: { value: '36' } });
    expect(useStore.getState().brushSize).toBe(36);

    rerender(<ToolsPalette activeTool="eraser" setActiveTool={vi.fn()} />);
    const eraserSize = screen.getByLabelText('橡皮擦大小');
    fireEvent.change(eraserSize, { target: { value: '48' } });
    expect(useStore.getState().eraserSize).toBe(48);
  });

  it('places GT mask import after overlap removal with a distinct violet style', () => {
    const onImportGtMask = vi.fn();
    render(
      <ToolsPalette
        activeTool="move"
        setActiveTool={vi.fn()}
        onImportGtMask={onImportGtMask}
        canImportGtMask
      />,
    );

    const overlapButton = screen.getByTitle('重叠区域去除 (-)');
    const importButton = screen.getByTitle('导入 GT Mask');
    fireEvent.click(importButton);

    expect(onImportGtMask).toHaveBeenCalled();
    expect(importButton).toHaveClass('bg-violet-500/10');
    expect(overlapButton.compareDocumentPosition(importButton) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
  });

  it('exposes clear mask action in the left toolbar', () => {
    const onClearMasks = vi.fn();
    const onDeleteMasks = vi.fn();
    render(<ToolsPalette activeTool="move" setActiveTool={vi.fn()} onClearMasks={onClearMasks} onDeleteMasks={onDeleteMasks} />);

    fireEvent.click(screen.getByTitle('删除选中遮罩 (Del)'));
    fireEvent.click(screen.getByTitle('清空遮罩'));

    expect(onDeleteMasks).toHaveBeenCalled();
    expect(onClearMasks).toHaveBeenCalled();
  });

  it('places colored auto propagation below the eraser tool', () => {
    const setActiveTool = vi.fn();
    const onAutoPropagate = vi.fn();
    render(
      <ToolsPalette
        activeTool="move"
        setActiveTool={setActiveTool}
        onAutoPropagate={onAutoPropagate}
        canAutoPropagate
      />,
    );

    const eraserButton = screen.getByTitle('橡皮擦 (X)');
    const autoButton = screen.getByRole('button', { name: '自动传播' });
    fireEvent.click(autoButton);

    expect(autoButton).toHaveClass('bg-cyan-500/10');
    expect(autoButton.querySelector('[data-testid="ai-segmentation-icon"]')).toBeInTheDocument();
    expect(eraserButton.compareDocumentPosition(autoButton) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
    expect(setActiveTool).toHaveBeenCalledWith('auto_propagate');
    expect(onAutoPropagate).toHaveBeenCalled();
  });

  it('separates drawing, editing, and external action tool groups', () => {
    const { container } = render(<ToolsPalette activeTool="move" setActiveTool={vi.fn()} canImportGtMask />);

    const separators = Array.from(container.querySelectorAll('.h-px'));
    const externalActionSeparator = screen.getByTestId('tool-group-separator');
    const circleButton = screen.getByTitle('创建圆 (O)');
    const brushButton = screen.getByTitle('画笔 (B)');
    const eraserButton = screen.getByTitle('橡皮擦 (X)');
    const autoButton = screen.getByRole('button', { name: '自动传播' });
    const mergeButton = screen.getByTitle('区域合并 (+)');
    const removeButton = screen.getByTitle('重叠区域去除 (-)');
    const deleteButton = screen.getByTitle('删除选中遮罩 (Del)');
    const clearButton = screen.getByTitle('清空遮罩');
    const importButton = screen.getByTitle('导入 GT Mask');

    expect(separators).toHaveLength(3);
    expect(externalActionSeparator).toBe(separators[2]);
    expect(circleButton.compareDocumentPosition(separators[0]) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
    expect(separators[0].compareDocumentPosition(brushButton) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
    expect(eraserButton.compareDocumentPosition(autoButton) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
    expect(autoButton.compareDocumentPosition(separators[1]) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
    expect(separators[1].compareDocumentPosition(mergeButton) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
    expect(removeButton.compareDocumentPosition(deleteButton) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
    expect(deleteButton.compareDocumentPosition(clearButton) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
    expect(clearButton.compareDocumentPosition(separators[2]) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
    expect(separators[2].compareDocumentPosition(importButton) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
    separators.forEach((separator) => {
      expect(separator).toHaveClass('bg-white/15');
    });
  });

  it('switches to SAM trigger and calls the AI navigation hook', () => {
    const setActiveTool = vi.fn();
    const onTriggerAI = vi.fn();

    render(<ToolsPalette activeTool="move" setActiveTool={setActiveTool} onTriggerAI={onTriggerAI} />);
    const aiButton = screen.getByTitle('打开 AI 智能分割');
    expect(aiButton.querySelector('[data-testid="ai-segmentation-icon"]')).toBeInTheDocument();
    fireEvent.click(aiButton);

    expect(setActiveTool).toHaveBeenCalledWith('sam_trigger');
    expect(onTriggerAI).toHaveBeenCalled();
  });

  it('uses compact vertically scrollable layout for smaller workspaces', () => {
    const { container } = render(<ToolsPalette activeTool="move" setActiveTool={vi.fn()} />);
    const palette = container.firstElementChild;

    expect(palette).toHaveClass('w-14');
    expect(palette).toHaveClass('overflow-y-auto');
    expect(palette).toHaveClass('seg-scrollbar');
    expect(palette?.firstElementChild).toHaveClass('w-12');
    expect(screen.getByTitle('创建多边形 (P)')).toHaveClass('h-9');
    expect(screen.getByTitle('打开 AI 智能分割')).toHaveClass('h-9');
  });
});
