import '@testing-library/jest-dom/vitest';
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/svelte';
import { afterEach, describe, expect, it, vi } from 'vitest';
import CustomLinkChannel from './CustomLinkChannel.svelte';

const channel = {
  id: 'project-custom-link',
  projectID: 1,
  type: 'custom_link' as const,
  title: 'Roadmap Board',
  icon: 'link',
  url: 'https://example.com/roadmap',
  sortOrder: 1,
};
const originalClipboard = Object.getOwnPropertyDescriptor(navigator, 'clipboard');

function setClipboard(writeText: Clipboard['writeText']) {
  Object.defineProperty(navigator, 'clipboard', {
    configurable: true,
    value: { writeText } as Clipboard,
  });
}

afterEach(() => {
  cleanup();
  if (originalClipboard) {
    Object.defineProperty(navigator, 'clipboard', originalClipboard);
  } else {
    Reflect.deleteProperty(navigator, 'clipboard');
  }
});

describe('CustomLinkChannel', () => {
  it('shows copy success only after clipboard writing resolves', async () => {
    let resolveWrite: (() => void) | undefined;
    const writeText = vi.fn(
      () =>
        new Promise<void>((resolve) => {
          resolveWrite = resolve;
        }),
    );
    setClipboard(writeText);
    render(CustomLinkChannel, { props: { channel } });

    await fireEvent.click(screen.getByRole('button', { name: 'Copy URL' }));

    expect(screen.queryByText('URL copied.')).not.toBeInTheDocument();
    resolveWrite?.();
    await waitFor(() => expect(screen.getByText('URL copied.')).toBeInTheDocument());
  });

  it('reports a copy failure when clipboard writing rejects', async () => {
    setClipboard(vi.fn().mockRejectedValue(new Error('Permission denied')));
    render(CustomLinkChannel, { props: { channel } });

    await fireEvent.click(screen.getByRole('button', { name: 'Copy URL' }));

    await waitFor(() => expect(screen.getByText('Unable to copy URL.')).toBeInTheDocument());
  });

  it('reports unavailable clipboard access without showing URL copied', async () => {
    Reflect.deleteProperty(navigator, 'clipboard');
    render(CustomLinkChannel, { props: { channel } });

    await fireEvent.click(screen.getByRole('button', { name: 'Copy URL' }));

    await waitFor(() => expect(screen.getByText('Copy unavailable in this browser.')).toBeInTheDocument());
    expect(screen.queryByText('URL copied.')).not.toBeInTheDocument();
  });
});
