import React from 'react';
import { cleanup, fireEvent, render, screen, waitFor, within } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

const mocks = vi.hoisted(() => ({
  getProfiles: vi.fn(),
  getSchemas: vi.fn(),
  getSchema: vi.fn(),
  assertBackendSession: vi.fn(),
  readSnapshot: vi.fn(),
  readFieldCatalog: vi.fn(),
  coordinate: vi.fn(),
  checkStatus: vi.fn(),
}));

vi.mock('@nexuscrm/host-sdk', () => ({
  getErrorMessage: (error: unknown, fallback: string) => error instanceof Error ? error.message : fallback,
}));

vi.mock('../src/platform/infrastructure/api/users', () => ({
  usersAPI: { getProfiles: mocks.getProfiles },
  controlledByParentAuthoring: () => null,
}));

vi.mock('../src/platform/infrastructure/api/metadata', () => ({
  metadataAPI: { getSchemas: mocks.getSchemas, getSchema: mocks.getSchema },
}));

vi.mock('../src/platform/infrastructure/api/permissionAuthoring', () => ({
  permissionAuthoringAPI: {
    assertBackendSession: mocks.assertBackendSession,
    readSnapshot: mocks.readSnapshot,
    readFieldCatalog: mocks.readFieldCatalog,
  },
  newPermissionAuthoringCommandId: () => 'permission-authoring:test',
  coordinatePermissionAuthoringCommand: mocks.coordinate,
  checkPermissionAuthoringCommandStatus: mocks.checkStatus,
  projectPermissionAuthoringFields: (
    objects: Array<{ name: string; fields?: Array<{ name: string }> }>,
    storedGrants: Array<{ resourceType: string; fieldName: string; read: boolean; edit: boolean }>,
  ) => {
    const stored = new Map(storedGrants.map(grant => [
      `${grant.resourceType.toLowerCase()}\u0000${grant.fieldName.toLowerCase()}`,
      grant,
    ]));
    return objects.flatMap(object => (object.fields ?? []).map(field => {
      const grant = stored.get(`${object.name.toLowerCase()}\u0000${field.name.toLowerCase()}`);
      return {
        resourceType: object.name,
        fieldName: field.name,
        read: grant?.read ?? false,
        edit: grant?.edit ?? false,
      };
    }));
  },
  projectPermissionAuthoringRecordTypes: () => [],
  buildPermissionAuthoringRecordTypeChanges: () => [],
}));

import { StudioPermissions, authorableStudioProfiles } from '../src/platform/features/studio/components/StudioPermissions';
import { PermissionEditorModal } from '../src/platform/features/security/components/PermissionEditorModal';
import type { Profile, SObjectDescribe } from '../src/platform/types';

const systemProfile = { Id: 'profile-system', Name: 'System Administrator', IsSystem: true } as Profile;
const customProfile = { Id: 'profile-custom', Name: 'Service Profile', IsSystem: false } as Profile;
const secondCustomProfile = { Id: 'profile-second', Name: 'Sales Profile', IsSystem: false } as Profile;
const malformedProfile = { Id: 'profile-unknown', Name: 'Unknown Profile' } as Profile;

afterEach(cleanup);

beforeEach(() => {
  mocks.getProfiles.mockReset();
  mocks.getSchemas.mockReset();
  mocks.getSchema.mockReset();
  mocks.assertBackendSession.mockReset();
  mocks.readSnapshot.mockReset();
  mocks.readFieldCatalog.mockReset();
  mocks.coordinate.mockReset();
  mocks.checkStatus.mockReset();
});

describe('Permission editor stale Snapshot fence', () => {
  it.each(['single', 'all'])('does not grant Create through the %s Modify All control', async control => {
    const snapshot = emptySnapshot();
    snapshot.catalog.objects = [{ resourceType: 'Account', label: 'Account', sharingModel: 'ReadWrite' }];
    mocks.readSnapshot.mockResolvedValue(snapshot);
    render(<PermissionEditorModal
      entity={{ id: customProfile.Id, name: customProfile.Name, type: 'profile' }}
      onClose={vi.fn()} onSave={vi.fn()}
    />);
    await waitFor(() => expect(screen.getAllByRole('checkbox')).toHaveLength(12));
    fireEvent.click(control === 'all' ? screen.getByTitle('Toggle all: Modify All') : screen.getAllByRole('checkbox')[11]);
    const row = screen.getAllByRole('checkbox').slice(6);
    expect(row[0]).toBeChecked();
    expect(row[1]).not.toBeChecked();
    expect(row[2]).toBeChecked();
    expect(row[3]).toBeChecked();
    expect(row[4]).toBeChecked();
    expect(row[5]).toBeChecked();
  });

  it('rejects an external session before reading schemas or authoring state', async () => {
    mocks.assertBackendSession.mockImplementation(() => { throw new Error('backend session required'); });

    render(<PermissionEditorModal
      entity={{ id: customProfile.Id, name: customProfile.Name, type: 'profile' }}
      onClose={vi.fn()}
      onSave={vi.fn()}
    />);

    expect(await screen.findByText('backend session required')).toBeInTheDocument();
    expect(mocks.getSchemas).not.toHaveBeenCalled();
    expect(mocks.readSnapshot).not.toHaveBeenCalled();
  });

  it('uses a live request signal when React StrictMode replays effects', async () => {
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());

    render(<React.StrictMode>
      <PermissionEditorModal
        entity={{ id: customProfile.Id, name: customProfile.Name, type: 'profile' }}
        onClose={vi.fn()}
        onSave={vi.fn()}
      />
    </React.StrictMode>);

    await waitFor(() => expect(mocks.readSnapshot.mock.calls.length).toBeGreaterThanOrEqual(2));
    const latestSignal = mocks.readSnapshot.mock.calls.at(-1)?.[1] as AbortSignal | undefined;
    expect(latestSignal?.aborted).toBe(false);
  });

  it('hydrates complete authoring objects and fields without caller-filtered describe', async () => {
    const authoringCatalog = {
      resourceType: 'Account',
      catalogRevision: '18',
      fields: [
        { name: 'Name', label: 'Account Name' },
        // This field is deliberately absent from caller-filtered Describe. A
        // ManageProfilesPermSets operator must still be able to author it.
        { name: 'Secret__c', label: 'Secret' },
      ],
    };
    const snapshot = emptySnapshot();
    snapshot.catalogRevision = '17';
    snapshot.catalog.objects = [{ resourceType: 'Account', label: 'Account', sharingModel: 'ReadWrite' }];
    snapshot.grants.fields = [
      { resourceType: 'Account', fieldName: 'Name', read: true, edit: false },
    ];
    mocks.readFieldCatalog.mockResolvedValue(authoringCatalog);
    mocks.readSnapshot.mockResolvedValue(snapshot);

    render(<PermissionEditorModal
      entity={{ id: customProfile.Id, name: customProfile.Name, type: 'profile' }}
      onClose={vi.fn()}
      onSave={vi.fn()}
    />);

    await screen.findByRole('button', { name: 'Field Permissions' });
    expect(mocks.getSchema).not.toHaveBeenCalled();
    fireEvent.click(screen.getByRole('button', { name: 'Field Permissions' }));

    await waitFor(() => expect(mocks.readFieldCatalog).toHaveBeenCalledTimes(1));
    expect(mocks.readFieldCatalog).toHaveBeenCalledWith(
      { type: 'profile', id: customProfile.Id },
      'Account',
      '17',
      expect.any(AbortSignal),
    );
    expect(mocks.getSchemas).not.toHaveBeenCalled();
    expect(mocks.getSchema).not.toHaveBeenCalled();
    expect(await screen.findByText('Account Name')).toBeInTheDocument();
    expect(screen.getByText('Secret')).toBeInTheDocument();
    expect(screen.getByText('Secret__c')).toBeInTheDocument();
    expect(screen.getByText('2 fields')).toBeInTheDocument();
    const nameRow = screen.getByText('Account Name').closest('tr');
    const secretRow = screen.getByText('Secret').closest('tr');
    expect(nameRow).not.toBeNull();
    expect(secretRow).not.toBeNull();
    expect(within(nameRow!).getAllByRole('checkbox').map(checkbox => (
      checkbox as HTMLInputElement
    ).checked)).toEqual([true, false]);
    expect(within(secretRow!).getAllByRole('checkbox').map(checkbox => (
      checkbox as HTMLInputElement
    ).checked)).toEqual([false, false]);

    mocks.coordinate.mockResolvedValue({ kind: 'OUTCOME_UNKNOWN', message: 'unknown' });
    fireEvent.click(within(secretRow!).getAllByRole('checkbox')[0]);
    fireEvent.click(screen.getByRole('button', { name: 'Save Permissions' }));
    await waitFor(() => expect(mocks.coordinate).toHaveBeenCalledTimes(1));
    expect(mocks.coordinate.mock.calls[0][0].minCatalogRevision).toBe('18');
  });

  it('retries a failed authoring field catalog request explicitly', async () => {
    const snapshot = emptySnapshot();
    snapshot.catalogRevision = '17';
    snapshot.catalog.objects = [{ resourceType: 'Account', label: 'Account', sharingModel: 'ReadWrite' }];
    mocks.readSnapshot.mockResolvedValue(snapshot);
    mocks.readFieldCatalog
      .mockRejectedValueOnce(new Error('catalog unavailable'))
      .mockResolvedValueOnce({
        resourceType: 'Account',
        catalogRevision: '17',
        fields: [{ name: 'Name', label: 'Account Name' }],
      });

    render(<PermissionEditorModal
      entity={{ id: customProfile.Id, name: customProfile.Name, type: 'profile' }}
      onClose={vi.fn()}
      onSave={vi.fn()}
    />);

    fireEvent.click(await screen.findByRole('button', { name: 'Field Permissions' }));
    expect(await screen.findByText('Field metadata unavailable.')).toBeInTheDocument();
    fireEvent.click(screen.getByRole('button', { name: 'Retry field metadata' }));

    await waitFor(() => expect(mocks.readFieldCatalog).toHaveBeenCalledTimes(2));
    expect(await screen.findByText('Account Name')).toBeInTheDocument();
  });

  it('keeps Save locked when the replacement Snapshot fails to load', async () => {
    const account = { name: 'Account', label: 'Account', sharingModel: 'ReadWrite', fields: [] } as SObjectDescribe;
    const initial = emptySnapshot();
    initial.catalog.objects = [{ resourceType: account.name, label: account.label, sharingModel: account.sharingModel }];
    mocks.readSnapshot
      .mockResolvedValueOnce(initial)
      .mockRejectedValueOnce(new Error('snapshot unavailable'));
    mocks.coordinate.mockResolvedValue({ kind: 'RELOAD_REQUIRED', message: 'stale' });

    render(<PermissionEditorModal
      entity={{ id: customProfile.Id, name: customProfile.Name, type: 'profile' }}
      onClose={vi.fn()}
      onSave={vi.fn()}
    />);

    fireEvent.click(await screen.findByTitle('Toggle all: Read'));
    fireEvent.click(screen.getByRole('button', { name: 'Save Permissions' }));
    fireEvent.click(await screen.findByRole('button', { name: 'Reload latest' }));

    expect(await screen.findByText('snapshot unavailable')).toBeInTheDocument();
    expect(screen.getByRole('button', { name: 'Reload latest' })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: 'Save Permissions' })).toBeDisabled();
  });

  it('modal checks an unknown command without issuing another Save', async () => {
    const account = { name: 'Account', label: 'Account', sharingModel: 'ReadWrite', fields: [] } as SObjectDescribe;
    const snapshot = emptySnapshot();
    snapshot.catalog.objects = [{ resourceType: account.name, label: account.label, sharingModel: account.sharingModel }];
    mocks.readSnapshot.mockResolvedValue(snapshot);
    mocks.coordinate.mockResolvedValue({ kind: 'OUTCOME_UNKNOWN', message: 'unknown' });
    mocks.checkStatus.mockImplementation(async command => ({
      kind: 'COMPLETED',
      result: { commandId: command.commandId, outcome: 'APPLIED', authoringToken: 'next-token', catalogRevision: '18' },
      message: 'Saved',
    }));

    render(<PermissionEditorModal
      entity={{ id: customProfile.Id, name: customProfile.Name, type: 'profile' }}
      onClose={vi.fn()}
      onSave={vi.fn()}
    />);

    fireEvent.click(await screen.findByTitle('Toggle all: Read'));
    fireEvent.click(screen.getByRole('button', { name: 'Save Permissions' }));
    await waitFor(() => expect(mocks.coordinate).toHaveBeenCalledTimes(1));
    const originalCommand = mocks.coordinate.mock.calls[0][0];

    fireEvent.click(await screen.findByRole('button', { name: 'Check Save Status' }));
    await waitFor(() => expect(mocks.checkStatus).toHaveBeenCalledTimes(1));
    expect(mocks.checkStatus.mock.calls[0][0]).toBe(originalCommand);
    expect(mocks.coordinate).toHaveBeenCalledTimes(1);
  });
});

describe('Studio Permission Authoring target domain', () => {
  it('loads only visible Profiles with bounded concurrency instead of a 48-request burst', async () => {
    mocks.getProfiles.mockResolvedValue(Array.from({ length: 48 }, (_, i) => ({
      Id: `profile-${i}`, Name: `Profile ${i}`, IsSystem: false,
    })));
    mocks.readSnapshot.mockImplementation(() => new Promise(() => {}));
    render(<StudioPermissions appObjects={[{ name: 'Account', label: 'Account' } as SObjectDescribe]} />);
    await screen.findByText('Profile 0');
    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(2));
    expect(screen.queryByText('Profile 47')).not.toBeInTheDocument();
    expect(screen.queryAllByRole('checkbox')).toHaveLength(0);
    expect(screen.getByRole('button', { name: 'Save Changes' })).toBeDisabled();
  });

  it('isolates a failed Profile without showing invented zero permissions or losing a healthy column', async () => {
    mocks.getProfiles.mockResolvedValue([customProfile, secondCustomProfile]);
    mocks.readSnapshot.mockImplementation(async target => {
      if (target.id === customProfile.Id) throw new Error('snapshot unavailable');
      return emptySnapshot();
    });
    render(<StudioPermissions appObjects={[{ name: 'Account', label: 'Account' } as SObjectDescribe]} />);
    expect(await screen.findByText('snapshot unavailable')).toBeInTheDocument();
    await waitFor(() => expect(screen.getAllByRole('checkbox')).toHaveLength(6));
    fireEvent.click(screen.getAllByRole('checkbox')[0]);
    expect(screen.getByRole('button', { name: 'Save Changes' })).not.toBeDisabled();
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());
    fireEvent.click(screen.getByRole('button', { name: `Retry ${customProfile.Name}` }));
    await waitFor(() => expect(screen.getAllByRole('checkbox')).toHaveLength(12));
    expect(screen.getAllByRole('checkbox')[6]).toBeChecked();
  });

  it('retains a Profile draft across pages without rereading its baseline', async () => {
    mocks.getProfiles.mockResolvedValue(Array.from({ length: 5 }, (_, i) => ({
      Id: `profile-${i}`, Name: `Profile ${i}`, IsSystem: false,
    })));
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());
    render(<StudioPermissions appObjects={[{ name: 'Account', label: 'Account' } as SObjectDescribe]} />);
    await waitFor(() => expect(screen.getAllByRole('checkbox')).toHaveLength(24));
    fireEvent.click(screen.getAllByRole('checkbox')[0]);
    fireEvent.click(screen.getByRole('button', { name: 'Next profiles' }));
    await waitFor(() => expect(screen.getAllByRole('checkbox')).toHaveLength(6));
    fireEvent.click(screen.getByRole('button', { name: 'Previous profiles' }));
    expect(screen.getAllByRole('checkbox')[0]).toBeChecked();
    expect(mocks.readSnapshot).toHaveBeenCalledTimes(5);
  });

  it('saves edits on both the visible and hidden Profile pages', async () => {
    mocks.getProfiles.mockResolvedValue(Array.from({ length: 5 }, (_, i) => ({
      Id: `profile-${i}`, Name: `Profile ${i}`, IsSystem: false,
    })));
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());
    mocks.coordinate.mockResolvedValue({ kind: 'NOT_ACCEPTED', message: 'Not accepted' });
    render(<StudioPermissions appObjects={[{ name: 'Account', label: 'Account' } as SObjectDescribe]} />);
    await waitFor(() => expect(screen.getAllByRole('checkbox')).toHaveLength(24));
    fireEvent.click(screen.getAllByRole('checkbox')[0]);
    fireEvent.click(screen.getByRole('button', { name: 'Next profiles' }));
    await waitFor(() => expect(screen.getAllByRole('checkbox')).toHaveLength(6));
    fireEvent.click(screen.getAllByRole('checkbox')[0]);
    fireEvent.click(screen.getByRole('button', { name: 'Save Changes' }));
    await waitFor(() => expect(mocks.coordinate).toHaveBeenCalledTimes(2));
    expect(mocks.coordinate.mock.calls.map(call => call[0].target.id)).toEqual(['profile-0', 'profile-4']);
    for (const [command] of mocks.coordinate.mock.calls) {
      expect(command.changes.objects).toHaveLength(1);
      expect(command.changes.objects[0].read).toBe(true);
    }
  });

  it('does not grant Create when enabling Modify All Records', async () => {
    mocks.getProfiles.mockResolvedValue([customProfile]);
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());
    render(<StudioPermissions appObjects={[{ name: 'Account', label: 'Account' } as SObjectDescribe]} />);
    await waitFor(() => expect(screen.getAllByRole('checkbox')).toHaveLength(6));
    fireEvent.click(screen.getAllByRole('checkbox')[5]);
    expect(screen.getAllByRole('checkbox')[0]).toBeChecked();
    expect(screen.getAllByRole('checkbox')[1]).not.toBeChecked();
    expect(screen.getAllByRole('checkbox')[5]).toBeChecked();
  });

  it('rejects an external session before reading Profiles or authoring state', async () => {
    mocks.assertBackendSession.mockImplementation(() => { throw new Error('backend session required'); });
    const account = { name: 'Account', label: 'Account', sharingModel: 'ReadWrite' } as SObjectDescribe;

    render(<StudioPermissions appObjects={[account]} />);

    expect(await screen.findByText('backend session required')).toBeInTheDocument();
    expect(mocks.getProfiles).not.toHaveBeenCalled();
    expect(mocks.readSnapshot).not.toHaveBeenCalled();
  });

  it('uses live request signals when React StrictMode replays effects', async () => {
    mocks.getProfiles.mockResolvedValue([customProfile]);
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());

    render(<React.StrictMode><StudioPermissions appObjects={[]} /></React.StrictMode>);

    // The obsolete mount is cancelled before it launches any Snapshot work.
    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(1));
    const latestSignal = mocks.readSnapshot.mock.calls.at(-1)?.[1] as AbortSignal | undefined;
    expect(latestSignal?.aborted).toBe(false);
  });

  it('derives authorable targets from Profile metadata without probing system Profiles', () => {
    expect(authorableStudioProfiles([systemProfile, customProfile, malformedProfile])).toEqual([customProfile]);
  });

  it('loads a normal Profile when the same result page also contains a system Profile', async () => {
    mocks.getProfiles.mockResolvedValue([systemProfile, customProfile]);
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());

    render(<StudioPermissions appObjects={[]} />);

    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(1));
    expect(mocks.readSnapshot.mock.calls.map(call => call[0])).toContainEqual({ type: 'profile', id: 'profile-custom' });
    expect(mocks.readSnapshot.mock.calls.map(call => call[0])).not.toContainEqual({ type: 'profile', id: 'profile-system' });
  });

  it('submits only the one edited identity from two sparse Profile aggregates', async () => {
    mocks.getProfiles.mockResolvedValue([customProfile, secondCustomProfile]);
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());
    mocks.coordinate.mockResolvedValue({ kind: 'NOT_ACCEPTED', message: 'Insufficient access' });
    const account = { name: 'Account', label: 'Account', sharingModel: 'ReadWrite' } as SObjectDescribe;

    render(<StudioPermissions appObjects={[account]} />);
    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(2));
    fireEvent.click(screen.getAllByRole('checkbox')[0]);
    fireEvent.click(screen.getByRole('button', { name: 'Save Changes' }));

    await waitFor(() => expect(mocks.coordinate).toHaveBeenCalledTimes(1));
    const submitted = mocks.coordinate.mock.calls[0][0];
    expect(submitted.target).toEqual({ type: 'profile', id: customProfile.Id });
    expect(submitted.changes).toEqual({
      objects: [{ resourceType: 'Account', read: true, create: false, edit: false, delete: false, viewAll: false, modifyAll: false }],
    });
  });

  it('treats an absent sparse grant toggled on and off as no change', async () => {
    mocks.getProfiles.mockResolvedValue([customProfile]);
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());
    const account = { name: 'Account', label: 'Account', sharingModel: 'ReadWrite' } as SObjectDescribe;

    render(<StudioPermissions appObjects={[account]} />);
    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(1));
    const read = screen.getAllByRole('checkbox')[0];
    const save = screen.getByRole('button', { name: 'Save Changes' });
    expect(save).toBeDisabled();

    fireEvent.click(read);
    await waitFor(() => expect(save).not.toBeDisabled());
    fireEvent.click(read);

    await waitFor(() => expect(save).toBeDisabled());
    expect(mocks.coordinate).not.toHaveBeenCalled();
  });

  it('keeps an unrelated Profile editable and saveable while another requires reload', async () => {
    mocks.getProfiles.mockResolvedValue([customProfile, secondCustomProfile]);
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());
    mocks.coordinate
      .mockResolvedValueOnce({ kind: 'RELOAD_REQUIRED', message: 'stale' })
      .mockResolvedValueOnce({ kind: 'NOT_ACCEPTED', message: 'not accepted' });
    const account = { name: 'Account', label: 'Account', sharingModel: 'ReadWrite' } as SObjectDescribe;

    render(<StudioPermissions appObjects={[account]} />);
    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(2));
    fireEvent.click(screen.getAllByRole('checkbox')[0]);
    fireEvent.click(screen.getByRole('button', { name: 'Save Changes' }));
    await waitFor(() => expect(mocks.coordinate).toHaveBeenCalledTimes(1));

    const checkboxes = screen.getAllByRole('checkbox');
    expect(checkboxes[0]).toBeDisabled();
    expect(checkboxes[6]).not.toBeDisabled();
    fireEvent.click(checkboxes[6]);
    fireEvent.click(screen.getByRole('button', { name: 'Save Changes' }));

    await waitFor(() => expect(mocks.coordinate).toHaveBeenCalledTimes(2));
    expect(mocks.coordinate.mock.calls[1][0].target).toEqual({ type: 'profile', id: secondCustomProfile.Id });
  });

  it('keeps an unrelated Profile editable while another command is pending', async () => {
    mocks.getProfiles.mockResolvedValue([customProfile, secondCustomProfile]);
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());
    mocks.coordinate
      .mockResolvedValueOnce({ kind: 'OUTCOME_UNKNOWN', message: 'unknown' })
      .mockResolvedValueOnce({ kind: 'NOT_ACCEPTED', message: 'not accepted' });
    mocks.checkStatus.mockResolvedValueOnce({ kind: 'OUTCOME_UNKNOWN', message: 'still unknown' });
    const account = { name: 'Account', label: 'Account', sharingModel: 'ReadWrite' } as SObjectDescribe;

    render(<StudioPermissions appObjects={[account]} />);
    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(2));
    fireEvent.click(screen.getAllByRole('checkbox')[0]);
    fireEvent.click(screen.getByRole('button', { name: 'Save Changes' }));
    await waitFor(() => expect(mocks.coordinate).toHaveBeenCalledTimes(1));

    const checkboxes = screen.getAllByRole('checkbox');
    expect(checkboxes[0]).toBeDisabled();
    expect(checkboxes[6]).not.toBeDisabled();
    fireEvent.click(checkboxes[6]);
    fireEvent.click(screen.getByRole('button', { name: 'Save Changes & Check Pending' }));

    await waitFor(() => expect(mocks.coordinate).toHaveBeenCalledTimes(2));
    await waitFor(() => expect(mocks.checkStatus).toHaveBeenCalledTimes(1));
    expect(mocks.coordinate.mock.calls[1][0].target).toEqual({ type: 'profile', id: secondCustomProfile.Id });
  });

  it('keeps stale Profile recovery reachable after saving an unrelated Profile', async () => {
    mocks.getProfiles.mockResolvedValue([customProfile, secondCustomProfile]);
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());
    mocks.coordinate
      .mockResolvedValueOnce({ kind: 'RELOAD_REQUIRED', message: 'stale' })
      .mockResolvedValueOnce({ kind: 'COMPLETED', result: {
        commandId: 'permission-authoring:test',
        outcome: 'APPLIED',
        authoringToken: 'next-token',
        catalogRevision: '18',
      }, message: 'Saved' });
    const account = { name: 'Account', label: 'Account', sharingModel: 'ReadWrite' } as SObjectDescribe;

    render(<StudioPermissions appObjects={[account]} />);
    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(2));

    fireEvent.click(screen.getAllByRole('checkbox')[0]);
    fireEvent.click(screen.getByRole('button', { name: 'Save Changes' }));
    expect(await screen.findByRole('button', { name: 'Reload latest' })).toBeInTheDocument();

    const checkboxes = screen.getAllByRole('checkbox');
    expect(checkboxes[0]).toBeDisabled();
    expect(checkboxes[6]).not.toBeDisabled();
    fireEvent.click(checkboxes[6]);
    fireEvent.click(screen.getByRole('button', { name: 'Save Changes' }));
    await waitFor(() => expect(mocks.coordinate).toHaveBeenCalledTimes(2));

    expect(screen.getAllByRole('checkbox')[0]).toBeDisabled();
    expect(screen.getByRole('button', { name: 'Reload latest' })).toBeInTheDocument();
  });

  it('keeps another Profile pending command reachable when stale Profile reload fails', async () => {
    mocks.getProfiles.mockResolvedValue([customProfile, secondCustomProfile]);
    mocks.readSnapshot
      .mockResolvedValueOnce(emptySnapshot())
      .mockResolvedValueOnce(emptySnapshot())
      .mockRejectedValueOnce(new Error('reload unavailable'));
    mocks.coordinate
      .mockResolvedValueOnce({ kind: 'RELOAD_REQUIRED', message: 'stale' })
      .mockResolvedValueOnce({ kind: 'OUTCOME_UNKNOWN', message: 'unknown' });
    mocks.checkStatus.mockResolvedValueOnce({ kind: 'OUTCOME_UNKNOWN', message: 'still unknown' });
    const account = { name: 'Account', label: 'Account', sharingModel: 'ReadWrite' } as SObjectDescribe;

    render(<StudioPermissions appObjects={[account]} />);
    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(2));
    const checkboxes = screen.getAllByRole('checkbox');
    fireEvent.click(checkboxes[0]);
    fireEvent.click(checkboxes[6]);
    fireEvent.click(screen.getByRole('button', { name: 'Save Changes' }));

    await waitFor(() => expect(mocks.coordinate).toHaveBeenCalledTimes(2));
    const unknownCommand = mocks.coordinate.mock.calls[1][0];
    fireEvent.click(await screen.findByRole('button', { name: 'Reload latest' }));
    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(3));
    expect(mocks.readSnapshot.mock.calls[2][0]).toEqual({ type: 'profile', id: customProfile.Id });
    expect(await screen.findByText(/reload unavailable/)).toBeInTheDocument();

    const save = await screen.findByRole('button', { name: 'Check Pending Saves' });
    await waitFor(() => expect(save).not.toBeDisabled());
    fireEvent.click(save);
    await waitFor(() => expect(mocks.checkStatus).toHaveBeenCalledTimes(1));
    expect(mocks.checkStatus.mock.calls[0][0]).toBe(unknownCommand);
    expect(mocks.coordinate).toHaveBeenCalledTimes(2);
  });

  it('Studio checks an unknown command without issuing another Save', async () => {
    mocks.getProfiles.mockResolvedValue([customProfile]);
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());
    mocks.coordinate.mockResolvedValueOnce({ kind: 'OUTCOME_UNKNOWN', message: 'unknown' });
    mocks.checkStatus.mockImplementationOnce(async command => ({
      kind: 'COMPLETED',
      result: { commandId: command.commandId, outcome: 'APPLIED', authoringToken: 'next-token', catalogRevision: '18' },
      message: 'Saved',
    }));
    const account = { name: 'Account', label: 'Account', sharingModel: 'ReadWrite' } as SObjectDescribe;

    render(<StudioPermissions appObjects={[account]} />);
    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(1));
    fireEvent.click(screen.getAllByRole('checkbox')[0]);
    fireEvent.click(screen.getByRole('button', { name: 'Save Changes' }));
    await waitFor(() => expect(mocks.coordinate).toHaveBeenCalledTimes(1));
    const originalCommand = mocks.coordinate.mock.calls[0][0];

    fireEvent.click(screen.getByRole('button', { name: 'Check Pending Saves' }));
    await waitFor(() => expect(mocks.checkStatus).toHaveBeenCalledTimes(1));
    expect(mocks.checkStatus.mock.calls[0][0]).toBe(originalCommand);
    expect(mocks.coordinate).toHaveBeenCalledTimes(1);
    expect(await screen.findByText('Saved')).toBeInTheDocument();
    expect(screen.queryByRole('button', { name: 'Reload latest' })).not.toBeInTheDocument();
  });

  it('starts from a fresh Snapshot after remount instead of recovering a browser command', async () => {
    mocks.getProfiles.mockResolvedValue([customProfile]);
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());
    mocks.coordinate.mockResolvedValue({ kind: 'OUTCOME_UNKNOWN', message: 'unknown' });
    const account = { name: 'Account', label: 'Account', sharingModel: 'ReadWrite' } as SObjectDescribe;

    const first = render(<StudioPermissions appObjects={[account]} />);
    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(1));
    fireEvent.click(screen.getAllByRole('checkbox')[0]);
    fireEvent.click(screen.getByRole('button', { name: 'Save Changes' }));
    await waitFor(() => expect(mocks.coordinate).toHaveBeenCalledTimes(1));
    first.unmount();

    render(<StudioPermissions appObjects={[account]} />);
    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(2));
    expect(screen.getByRole('button', { name: 'Save Changes' })).toBeDisabled();
    expect(mocks.coordinate).toHaveBeenCalledTimes(1);
  });

  it('discards a command proven not accepted and unlocks the edited matrix', async () => {
    mocks.getProfiles.mockResolvedValue([customProfile]);
    mocks.readSnapshot.mockResolvedValue(emptySnapshot());
    mocks.coordinate.mockResolvedValue({ kind: 'NOT_ACCEPTED', message: 'Insufficient access' });
    const account = { name: 'Account', label: 'Account', sharingModel: 'ReadWrite' } as SObjectDescribe;

    const { container } = render(<StudioPermissions appObjects={[account]} />);
    await waitFor(() => expect(mocks.readSnapshot).toHaveBeenCalledTimes(1));
    fireEvent.click(screen.getAllByRole('checkbox')[0]);
    fireEvent.click(screen.getByRole('button', { name: 'Save Changes' }));

    await waitFor(() => expect(mocks.coordinate).toHaveBeenCalledTimes(1));
    await waitFor(() => expect(container.querySelector('.pointer-events-none')).toBeNull());
    expect(screen.getAllByRole('checkbox')[0]).not.toBeDisabled();
  });
});

function emptySnapshot() {
  return {
    canonicalPermissionSetId: 'permission-set-custom',
    authoringToken: 'opaque-token',
    catalogRevision: '17',
    catalog: { objects: [], system: [], recordTypes: [], custom: [] },
    grants: { system: [], objects: [], fields: [], recordTypes: [], custom: [] },
  };
}
