import { signal } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { provideRouter, Router } from '@angular/router';

import { App } from './app';
import { routes } from './app.routes';
import { Tenant } from './core/services/tenant.interface';
import { TenantService } from './core/services/tenant.service';

const tenant: Tenant = {
  id: 1,
  codigo: 'test',
  nombre: 'Test Tenant',
  dominio: 'localhost',
  primary_color: '#6376F3',
  secondary_color: '#A0A0A0',
  danger_color: '#FF8888',
  header_footer_bg_color: '#313131',
  header_logo: 'https://example.com/header.png',
  footer_logo: 'https://example.com/footer.png'
};

function createTenantServiceStub(
  status: 'ready' | 'not-found' = 'ready',
  currentTenant: Tenant | null = tenant
) {
  const tenantState = signal(currentTenant);
  const statusState = signal(status);

  return {
    tenant: tenantState.asReadonly(),
    status: statusState.asReadonly(),
    getTenant: () => tenantState(),
    bootstrap: vi.fn().mockResolvedValue(undefined)
  };
}

async function renderAppAt(
  url: string,
  tenantService: ReturnType<typeof createTenantServiceStub> = createTenantServiceStub()
) {
  TestBed.resetTestingModule();

  await TestBed.configureTestingModule({
    imports: [App],
    providers: [
      provideRouter(routes),
      {
        provide: TenantService,
        useValue: tenantService
      }
    ]
  }).compileComponents();

  const router = TestBed.inject(Router);
  const fixture = TestBed.createComponent(App);

  fixture.detectChanges();
  await router.navigateByUrl(url);
  await fixture.whenStable();
  fixture.detectChanges();

  return { fixture, router };
}

describe('app routes', () => {
  it('loads the store layout at /', async () => {
    const { fixture, router } = await renderAppAt('/');
    const compiled = fixture.nativeElement as HTMLElement;

    expect(router.url).toBe('/');
    expect(compiled.querySelector('.store-layout')).not.toBeNull();
    expect(compiled.querySelector('.store-home')).not.toBeNull();
    expect(compiled.textContent).toContain('Tienda en construccion');
    expect(compiled.style.getPropertyValue('--tenant-primary')).toBe(tenant.primary_color);
  });

  it('loads componentes-test under a valid tenant', async () => {
    const { fixture, router } = await renderAppAt('/');
    await router.navigateByUrl('/componentes-test/reutilizables');
    await fixture.whenStable();
    fixture.detectChanges();

    const compiled = fixture.nativeElement as HTMLElement;

    expect(router.url).toBe('/componentes-test/reutilizables');
    expect(compiled.textContent).toContain('Componentes reutilizables');
  });

  it('renders the tenant not found screen for any route when the tenant is missing', async () => {
    const { fixture } = await renderAppAt(
      '/componentes-test/reutilizables',
      createTenantServiceStub('not-found', null)
    );
    const compiled = fixture.nativeElement as HTMLElement;

    expect(compiled.querySelector('.tenant-status')).not.toBeNull();
    expect(compiled.textContent).toContain('No encontramos una tienda para este dominio');
  });
});
