import { describe, expect, it } from 'vitest';

import {
  buildTopBarNotifications,
  countUnreadTopBarNotifications,
  getTopBarCampusLabel,
  getTopBarInitials,
  getTopBarRoleLabel,
} from '@/business/top-bar/selectors';
import { APP_ROUTE_PATHS } from '@/shared/constants/routes';
import type { CommunicationEventDto } from '@/shared/types/communications';
import type { PolicyAcknowledgmentDto } from '@/shared/types/policyDocuments';

function createCommunicationEvent(overrides: Partial<CommunicationEventDto> = {}): CommunicationEventDto {
  return {
    id: 'event-1',
    title: 'Campus meeting',
    date: '2026-06-15',
    type: 'meeting',
    targetLevel: 'campus',
    roles: ['director'],
    organizationId: 'org-1',
    campusId: 'campus-1',
    schoolId: null,
    classId: null,
    canceledEventId: null,
    createdById: 'user-1',
    updatedById: null,
    createdAt: '2026-06-15T00:00:00Z',
    updatedAt: '2026-06-15T00:00:00Z',
    ...overrides,
  };
}

function createPolicyAcknowledgment(
  overrides: Partial<PolicyAcknowledgmentDto> = {},
): PolicyAcknowledgmentDto {
  return {
    id: 'ack-1',
    policyDocumentId: 'handbook-1',
    version: 1,
    userId: 'user-1',
    acknowledgedAt: '2026-06-15T00:00:00Z',
    organizationId: 'org-1',
    campusId: null,
    createdAt: '2026-06-15T00:00:00Z',
    updatedAt: '2026-06-15T00:00:00Z',
    ...overrides,
  };
}

describe('top bar selectors', () => {
  it('surfaces an unread zone check-in nudge (linking to the zones page) only when needed', () => {
    expect(buildTopBarNotifications({ needsZoneCheckIn: false })).toEqual([]);

    const withNudge = buildTopBarNotifications({ needsZoneCheckIn: true });
    expect(withNudge).toHaveLength(1);
    expect(withNudge[0]).toMatchObject({ unread: true, href: APP_ROUTE_PATHS.zones });
    expect(countUnreadTopBarNotifications(withNudge)).toBe(1);
  });

  it('builds initials from display names', () => {
    expect(getTopBarInitials('Guest')).toBe('G');
    expect(getTopBarInitials('Ada Lovelace')).toBe('AL');
    expect(getTopBarInitials('  Grace  Hopper  ')).toBe('GH');
  });

  it('surfaces unacknowledged internal alerts in the notifications menu', () => {
    const unread = buildTopBarNotifications({
      needsZoneCheckIn: false,
      communicationEvents: [createCommunicationEvent()],
      acknowledgedCommunicationEventIds: new Set(),
    });

    expect(unread).toHaveLength(1);
    expect(unread[0]).toMatchObject({
      text: 'Internal alert: Campus meeting',
      href: APP_ROUTE_PATHS.internalComm,
      unread: true,
    });

    expect(buildTopBarNotifications({
      needsZoneCheckIn: false,
      communicationEvents: [createCommunicationEvent()],
      acknowledgedCommunicationEventIds: new Set(['event-1']),
    })).toEqual([]);
  });

  it('surfaces unread handbook policies and safety protocols by document version', () => {
    const unread = buildTopBarNotifications({
      needsZoneCheckIn: false,
      handbookPolicies: [{
        id: 'handbook-1',
        title: 'Parent Communication',
        category: 'Communication',
        content: 'Document families contact.',
        version: 2,
        lastUpdated: '2026-06-15',
        updatedBy: 'Director',
      }],
      safetyProtocols: [{
        id: 'safety-1',
        title: 'Fire Drill',
        tag: 'fire',
        steps: ['Line up'],
        autismConsiderations: [],
        version: 1,
        lastUpdated: '2026-06-15',
        author: 'Director',
      }],
      policyAcknowledgments: [
        createPolicyAcknowledgment({ policyDocumentId: 'handbook-1', version: 1 }),
        createPolicyAcknowledgment({ id: 'ack-2', policyDocumentId: 'safety-1', version: 1 }),
      ],
    });

    expect(unread).toEqual([{
      id: 'handbook-policy-handbook-1-v2',
      text: 'Unread handbook policy: Parent Communication',
      time: 'Version 2',
      unread: true,
      href: APP_ROUTE_PATHS.handbook,
    }]);
  });

  it('falls back to default campus label', () => {
    expect(getTopBarCampusLabel()).toBe('Current Campus');
  });

  it('uses shared auth role labels', () => {
    expect(getTopBarRoleLabel('support_staff')).toBe('Support Staff');
    expect(getTopBarRoleLabel('office_manager')).toBe('Office Manager');
  });

  it('counts unread notifications', () => {
    expect(countUnreadTopBarNotifications([
      { id: '1', text: 'One', time: 'Now', unread: true },
      { id: '2', text: 'Two', time: 'Earlier', unread: false },
    ])).toBe(1);
  });
});
