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('surfaces an unread QBS quiz reminder when the weekly quiz is incomplete', () => {
    expect(buildTopBarNotifications({
      needsZoneCheckIn: false,
      needsSafetyQuiz: false,
    })).toEqual([]);

    const withReminder = buildTopBarNotifications({
      needsZoneCheckIn: false,
      needsSafetyQuiz: true,
    });

    expect(withReminder).toEqual([{
      id: 'safety-quiz-weekly',
      text: "You haven't completed this week's QBS safety quiz",
      time: 'This week',
      unread: true,
      href: APP_ROUTE_PATHS.qbs,
    }]);
  });

  it('surfaces an unread sign-of-week reminder when the weekly sign is not learned', () => {
    const withReminder = buildTopBarNotifications({
      needsZoneCheckIn: false,
      needsSignOfWeek: true,
    });

    expect(withReminder).toEqual([{
      id: 'sign-of-week',
      text: "You haven't learned this week's sign",
      time: 'This week',
      unread: true,
      href: APP_ROUTE_PATHS.signs,
    }]);
  });

  it('surfaces manager reminders for missing weekly and daily content', () => {
    const reminders = buildTopBarNotifications({
      needsZoneCheckIn: false,
      needsWeeklySignSelection: true,
      needsWeeklyFrameContent: true,
      needsDailyAttendanceContent: true,
    });

    expect(reminders).toEqual([
      {
        id: 'weekly-sign-selection',
        text: "Select this week's Sign of the Week",
        time: 'This week',
        unread: true,
        href: APP_ROUTE_PATHS.signs,
      },
      {
        id: 'weekly-frame-content',
        text: "Publish this week's F.R.A.M.E. entry",
        time: 'This week',
        unread: true,
        href: APP_ROUTE_PATHS.frame,
      },
      {
        id: 'daily-attendance-content',
        text: "Submit today's attendance",
        time: 'Today',
        unread: true,
        href: APP_ROUTE_PATHS.attendance,
      },
    ]);
  });

  it('surfaces EI self-assessment and personality quiz completion reminders', () => {
    const reminders = buildTopBarNotifications({
      needsZoneCheckIn: false,
      needsEiSelfAssessment: true,
      needsPersonalityQuiz: true,
    });

    expect(reminders).toEqual([
      {
        id: 'ei-self-assessment',
        text: "You haven't completed your EI self-assessment",
        time: 'This week',
        unread: true,
        href: APP_ROUTE_PATHS.ei,
      },
      {
        id: 'ei-personality-quiz',
        text: "You haven't completed your personality type quiz",
        time: 'Once',
        unread: true,
        href: APP_ROUTE_PATHS.ei,
      },
    ]);
  });

  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',
        tag: '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('surfaces ESA funding updates with the updated section name', () => {
    const unread = buildTopBarNotifications({
      needsZoneCheckIn: false,
      handbookPolicies: [{
        id: 'esa-policy-1',
        title: 'ESA Funding Information',
        category: 'Operations',
        tag: 'ESA Funding',
        content: 'Staff must review the current ESA Funding Information page.\n\nUpdated section: Helpful Resources',
        version: 3,
        lastUpdated: '2026-06-22',
        updatedBy: 'Director',
      }],
      policyAcknowledgments: [
        createPolicyAcknowledgment({ policyDocumentId: 'esa-policy-1', version: 2 }),
      ],
    });

    expect(unread).toEqual([{
      id: 'handbook-policy-esa-policy-1-v3',
      text: 'Updated ESA funding section: Helpful Resources',
      time: 'Version 3',
      unread: true,
      href: APP_ROUTE_PATHS.esa,
    }]);
  });

  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);
  });
});
