import { signal, WritableSignal } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { provideRouter } from '@angular/router';
import { CharacterResponse } from './core/api/game-api.models';
import { WorldStore } from './features/world/world.store';
import { AppShellComponent } from './layout/app-shell/app-shell.component';
import { routes } from './app.routes';

describe('App', () => {
  let character: WritableSignal<CharacterResponse | null>;
  let currentLocation: WritableSignal<null>;
  let selectedConnection: WritableSignal<null>;

  beforeEach(async () => {
    character = signal<CharacterResponse | null>(null);
    currentLocation = signal(null);
    selectedConnection = signal(null);

    await TestBed.configureTestingModule({
      imports: [AppShellComponent],
      providers: [
        provideRouter([]),
        {
          provide: WorldStore,
          useValue: { character, currentLocation, selectedConnection },
        },
      ],
    }).compileComponents();
  });

  it('renders the reusable game shell with only Karte available', () => {
    const fixture = TestBed.createComponent(AppShellComponent);
    fixture.detectChanges();

    const element = fixture.nativeElement as HTMLElement;
    expect(element.querySelector('app-top-bar')).not.toBeNull();
    expect(element.querySelector('app-side-navigation')).not.toBeNull();
    expect(element.querySelector('main')).not.toBeNull();
    expect(element.querySelector('app-game-footer')).not.toBeNull();

    const mapButton = element.querySelector<HTMLButtonElement>('[data-navigation="world"]');
    expect(mapButton).not.toBeNull();
    expect(mapButton?.disabled).toBe(false);
    expect(mapButton?.getAttribute('aria-current')).toBe('page');
    expect(mapButton?.getAttribute('aria-label')).toBe('Karte');

    for (const destination of ['hunt', 'quests', 'inventory', 'character']) {
      expect(
        element.querySelector<HTMLButtonElement>(`[data-navigation="${destination}"]`)?.disabled,
      ).toBe(true);
    }

    expect(element.textContent).not.toContain('Shop');
  });

  it('renders loaded character values supplied by the WorldStore', () => {
    character.set({
      id: 'character-id',
      name: 'Mara Ashfall',
      level: 7,
      experience: 320,
      currentHp: 52,
      maxHp: 80,
      attack: 12,
      currentLocation: { id: 'location-id', key: 'south-gate', name: 'Südtor von Graufurt' },
    });
    const fixture = TestBed.createComponent(AppShellComponent);
    fixture.detectChanges();

    expect(fixture.nativeElement.querySelector('app-top-bar')?.textContent).toContain(
      'Mara Ashfall',
    );
    expect(fixture.nativeElement.querySelector('app-top-bar')?.textContent).toContain('Stufe 7');
    expect(fixture.nativeElement.querySelector('app-top-bar')?.textContent).toContain('52 / 80');
  });

  it('redirects root and unknown routes to the world shell', () => {
    expect(routes.find((route) => route.path === '')).toMatchObject({
      pathMatch: 'full',
      redirectTo: 'world',
    });
    expect(routes.find((route) => route.path === '**')).toMatchObject({ redirectTo: 'world' });
  });
});
