/**
 * Dialogs Tests
 *
 * Tests the FlowBuilder Dialogs component including:
 * - Node deletion dialog
 * - Unsaved changes dialog
 * - Cancel/confirm handlers
 */
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { Dialogs, DialogsProps } from './Dialogs';

// Mock the UIStore
const mockSetShowUnsavedDialog = vi.fn();

vi.mock('../../stores', () => ({
  useDialogState: vi.fn(() => ({
    nodeToDelete: null,
    showUnsavedDialog: false,
    setShowUnsavedDialog: mockSetShowUnsavedDialog,
  })),
}));

import { useDialogState } from '../../stores';

describe('Dialogs', () => {
  const defaultProps: DialogsProps = {
    onConfirmDeleteNode: vi.fn(),
    onCancelDeleteNode: vi.fn(),
    onLeaveWithoutSaving: vi.fn(),
  };

  beforeEach(() => {
    vi.clearAllMocks();
  });

  // ==========================================================================
  // Node Deletion Dialog Tests
  // ==========================================================================

  describe('node deletion dialog', () => {
    it('shows dialog when nodeToDelete is set', () => {
      vi.mocked(useDialogState).mockReturnValue({
        nodeToDelete: { id: 'node-1', name: 'Send Email' },
        showUnsavedDialog: false,
        setShowUnsavedDialog: mockSetShowUnsavedDialog,
      } as any);

      render(<Dialogs {...defaultProps} />);

      expect(screen.getByText('Delete Node')).toBeInTheDocument();
      expect(screen.getByText(/Are you sure you want to delete "Send Email"/)).toBeInTheDocument();
    });

    it('does not show dialog when nodeToDelete is null', () => {
      vi.mocked(useDialogState).mockReturnValue({
        nodeToDelete: null,
        showUnsavedDialog: false,
        setShowUnsavedDialog: mockSetShowUnsavedDialog,
      } as any);

      render(<Dialogs {...defaultProps} />);

      expect(screen.queryByText('Delete Node')).not.toBeInTheDocument();
    });

    it('calls onCancelDeleteNode when cancel clicked', () => {
      vi.mocked(useDialogState).mockReturnValue({
        nodeToDelete: { id: 'node-1', name: 'Test Node' },
        showUnsavedDialog: false,
        setShowUnsavedDialog: mockSetShowUnsavedDialog,
      } as any);

      render(<Dialogs {...defaultProps} />);

      fireEvent.click(screen.getByText('Cancel'));

      expect(defaultProps.onCancelDeleteNode).toHaveBeenCalled();
    });

    it('calls onConfirmDeleteNode when delete clicked', () => {
      vi.mocked(useDialogState).mockReturnValue({
        nodeToDelete: { id: 'node-1', name: 'Test Node' },
        showUnsavedDialog: false,
        setShowUnsavedDialog: mockSetShowUnsavedDialog,
      } as any);

      render(<Dialogs {...defaultProps} />);

      fireEvent.click(screen.getByText('Delete'));

      expect(defaultProps.onConfirmDeleteNode).toHaveBeenCalled();
    });
  });

  // ==========================================================================
  // Unsaved Changes Dialog Tests
  // ==========================================================================

  describe('unsaved changes dialog', () => {
    it('shows dialog when showUnsavedDialog is true', () => {
      vi.mocked(useDialogState).mockReturnValue({
        nodeToDelete: null,
        showUnsavedDialog: true,
        setShowUnsavedDialog: mockSetShowUnsavedDialog,
      } as any);

      render(<Dialogs {...defaultProps} />);

      expect(screen.getByText('Unsaved Changes')).toBeInTheDocument();
      expect(screen.getByText(/You have unsaved changes/)).toBeInTheDocument();
    });

    it('does not show dialog when showUnsavedDialog is false', () => {
      vi.mocked(useDialogState).mockReturnValue({
        nodeToDelete: null,
        showUnsavedDialog: false,
        setShowUnsavedDialog: mockSetShowUnsavedDialog,
      } as any);

      render(<Dialogs {...defaultProps} />);

      expect(screen.queryByText('Unsaved Changes')).not.toBeInTheDocument();
    });

    it('calls onLeaveWithoutSaving when leave button clicked', () => {
      vi.mocked(useDialogState).mockReturnValue({
        nodeToDelete: null,
        showUnsavedDialog: true,
        setShowUnsavedDialog: mockSetShowUnsavedDialog,
      } as any);

      render(<Dialogs {...defaultProps} />);

      fireEvent.click(screen.getByText('Leave Without Saving'));

      expect(defaultProps.onLeaveWithoutSaving).toHaveBeenCalled();
    });
  });
});
