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

describe('ProjectWorkbench', () => {
  it('renders project rail, channel sidebar, topbar, and inspector', () => {
    render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });

    expect(screen.getByLabelText('Project list')).toBeInTheDocument();
    expect(screen.getByRole('button', { name: 'Project A1' })).toHaveAttribute('aria-pressed', 'true');
    expect(screen.getByLabelText('Project A1 updates 36')).toBeInTheDocument();
    expect(screen.getByLabelText('Project channels')).toBeInTheDocument();
    expect(screen.getByRole('button', { name: 'Message Flow 36' })).toBeInTheDocument();
    expect(screen.getByLabelText('Global search')).toBeEnabled();
    expect(screen.getByRole('button', { name: 'Search workspace' })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: 'Switch to dark mode' })).toBeInTheDocument();
    expect(screen.getByLabelText('Object inspector')).toBeInTheDocument();
  });

  it('pins user actions and task status to the page bottom bar', () => {
    render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
    const statusBar = screen.getByLabelText('Workspace status');

    expect(within(statusBar).getByText('david@example.com')).toBeInTheDocument();
    expect(within(statusBar).getByRole('button', { name: 'Friends' })).toBeInTheDocument();
    expect(within(statusBar).getByRole('button', { name: 'Direct messages' })).toBeInTheDocument();
    expect(within(statusBar).getByRole('button', { name: 'Settings' })).toBeInTheDocument();
    expect(within(statusBar).getByText('Sync complete')).toBeInTheDocument();
    expect(within(statusBar).getByText('3 tasks running')).toBeInTheDocument();
    expect(within(statusBar).getByText('AI queue idle')).toBeInTheDocument();
    expect(within(statusBar).getByText('Draft saved')).toBeInTheDocument();
  });

  it('shows overview work queues below the metric cards', () => {
    render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });

    expect(screen.getByRole('heading', { name: 'Inbox 待处理' })).toBeInTheDocument();
    expect(screen.getByRole('heading', { name: '进行中的任务' })).toBeInTheDocument();
    expect(screen.getByRole('heading', { name: 'AI 会话' })).toBeInTheDocument();
    expect(screen.getByText('Collect competitor pricing notes')).toBeInTheDocument();
    expect(screen.getByText('Confirm homepage information architecture')).toBeInTheDocument();
  });

  it('toggles between light and dark workbench palettes', async () => {
    render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
    const shell = screen.getByLabelText('SenlinAI workbench');

    expect(shell).toHaveAttribute('data-theme', 'light');

    await fireEvent.click(screen.getByRole('button', { name: 'Switch to dark mode' }));

    expect(shell).toHaveAttribute('data-theme', 'dark');
    expect(screen.getByRole('button', { name: 'Switch to light mode' })).toBeInTheDocument();
  });

  it('refreshes channels when switching projects', async () => {
    render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });

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

    expect(screen.getByRole('button', { name: 'Project A2' })).toHaveAttribute('aria-pressed', 'true');
    expect(screen.getByText('Ops Dashboard')).toBeInTheDocument();
  });

  it('marks active channel with aria-pressed', async () => {
    render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });

    await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));

    expect(screen.getByRole('button', { name: 'Work Plan 8' })).toHaveAttribute('aria-pressed', 'true');
  });

  it('shows inspected task details in the inspector', async () => {
    render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
    const inspector = screen.getByLabelText('Object inspector');

    expect(within(inspector).getByRole('button', { name: 'Discussion' })).toHaveAttribute('aria-pressed', 'true');

    await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
    await fireEvent.click(screen.getByRole('button', { name: 'Inspect Confirm homepage information architecture' }));

    expect(within(inspector).getByRole('heading', { name: 'Confirm homepage information architecture' })).toBeInTheDocument();

    await fireEvent.click(within(inspector).getByRole('button', { name: 'Properties' }));

    expect(within(inspector).getByRole('button', { name: 'Properties' })).toHaveAttribute('aria-pressed', 'true');
    expect(within(inspector).getByText('Status')).toBeInTheDocument();
    expect(within(inspector).getByText('Open')).toBeInTheDocument();
    expect(within(inspector).getByText('Owner')).toBeInTheDocument();
    expect(within(inspector).getByText('David')).toBeInTheDocument();
  });

  it('clears the inspector when the project or channel changes', async () => {
    render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
    const inspector = screen.getByLabelText('Object inspector');

    await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
    await fireEvent.click(screen.getByRole('button', { name: 'Inspect Confirm homepage information architecture' }));
    expect(within(inspector).getByRole('heading', { name: 'Confirm homepage information architecture' })).toBeInTheDocument();

    await fireEvent.click(screen.getByRole('button', { name: 'Project A2' }));
    expect(within(inspector).getByRole('heading', { name: 'Inspector' })).toBeInTheDocument();
    expect(within(inspector).queryByRole('heading', { name: 'Confirm homepage information architecture' })).not.toBeInTheDocument();

    await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
    await fireEvent.click(screen.getByRole('button', { name: 'Inspect Confirm homepage information architecture' }));
    await fireEvent.click(screen.getByRole('button', { name: 'Message Flow 36' }));
    expect(within(inspector).getByRole('heading', { name: 'Inspector' })).toBeInTheDocument();
  });

  it('preserves task completion when switching channels within a project', async () => {
    render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });

    await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
    const task = screen.getByRole('checkbox', { name: 'Mark Confirm homepage information architecture complete' });
    await fireEvent.click(task);
    expect(task).toBeChecked();

    await fireEvent.click(screen.getByRole('button', { name: 'Message Flow 36' }));
    await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
    expect(screen.getByRole('checkbox', { name: 'Mark Confirm homepage information architecture complete' })).toBeChecked();

    await fireEvent.click(screen.getByRole('button', { name: 'Project A2' }));
    await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
    expect(screen.getByRole('checkbox', { name: 'Mark Confirm homepage information architecture complete' })).not.toBeChecked();
  });

  it('provides Copy link feedback and disables unavailable archive actions', async () => {
    const originalClipboard = Object.getOwnPropertyDescriptor(navigator, 'clipboard');
    Object.defineProperty(navigator, 'clipboard', {
      configurable: true,
      value: { writeText: vi.fn().mockResolvedValue(undefined) } as Clipboard,
    });
    render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
    const inspector = screen.getByLabelText('Object inspector');

    await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
    await fireEvent.click(screen.getByRole('button', { name: 'Inspect Confirm homepage information architecture' }));
    await fireEvent.click(within(inspector).getByRole('button', { name: 'More' }));
    await fireEvent.click(within(inspector).getByRole('button', { name: 'Copy link' }));

    await waitFor(() => expect(within(inspector).getByRole('status')).toHaveTextContent('Link copied to clipboard.'));
    expect(within(inspector).getByRole('button', { name: 'Archive is unavailable in this preview' })).toBeDisabled();

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