import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
import useSharePreview from '../../hooks/use-share-preview';
import PreviewShareModal from './preview-share-modal';

// react-tooltip のアンカー追従（floating-ui の autoUpdate）が ResizeObserver 前提のため、
// Tooltip を描画するこのコンポーネントのテストでも tooltip.test.tsx と同様にモックする
beforeAll(() => {
  class MockResizeObserver {
    observe() {}

    unobserve() {}

    disconnect() {}
  }
  (globalThis as unknown as { ResizeObserver: unknown }).ResizeObserver = MockResizeObserver;
});

// クリップボードへのコピー成否は copied の値だけをテストごとに切り替えたいため、
// 呼び出しのたびに mockUseClipboard を経由する薄いラッパーにする
const mockUseClipboard = vi.fn(() => ({ copy: vi.fn(), copied: false, reset: vi.fn() }));
vi.mock('@ablogcms/react-hooks/use-clipboard', () => ({
  default: () => mockUseClipboard(),
}));

vi.mock('../../hooks/use-share-preview', () => ({
  default: vi.fn(),
}));

const mockedUseSharePreview = vi.mocked(useSharePreview);

const renderModal = () =>
  render(<PreviewShareModal isOpen onClose={vi.fn()} container={document.body} url="https://example.com/entry/1/" />);

describe('PreviewShareModal', () => {
  beforeEach(() => {
    (window as unknown as { ACMS: { Config: Record<string, unknown> } }).ACMS.Config = {
      urlPreviewExpire: 24,
    };
    mockUseClipboard.mockReturnValue({ copy: vi.fn(), copied: false, reset: vi.fn() });
  });

  it('リンク取得ボタンが acms-admin-btn-flat-primary 系の独立クラスを維持したまま描画される（unstyled で acms-admin-btn 側の装飾は打ち消される）', async () => {
    const createShareUrl = vi.fn();
    mockedUseSharePreview.mockReturnValue({
      status: 'standby',
      error: '',
      shareUrl: '',
      createShareUrl,
      setInputRef: vi.fn(),
      standby: vi.fn(),
    });

    renderModal();
    const getLinkButton = screen.getByRole('button', { name: ACMS.i18n('preview.get_link') });
    expect(getLinkButton).toHaveClass('acms-admin-btn');
    expect(getLinkButton).toHaveClass('acms-admin-btn-large');
    expect(getLinkButton).toHaveClass('acms-admin-btn-block');
    expect(getLinkButton).toHaveClass('acms-admin-btn-flat-primary');
    expect(getLinkButton).toHaveAttribute('type', 'button');

    await userEvent.click(getLinkButton);
    expect(createShareUrl).toHaveBeenCalledWith('https://example.com/entry/1/');
  });

  it('コピーボタンが Button コンポーネント経由でも既存の acms-admin-btn クラスのまま描画される', () => {
    mockedUseSharePreview.mockReturnValue({
      status: 'done',
      error: '',
      shareUrl: 'https://example.com/preview/share/xxxxx',
      createShareUrl: vi.fn(),
      setInputRef: vi.fn(),
      standby: vi.fn(),
    });

    renderModal();
    const copyButton = screen.getByRole('button', { name: ACMS.i18n('preview.copy') });
    expect(copyButton).toHaveClass('acms-admin-btn');
    expect(copyButton).toHaveAttribute('type', 'button');

    const shareUrlInput = screen.getByDisplayValue('https://example.com/preview/share/xxxxx');
    expect(shareUrlInput).toHaveAttribute('type', 'url');
    expect(shareUrlInput).toHaveAttribute('readonly');
  });

  it('コピーボタンをクリックすると、通知(トースト)ではなくボタン自体のツールチップで結果を示す', async () => {
    const copy = vi.fn();
    mockUseClipboard.mockReturnValue({ copy, copied: false, reset: vi.fn() });
    mockedUseSharePreview.mockReturnValue({
      status: 'done',
      error: '',
      shareUrl: 'https://example.com/preview/share/xxxxx',
      createShareUrl: vi.fn(),
      setInputRef: vi.fn(),
      standby: vi.fn(),
    });

    renderModal();
    const copyButton = screen.getByRole('button', { name: ACMS.i18n('preview.copy') });
    expect(copyButton).toHaveAttribute('data-tooltip-content', ACMS.i18n('preview.copy_to_clipboard'));

    await userEvent.click(copyButton);
    expect(copy).toHaveBeenCalledWith('https://example.com/preview/share/xxxxx');
  });

  it('copied が true のとき、コピーボタンに紐づくツールチップにコピー完了メッセージを表示する', async () => {
    mockUseClipboard.mockReturnValue({ copy: vi.fn(), copied: true, reset: vi.fn() });
    mockedUseSharePreview.mockReturnValue({
      status: 'done',
      error: '',
      shareUrl: 'https://example.com/preview/share/xxxxx',
      createShareUrl: vi.fn(),
      setInputRef: vi.fn(),
      standby: vi.fn(),
    });

    renderModal();
    await waitFor(() => {
      expect(screen.getByRole('tooltip')).toHaveTextContent(ACMS.i18n('preview.copy_to_clipboard'));
    });
  });
});
