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

import { InternalAlertsModule } from '@/components/internal-alerts/InternalAlertsModule';
import type { ScopeContextValue } from '@/contexts/scope-context';
import type { TenantChild } from '@/shared/types/scope';
import type { CurrentUser } from '@/shared/types/auth';

const useTenantChildrenMock = vi.hoisted(() => vi.fn());
const scopeContextMock = vi.hoisted(() => vi.fn());
const permissionHasMock = vi.hoisted(() => vi.fn());

vi.mock('@/business/scope/queries', () => ({
  useTenantChildren: useTenantChildrenMock,
}));

vi.mock('@/contexts/scope-context', () => ({
  useScopeContext: scopeContextMock,
}));

vi.mock('@/hooks/usePermissions', () => ({
  usePermissions: () => ({
    has: permissionHasMock,
  }),
}));

vi.mock('@/business/communications/hooks', () => ({
  useCancelCommunicationEvent: () => ({
    error: null,
    isPending: false,
    mutateAsync: vi.fn(),
  }),
  useCommunicationEvents: () => ({
    data: [],
    error: null,
    isLoading: false,
  }),
  useCreateCommunicationEvent: () => ({
    error: null,
    isPending: false,
    mutateAsync: vi.fn(),
  }),
  useDeleteCommunicationEvent: () => ({
    error: null,
    isPending: false,
    mutateAsync: vi.fn(),
  }),
  useUpdateCommunicationEvent: () => ({
    error: null,
    isPending: false,
    mutateAsync: vi.fn(),
  }),
}));

const organization: TenantChild = {
  id: 'org-1',
  level: 'organization',
  name: 'Demo Academy',
  logo: null,
};
const school: TenantChild = {
  id: 'school-1',
  level: 'school',
  name: 'Demo Academy North',
  logo: null,
};
const campus: TenantChild = {
  id: 'campus-1',
  level: 'campus',
  name: 'Tigers Campus',
  logo: null,
};
const user = {
  id: 'user-1',
  email: 'user@example.com',
  firstName: 'Test',
  lastName: 'User',
  permissions: ['READ_INTERNAL_COMM', 'MANAGE_INTERNAL_COMM'],
  app_role: { name: 'director', globalAccess: false },
} satisfies CurrentUser;

function scopeContext(overrides: Partial<ScopeContextValue>): ScopeContextValue {
  return {
    tier: 'campus',
    ownTenant: null,
    selectedTenant: null,
    effectiveTenant: { id: 'campus-1', level: 'campus', name: 'Tigers Campus', logo: null },
    canDrill: false,
    drillInto: vi.fn(),
    setScopeTenant: vi.fn(),
    resetScope: vi.fn(),
    ...overrides,
  };
}

function renderModule(context: ScopeContextValue): void {
  scopeContextMock.mockReturnValue(context);
  render(<InternalAlertsModule user={user} />);
}

function enabledScopeChildrenCalls() {
  return useTenantChildrenMock.mock.calls.filter(([, options]) => options?.enabled === true);
}

beforeEach(() => {
  scopeContextMock.mockReset();
  useTenantChildrenMock.mockReset();
  permissionHasMock.mockImplementation((permission: string) => permission === 'MANAGE_INTERNAL_COMM');
  useTenantChildrenMock.mockImplementation((parent: { level?: string } | null) => {
    if (parent?.level === 'organization') return { data: { rows: [school] } };
    if (parent?.level === 'school') return { data: { rows: [campus] } };
    return { data: { rows: [organization] } };
  });
});

describe('InternalAlertsModule scope child lookups', () => {
  it('does not request school children for campus-scope managers', () => {
    renderModule(scopeContext({}));

    expect(enabledScopeChildrenCalls()).toEqual([]);
    expect(screen.queryByLabelText('Target campus')).not.toBeInTheDocument();
  });

  it('loads organizations only for platform-scope managers by default', () => {
    renderModule(scopeContext({
      tier: 'global',
      effectiveTenant: null,
    }));

    expect(enabledScopeChildrenCalls()).toEqual([[null, { enabled: true }]]);
    expect(screen.getByLabelText('Alert audience')).toHaveValue('system');
  });

  it('loads school and campus children when organization-scope managers target campus staff', () => {
    renderModule(scopeContext({
      tier: 'organization',
      effectiveTenant: { id: 'org-1', level: 'organization', name: 'Demo Academy', logo: null },
    }));

    fireEvent.change(screen.getByLabelText('Alert audience'), {
      target: { value: 'campus' },
    });

    expect(enabledScopeChildrenCalls()).toEqual([
      [{ level: 'organization', id: 'org-1' }, { enabled: true }],
      [{ level: 'school', id: 'school-1' }, { enabled: true }],
    ]);
    expect(screen.getByLabelText('Target school')).toHaveValue('school-1');
    expect(screen.getByLabelText('Target campus')).toHaveValue('campus-1');
  });

  it('loads current school children only when school-scope managers target campus staff', () => {
    renderModule(scopeContext({
      tier: 'school',
      effectiveTenant: { id: 'school-1', level: 'school', name: 'Demo Academy North', logo: null },
    }));

    fireEvent.change(screen.getByLabelText('Alert audience'), {
      target: { value: 'campus' },
    });

    expect(enabledScopeChildrenCalls()).toEqual([[{ level: 'school', id: 'school-1' }, { enabled: true }]]);
    expect(screen.getByLabelText('Target campus')).toHaveValue('campus-1');
  });

  it('hides the creation form when MANAGE_INTERNAL_COMM is absent', () => {
    permissionHasMock.mockReturnValue(false);

    renderModule(scopeContext({}));

    expect(screen.queryByText('Schedule New Alert')).not.toBeInTheDocument();
    expect(enabledScopeChildrenCalls()).toEqual([]);
  });
});
