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

import {
  buildDirectorAcknowledgmentDocuments,
  buildDirectorFramePreviews,
  buildDirectorOverviewCards,
  buildDirectorQuizResults,
  buildDirectorRiskAreas,
  calculateQuizCompletionRate,
} from '@/business/director-dashboard/selectors';
import type { FrameEntryViewModel } from '@/business/frame/types';
import type { StaffAttendanceRecordViewModel } from '@/business/staff-attendance/types';
import type {
  SafetyQuizCompletionSummary,
  SafetyQuizComplianceRow,
} from '@/business/safety-quiz/types';
import type { PersonalityCompletionDto } from '@/shared/types/personality';
import type { ZoneCheckinCompletionDto } from '@/shared/types/zoneCheckins';
import type { PolicyAcknowledgmentReportDto } from '@/shared/types/policyDocuments';

function createAttendanceRecord(
  overrides: Partial<StaffAttendanceRecordViewModel> = {},
): StaffAttendanceRecordViewModel {
  return {
    id: 'attendance-1',
    date: '2026-06-01',
    status: 'present',
    note: null,
    userName: 'Ava Lee',
    userRole: 'teacher',
    ...overrides,
  };
}

function createQuizSummary(overrides: Partial<SafetyQuizCompletionSummary> = {}): SafetyQuizCompletionSummary {
  return {
    completedCount: 1,
    pendingCount: 1,
    totalStaff: 2,
    completionRate: 50,
    ...overrides,
  };
}

function createFrameEntry(overrides: Partial<FrameEntryViewModel> = {}): FrameEntryViewModel {
  return {
    id: 'frame-1',
    weekStart: '2026-05-31',
    weekLabel: '',
    weekOf: 'May 31, 2026',
    postedDate: 'June 1, 2026',
    formal: 'Formal learning focus for the week',
    recognition: 'Recognition focus for the week',
    application: 'Application focus for the week',
    management: 'Management focus for the week',
    emotional: 'Emotional learning focus for the week',
    author: 'Director',
    ...overrides,
  };
}

function createPersonalityCompletion(
  overrides: Partial<PersonalityCompletionDto> = {},
): PersonalityCompletionDto {
  return {
    summary: {
      totalStaff: 2,
      completedCount: 1,
      pendingCount: 1,
      selfAssessmentCompletedCount: 1,
      personalityCompletedCount: 1,
      completionRate: 50,
    },
    rows: [
      {
        userId: 'user-1',
        name: 'Ava Lee',
        email: 'ava@example.test',
        avatar: 'users/avatar/ava.png',
        tenantName: 'Tigers Campus',
        tenantLogo: 'campuses/logo/tigers.png',
        role: 'Teacher',
        status: 'complete',
        completedKinds: ['ei_self_assessment', 'personality_type'],
        selfAssessment: {
          id: 'ei-1',
          quiz_kind: 'ei_self_assessment',
          quiz_id: 'ei-weekly',
          quiz_title: 'EI Self-Assessment',
          week_of: '2026-06-14',
          personality_type: null,
          quiz_answers: {},
          score: 14,
          total_questions: 8,
          result_label: 'Developing Awareness',
          result_payload: null,
          user_name: 'Ava Lee',
          user_role: 'Teacher',
          completed_at: '2026-06-18T10:00:00.000Z',
          organizationId: 'org-1',
          campusId: 'campus-1',
          userId: 'user-1',
          createdById: null,
          updatedById: null,
          createdAt: '2026-06-18T10:00:00.000Z',
          updatedAt: '2026-06-18T10:00:00.000Z',
        },
        personality: {
          id: 'personality-1',
          quiz_kind: 'personality_type',
          quiz_id: 'personality-type',
          quiz_title: 'Personality Type Quiz',
          week_of: null,
          personality_type: 'ENFP',
          quiz_answers: {},
          score: null,
          total_questions: 0,
          result_label: 'ENFP',
          result_payload: null,
          user_name: 'Ava Lee',
          user_role: 'Teacher',
          completed_at: '2026-06-18T10:00:00.000Z',
          organizationId: 'org-1',
          campusId: 'campus-1',
          userId: 'user-1',
          createdById: null,
          updatedById: null,
          createdAt: '2026-06-18T10:00:00.000Z',
          updatedAt: '2026-06-18T10:00:00.000Z',
        },
      },
    ],
    ...overrides,
  };
}

function createZoneCheckinCompletion(
  overrides: Partial<ZoneCheckinCompletionDto> = {},
): ZoneCheckinCompletionDto {
  return {
    summary: {
      totalStaff: 2,
      completedCount: 1,
      pendingCount: 1,
      greenCount: 0,
      nonGreenCount: 1,
      completionRate: 50,
    },
    rows: [
      {
        userId: 'user-1',
        name: 'Ava Lee',
        email: 'ava@example.test',
        avatar: 'users/avatar/ava.png',
        tenantName: 'Tigers Campus',
        tenantLogo: 'campuses/logo/tigers.png',
        role: 'Teacher',
        date: '2026-06-18',
        status: 'complete',
        zone: 'yellow',
        riskLevel: 'medium',
        result: 'Yellow Zone',
      },
    ],
    ...overrides,
  };
}

function createAcknowledgmentReport(
  overrides: Partial<PolicyAcknowledgmentReportDto> = {},
): PolicyAcknowledgmentReportDto {
  return {
    summary: {
      scope: 'campus',
      totalDocuments: 1,
      totalStaff: 2,
      totalRequired: 2,
      acknowledgedCount: 1,
      missingCount: 1,
      completionRate: 50,
    },
    documents: [
      {
        id: 'policy-1',
        title: 'Fire Drill Procedures',
        category: 'safety_protocol',
        version: 3,
        totalStaff: 2,
        acknowledgedCount: 1,
        missingCount: 1,
        completionRate: 50,
      },
    ],
    staff: [
      {
        userId: 'user-1',
        name: 'Ava Lee',
        email: 'ava@example.test',
        avatar: 'users/avatar/ava.png',
        tenantName: 'Tigers Campus',
        tenantLogo: 'campuses/logo/tigers.png',
        role: 'teacher',
        campusId: 'campus-1',
        schoolId: 'school-1',
        classId: 'class-1',
        acknowledgedCount: 1,
        missingCount: 0,
        completionRate: 100,
        documents: [
          {
            policyDocumentId: 'policy-1',
            title: 'Fire Drill Procedures',
            category: 'safety_protocol',
            version: 3,
            acknowledgedAt: '2026-06-18T10:00:00.000Z',
            missing: false,
          },
        ],
      },
      {
        userId: 'user-2',
        name: 'Ben Cruz',
        email: 'ben@example.test',
        avatar: 'users/avatar/ben.png',
        tenantName: 'Tigers Campus',
        tenantLogo: 'campuses/logo/tigers.png',
        role: 'support_staff',
        campusId: 'campus-1',
        schoolId: 'school-1',
        classId: 'class-1',
        acknowledgedCount: 0,
        missingCount: 1,
        completionRate: 0,
        documents: [
          {
            policyDocumentId: 'policy-1',
            title: 'Fire Drill Procedures',
            category: 'safety_protocol',
            version: 3,
            acknowledgedAt: null,
            missing: true,
          },
        ],
      },
    ],
    ...overrides,
  };
}

describe('director dashboard selectors', () => {
  it('calculates quiz completion rate with empty staff protection', () => {
    expect(calculateQuizCompletionRate(createQuizSummary({ completionRate: 0 }))).toBe(0);
    expect(calculateQuizCompletionRate(createQuizSummary({ completionRate: 25 }))).toBe(25);
  });

  it('builds overview cards from backend-backed records', () => {
    const cards = buildDirectorOverviewCards(
      [
        createAttendanceRecord({ id: 'present', status: 'present' }),
        createAttendanceRecord({ id: 'absent', status: 'absent' }),
      ],
      createQuizSummary(),
      [createFrameEntry()],
      {
        scope: 'campus',
        totalDocuments: 2,
        totalStaff: 2,
        totalRequired: 4,
        acknowledgedCount: 3,
        missingCount: 1,
        completionRate: 75,
      },
    );

    expect(cards.map((card) => card.value)).toEqual(['50%', '1/2', '1', '2', '75%']);
    expect(cards.map((card) => card.module)).toEqual([
      'attendance',
      'qbs',
      'frame',
      'user-admin',
      'director',
    ]);
    expect(cards[1]?.action).toBe('openQuizResults');
    expect(cards[cards.length - 1]?.action).toBe('openAcknowledgments');
  });

  it('flags dashboard risk levels from quiz completion and staff attendance exceptions', () => {
    const risks = buildDirectorRiskAreas(
      [
        createAttendanceRecord({ id: '1', status: 'absent' }),
        createAttendanceRecord({ id: '2', status: 'absent' }),
        createAttendanceRecord({ id: '3', status: 'absent' }),
        createAttendanceRecord({ id: '4', status: 'late' }),
      ],
      createQuizSummary({ completedCount: 1, pendingCount: 5, totalStaff: 6, completionRate: 17 }),
      null,
      createZoneCheckinCompletion(),
      buildDirectorAcknowledgmentDocuments(createAcknowledgmentReport()),
    );

    expect(risks).toEqual([
      {
        issue: "5 staff haven't completed Behavior Management quiz",
        severity: 'high',
        module: 'qbs',
        action: 'openQuizResults',
      },
      {
        issue: "1 staff haven't completed daily zone check-in",
        severity: 'medium',
        module: 'zones',
        action: 'openQuizResults',
      },
      {
        issue: 'Non-green regulation zones: Ava Lee (Yellow Zone)',
        severity: 'medium',
        module: 'zones',
      },
      {
        issue: "1 staff haven't acknowledged 1 document",
        severity: 'medium',
        module: 'director',
        action: 'openAcknowledgments',
      },
      {
        issue: '4 staff attendance exceptions this period (1 late, 3 absent)',
        severity: 'high',
        module: 'attendance',
      },
    ]);
  });

  it('hides resolved risk cards with zero counts', () => {
    const risks = buildDirectorRiskAreas(
      [],
      createQuizSummary({ completedCount: 2, pendingCount: 0, totalStaff: 2, completionRate: 100 }),
      createPersonalityCompletion({
        summary: {
          totalStaff: 2,
          completedCount: 2,
          pendingCount: 0,
          selfAssessmentCompletedCount: 2,
          personalityCompletedCount: 2,
          completionRate: 100,
        },
      }),
      createZoneCheckinCompletion({
        summary: {
          totalStaff: 2,
          completedCount: 2,
          pendingCount: 0,
          greenCount: 2,
          nonGreenCount: 0,
          completionRate: 100,
        },
        rows: [
          {
            userId: 'user-1',
            name: 'Ava Lee',
            email: 'ava@example.test',
            avatar: 'users/avatar/ava.png',
            tenantName: 'Tigers Campus',
            tenantLogo: 'campuses/logo/tigers.png',
            role: 'Teacher',
            date: '2026-06-18',
            status: 'complete',
            zone: 'green',
            riskLevel: 'none',
            result: 'Green Zone',
          },
        ],
      }),
      buildDirectorAcknowledgmentDocuments(createAcknowledgmentReport({
        summary: {
          scope: 'campus',
          totalDocuments: 1,
          totalStaff: 2,
          totalRequired: 2,
          acknowledgedCount: 2,
          missingCount: 0,
          completionRate: 100,
        },
        documents: [
          {
            id: 'policy-1',
            title: 'Fire Drill Procedures',
            category: 'safety_protocol',
            version: 3,
            totalStaff: 2,
            acknowledgedCount: 2,
            missingCount: 0,
            completionRate: 100,
          },
        ],
        staff: [],
      })),
    );

    expect(risks).toEqual([]);
  });

  it('aggregates document acknowledgment risks into one card', () => {
    const risks = buildDirectorRiskAreas(
      [],
      createQuizSummary({ completedCount: 4, pendingCount: 0, totalStaff: 4, completionRate: 100 }),
      null,
      null,
      Array.from({ length: 10 }, (_, index) => ({
        id: `policy-${index}`,
        title: `Policy ${index}`,
        category: 'handbook_policy',
        categoryLabel: 'Handbook & Policies',
        version: 1,
        totalStaff: 4,
        acknowledgedCount: 0,
        missingCount: 4,
        completionRate: 0,
        missingStaff: [
          {
            userId: 'user-1',
            name: 'Ava Lee',
            avatar: null,
            tenantName: 'Tigers Campus',
            tenantLogo: null,
            role: 'teacher',
            email: 'ava@example.test',
          },
          {
            userId: 'user-2',
            name: 'Ben Cruz',
            avatar: null,
            tenantName: 'Tigers Campus',
            tenantLogo: null,
            role: 'support staff',
            email: 'ben@example.test',
          },
          {
            userId: 'user-3',
            name: 'Cara Fox',
            avatar: null,
            tenantName: 'Tigers Campus',
            tenantLogo: null,
            role: 'office manager',
            email: 'cara@example.test',
          },
          {
            userId: 'user-4',
            name: 'Drew Kim',
            avatar: null,
            tenantName: 'Tigers Campus',
            tenantLogo: null,
            role: 'director',
            email: 'drew@example.test',
          },
        ],
      })),
    );

    expect(risks).toEqual([
      {
        issue: "4 staff haven't acknowledged 10 documents",
        severity: 'high',
        module: 'director',
        action: 'openAcknowledgments',
      },
    ]);
  });

  it('builds current-version acknowledgment rows with missing staff', () => {
    const rows = buildDirectorAcknowledgmentDocuments(createAcknowledgmentReport());

    expect(rows).toEqual([
      {
        id: 'policy-1',
        title: 'Fire Drill Procedures',
        category: 'safety_protocol',
        categoryLabel: 'Safety Protocols',
        version: 3,
        totalStaff: 2,
        acknowledgedCount: 1,
        missingCount: 1,
        completionRate: 50,
        missingStaff: [
          {
            userId: 'user-2',
            name: 'Ben Cruz',
            avatar: 'users/avatar/ben.png',
            tenantName: 'Tigers Campus',
            tenantLogo: 'campuses/logo/tigers.png',
            role: 'support staff',
            email: 'ben@example.test',
          },
        ],
      },
    ]);
  });

  it('groups safety, EI assessment, personality, and zone check-in results by staff member', () => {
    const rows = buildDirectorQuizResults(
      [
        {
          userId: 'user-1',
          name: 'Ava Lee',
          avatar: 'users/avatar/ava.png',
          tenantName: 'Tigers Campus',
          tenantLogo: 'campuses/logo/tigers.png',
          role: 'Teacher',
          status: 'complete',
          score: '3/5',
          date: 'Jun 18',
        } satisfies SafetyQuizComplianceRow,
      ],
      createPersonalityCompletion(),
      createZoneCheckinCompletion(),
      'Tigers Campus',
    );

    expect(rows).toHaveLength(1);
    expect(rows[0]).toMatchObject({
      id: 'user-1',
      staffName: 'Ava Lee',
      tenant: 'Tigers Campus',
      tenantLogo: 'campuses/logo/tigers.png',
      role: 'Teacher',
      completedCount: 4,
      totalCount: 4,
    });
    expect(rows[0].details.map((row) => row.quiz)).toEqual([
      'Behavior Management',
      'EI Self-Assessment',
      'Personality Type Quiz',
      'Daily Zone Check-In',
    ]);
    expect(rows[0].details.map((row) => row.result)).toEqual([
      '3/5',
      'Developing Awareness (14/32)',
      'ENFP',
      'Yellow Zone',
    ]);
  });

  it('keeps one quiz row per staff member when completion sources contain different users', () => {
    const rows = buildDirectorQuizResults(
      [
        {
          userId: 'user-1',
          name: 'Ava Lee',
          avatar: 'users/avatar/ava.png',
          tenantName: 'Tigers Campus',
          tenantLogo: 'campuses/logo/tigers.png',
          role: 'Teacher',
          status: 'complete',
          score: '3/5',
          date: 'Jun 18',
        } satisfies SafetyQuizComplianceRow,
      ],
      createPersonalityCompletion({
        rows: [
          {
            userId: 'user-2',
            name: 'Ben Cruz',
            email: 'ben@example.test',
            avatar: null,
            tenantName: 'Tigers Campus',
            tenantLogo: null,
            role: 'Support Staff',
            status: 'pending',
            completedKinds: [],
            selfAssessment: null,
            personality: null,
          },
        ],
      }),
      createZoneCheckinCompletion({
        rows: [
          {
            userId: 'user-1',
            name: 'Ava Lee',
            email: 'ava@example.test',
            avatar: 'users/avatar/ava.png',
            tenantName: 'Tigers Campus',
            tenantLogo: 'campuses/logo/tigers.png',
            role: 'Teacher',
            date: '2026-06-18',
            status: 'pending',
            zone: null,
            riskLevel: 'pending',
            result: 'Pending',
          },
        ],
      }),
      'Demo Academy',
    );

    expect(rows.map((row) => row.staffName)).toEqual(['Ava Lee', 'Ben Cruz']);
    expect(rows.find((row) => row.id === 'user-1')?.details.map((detail) => detail.quiz)).toEqual([
      'Behavior Management',
      'Daily Zone Check-In',
    ]);
    expect(rows.find((row) => row.id === 'user-2')?.details.map((detail) => detail.quiz)).toEqual([
      'EI Self-Assessment',
      'Personality Type Quiz',
    ]);
  });

  it('limits and truncates FRAME previews', () => {
    const longText = 'A'.repeat(70);
    const previews = buildDirectorFramePreviews([
      createFrameEntry({ id: '1', formal: longText }),
      createFrameEntry({ id: '2' }),
      createFrameEntry({ id: '3' }),
      createFrameEntry({ id: '4' }),
    ]);

    expect(previews).toHaveLength(3);
    expect(previews[0].sections[0]).toEqual({
      letter: 'F',
      text: `${'A'.repeat(60)}...`,
    });
  });
});
