import { signal } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { of, throwError } from 'rxjs';
import { provideRouter } from '@angular/router';
import { AuthStore } from '../../../../core/auth/auth-store';
import { TeamPermissionsApi } from '../../../../core/team/team-permissions-api';
import { TeamStore } from '../../../../core/team/team-store';
import { Permissions } from './permissions';

describe('Permissions', () => {
  const permissions = {
    transactionCreateMinRole: 2,
    transactionReverseMinRole: 2,
    inviteMinRole: 3,
    memberManageMinRole: 3,
    penaltyManageMinRole: 3,
    publicAccessManageMinRole: 3,
  };

  const managerTeam = {
    id: 5,
    name: 'Team A',
    alias: 'a',
    balance: 0,
    players: [
      {
        id: 1,
        firstName: 'Alex',
        lastName: 'Muster',
        balance: 0,
        active: true,
        teamRole: { id: 3 },
        user: { id: 42 },
      },
    ],
  };

  async function setup(team = managerTeam) {
    const getPermissions = vi.fn(() => of(permissions));
    const updatePermissions = vi.fn(() => of({ ...permissions, inviteMinRole: 4 }));
    const refreshTeam = vi.fn();
    await TestBed.configureTestingModule({
      imports: [Permissions],
      providers: [
        provideRouter([]),
        {
          provide: AuthStore,
          useValue: {
            currentUser: signal({ id: 42, email: null, firstName: null, lastName: null, role: { id: 2 } }),
          },
        },
        { provide: TeamStore, useValue: { team: signal(team), refreshTeam } },
        { provide: TeamPermissionsApi, useValue: { getPermissions, updatePermissions } },
      ],
    }).compileComponents();
    const fixture = TestBed.createComponent(Permissions);
    fixture.detectChanges();
    return { fixture, component: fixture.componentInstance, getPermissions, updatePermissions, refreshTeam };
  }

  it('loads and displays the configured minimum roles for a manager', async () => {
    const { fixture, component, getPermissions } = await setup();

    expect(getPermissions).toHaveBeenCalledWith(5);
    expect(fixture.nativeElement.textContent).toContain('Mitglieder einladen');
    expect(component['canManage']()).toBe(true);
  });

  it('saves a changed minimum role and refreshes the team', async () => {
    const { component, updatePermissions, refreshTeam } = await setup();

    component['changeRole']('inviteMinRole', 4);

    expect(updatePermissions).toHaveBeenCalledWith(5, { inviteMinRole: 4 });
    expect(refreshTeam).toHaveBeenCalled();
  });

  it('ignores changes from a non-manager', async () => {
    const playerTeam = {
      ...managerTeam,
      players: [{ ...managerTeam.players[0], teamRole: { id: 1 } }],
    };
    const { component, updatePermissions } = await setup(playerTeam);

    component['changeRole']('inviteMinRole', 4);

    expect(updatePermissions).not.toHaveBeenCalled();
  });

  it('shows an error state when loading fails', async () => {
    const refreshTeam = vi.fn();
    await TestBed.configureTestingModule({
      imports: [Permissions],
      providers: [
        provideRouter([]),
        {
          provide: AuthStore,
          useValue: {
            currentUser: signal({ id: 42, email: null, firstName: null, lastName: null, role: { id: 2 } }),
          },
        },
        { provide: TeamStore, useValue: { team: signal(managerTeam), refreshTeam } },
        {
          provide: TeamPermissionsApi,
          useValue: {
            getPermissions: vi.fn(() => throwError(() => new Error('fail'))),
            updatePermissions: vi.fn(),
          },
        },
      ],
    }).compileComponents();
    const fixture = TestBed.createComponent(Permissions);
    fixture.detectChanges();

    expect(fixture.nativeElement.textContent).toContain('konnten nicht geladen werden');
  });
});
