import { describe, test, expect, vi } from 'vitest';
import React from 'react';
import { createRoot, Root } from 'react-dom/client';
import { act } from 'react-dom/test-utils';
import { MobilePanelBar } from './MobilePanelBar';
import { MobileChromeProvider } from '../../state/MobileChromeContext';

/**
 * Mobile-A2 (review item 5): the real BlocksPanel/PagesPanel/LayersPanel/
 * AssetsPanel/GuidedStyles all pull in Craft.js's `useEditor` and other
 * heavy dependencies not relevant here, so they're stubbed out -- this
 * suite is only exercising MobilePanelBar's OWN wiring: tapping a tab opens
 * that tab's sheet with only its panel rendered, tapping the active tab
 * again closes it, and (mirroring MobileChromeContext.test.tsx) only one
 * sheet's content is ever mounted at once.
 */
vi.mock('../left/BlocksPanel', () => ({ BlocksPanel: () => <div data-testid="panel-blocks" /> }));
vi.mock('../left/PagesPanel', () => ({ PagesPanel: () => <div data-testid="panel-pages" /> }));
vi.mock('../left/LayersPanel', () => ({ LayersPanel: () => <div data-testid="panel-layers" /> }));
vi.mock('../left/AssetsPanel', () => ({ AssetsPanel: () => <div data-testid="panel-assets" /> }));
vi.mock('../right/GuidedStyles', () => ({ GuidedStyles: () => <div data-testid="panel-styles" /> }));

let container: HTMLDivElement;
let root: Root;

function render(ui: React.ReactElement) {
  container = document.createElement('div');
  document.body.appendChild(container);
  act(() => {
    root = createRoot(container);
    root.render(ui);
  });
}

function unmount() {
  act(() => {
    root.unmount();
  });
  container.remove();
}

function tabButton(label: string): HTMLButtonElement {
  const buttons = Array.from(container.querySelectorAll('.mobile-tab-btn')) as HTMLButtonElement[];
  const btn = buttons.find((b) => b.textContent?.includes(label));
  if (!btn) throw new Error(`No tab button found for "${label}"`);
  return btn;
}

function openPanelIds(): string[] {
  return Array.from(container.querySelectorAll('[data-testid^="panel-"]')).map(
    (el) => (el as HTMLElement).dataset.testid!,
  );
}

describe('MobilePanelBar', () => {
  test('no sheet is open initially', () => {
    render(
      <MobileChromeProvider>
        <MobilePanelBar />
      </MobileChromeProvider>,
    );
    expect(container.querySelector('.mobile-sheet-backdrop')).toBeNull();
    expect(openPanelIds()).toEqual([]);
    unmount();
  });

  test('tapping a tab opens exactly that tab\'s panel', () => {
    render(
      <MobileChromeProvider>
        <MobilePanelBar />
      </MobileChromeProvider>,
    );

    act(() => {
      tabButton('Blocks').click();
    });
    expect(openPanelIds()).toEqual(['panel-blocks']);

    unmount();
  });

  test('switching tabs replaces the open sheet -- only one panel mounted at a time', () => {
    render(
      <MobileChromeProvider>
        <MobilePanelBar />
      </MobileChromeProvider>,
    );

    act(() => {
      tabButton('Blocks').click();
    });
    expect(openPanelIds()).toEqual(['panel-blocks']);

    act(() => {
      tabButton('Styles').click();
    });
    expect(openPanelIds()).toEqual(['panel-styles']);

    act(() => {
      tabButton('Assets').click();
    });
    expect(openPanelIds()).toEqual(['panel-assets']);

    unmount();
  });

  test('tapping the active tab again closes the sheet', () => {
    render(
      <MobileChromeProvider>
        <MobilePanelBar />
      </MobileChromeProvider>,
    );

    act(() => {
      tabButton('Pages').click();
    });
    expect(openPanelIds()).toEqual(['panel-pages']);
    expect(container.querySelector('.mobile-sheet-backdrop')).not.toBeNull();

    act(() => {
      tabButton('Pages').click();
    });
    expect(openPanelIds()).toEqual([]);
    expect(container.querySelector('.mobile-sheet-backdrop')).toBeNull();

    unmount();
  });

  test('active tab button carries aria-pressed=true only for the open sheet', () => {
    render(
      <MobileChromeProvider>
        <MobilePanelBar />
      </MobileChromeProvider>,
    );

    act(() => {
      tabButton('Layers').click();
    });

    expect(tabButton('Layers').getAttribute('aria-pressed')).toBe('true');
    expect(tabButton('Blocks').getAttribute('aria-pressed')).toBe('false');

    unmount();
  });
});
