// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========

import { SidebarScrollArea } from '@/components/Layout/AppSidebar';
import { render } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';

let clientHeightSpy: ReturnType<typeof vi.spyOn> | undefined;
let scrollHeightSpy: ReturnType<typeof vi.spyOn> | undefined;
afterEach(() => {
  clientHeightSpy?.mockRestore();
  scrollHeightSpy?.mockRestore();
  clientHeightSpy = undefined;
  scrollHeightSpy = undefined;
});

function mockVerticalSize({
  clientHeight,
  scrollHeight,
}: {
  clientHeight: number;
  scrollHeight: number;
}) {
  clientHeightSpy = vi
    .spyOn(HTMLElement.prototype, 'clientHeight', 'get')
    .mockReturnValue(clientHeight);
  scrollHeightSpy = vi
    .spyOn(HTMLElement.prototype, 'scrollHeight', 'get')
    .mockReturnValue(scrollHeight);
}

describe('SidebarScrollArea', () => {
  it('shows a visible scrollbar only while sidebar content overflows', () => {
    mockVerticalSize({ clientHeight: 100, scrollHeight: 180 });

    const { container } = render(
      <SidebarScrollArea>
        <div>Overflowing navigation</div>
      </SidebarScrollArea>
    );
    const scrollArea = container.querySelector(
      '[data-sidebar-scroll-overflow]'
    );

    expect(scrollArea).toHaveAttribute('data-sidebar-scroll-overflow', 'true');
    expect(scrollArea).toHaveClass(
      'scrollbar-always-visible',
      'overflow-y-auto'
    );
    expect(scrollArea).not.toHaveClass('scrollbar');
  });

  it('does not reserve a scrollbar gutter when all rows fit', () => {
    mockVerticalSize({ clientHeight: 100, scrollHeight: 100 });

    const { container } = render(
      <SidebarScrollArea>
        <div>Short navigation</div>
      </SidebarScrollArea>
    );
    const scrollArea = container.querySelector(
      '[data-sidebar-scroll-overflow]'
    );

    expect(scrollArea).toHaveAttribute('data-sidebar-scroll-overflow', 'false');
    expect(scrollArea).toHaveClass('overflow-hidden');
    expect(scrollArea).not.toHaveClass('scrollbar-always-visible');
  });
});
