import { TestBed } from '@angular/core/testing';
import { AuthStore } from './auth-store';
import { RoleId } from '../../models/role.model';

describe('AuthStore', () => {
  beforeEach(() => {
    localStorage.clear();
  });

  it('starts logged out when nothing is stored', () => {
    TestBed.configureTestingModule({});
    const store = TestBed.inject(AuthStore);

    expect(store.isLoggedIn()).toBe(false);
    expect(store.currentUser()).toBeNull();
  });

  it('stores the session and exposes it as logged in', () => {
    TestBed.configureTestingModule({});
    const store = TestBed.inject(AuthStore);
    const user = { id: 1, email: 'a@b.de', firstName: 'A', lastName: 'B' };

    store.setSession('jwt-token', user);

    expect(store.isLoggedIn()).toBe(true);
    expect(store.token()).toBe('jwt-token');
    expect(store.currentUser()).toEqual(user);
    expect(localStorage.getItem('tw_token')).toBe('jwt-token');
  });

  it('restores the session from localStorage on creation', () => {
    localStorage.setItem('tw_token', 'stored-token');
    localStorage.setItem(
      'tw_user',
      JSON.stringify({ id: 2, email: 'c@d.de', firstName: 'C', lastName: 'D' }),
    );

    TestBed.configureTestingModule({});
    const store = TestBed.inject(AuthStore);

    expect(store.isLoggedIn()).toBe(true);
    expect(store.token()).toBe('stored-token');
    expect(store.currentUser()?.email).toBe('c@d.de');
  });

  it('does not throw and starts logged out when stored user JSON is invalid', () => {
    localStorage.setItem('tw_user', 'not-json');

    TestBed.configureTestingModule({});

    expect(() => TestBed.inject(AuthStore)).not.toThrow();
    const store = TestBed.inject(AuthStore);
    expect(store.currentUser()).toBeNull();
  });

  it('clears the session', () => {
    TestBed.configureTestingModule({});
    const store = TestBed.inject(AuthStore);
    store.setSession('jwt-token', { id: 1, email: 'a@b.de', firstName: 'A', lastName: 'B' });

    store.clearSession();

    expect(store.isLoggedIn()).toBe(false);
    expect(store.currentUser()).toBeNull();
    expect(localStorage.getItem('tw_token')).toBeNull();
  });

  it('updates and persists the current user without changing the token', () => {
    TestBed.configureTestingModule({});
    const store = TestBed.inject(AuthStore);
    store.setSession('jwt-token', { id: 1, email: 'a@b.de', firstName: 'A', lastName: 'B' });
    const updated = { id: 1, email: 'a@b.de', firstName: 'Alex', lastName: 'Neu' };

    store.updateUser(updated);

    expect(store.currentUser()).toEqual(updated);
    expect(localStorage.getItem('tw_token')).toBe('jwt-token');
    expect(JSON.parse(localStorage.getItem('tw_user')!)).toEqual(updated);
  });

  it('derives the global admin presentation hint from the current user role', () => {
    TestBed.configureTestingModule({});
    const store = TestBed.inject(AuthStore);
    store.setSession('jwt-token', {
      id: 1,
      email: 'admin@example.de',
      firstName: 'Ada',
      lastName: 'Admin',
      role: { id: RoleId.Admin, name: 'admin' },
    });

    expect(store.currentGlobalRole()).toBe(RoleId.Admin);
    expect(store.isGlobalAdmin()).toBe(true);
  });

  it('does not treat a signed-in standard user as a global admin', () => {
    TestBed.configureTestingModule({});
    const store = TestBed.inject(AuthStore);
    store.setSession('jwt-token', {
      id: 2,
      email: 'user@example.de',
      firstName: 'Ute',
      lastName: 'User',
      role: { id: RoleId.User, name: 'user' },
    });

    expect(store.currentGlobalRole()).toBe(RoleId.User);
    expect(store.isGlobalAdmin()).toBe(false);
  });
});
