import { describe, expect, it } from 'vitest';
import {
  buildAttendanceEntryInput,
  buildCampusAttendanceScopeModel,
  buildCombinedAttendanceStats,
  buildOverallAttendanceStats,
  getWeekEnd,
  getWeekStart,
} from '@/business/campus-attendance/selectors';
import type {
  CampusAttendanceEntryDraft,
  CampusAttendanceSummaryViewModel,
} from '@/business/campus-attendance/types';

const summaries: readonly CampusAttendanceSummaryViewModel[] = [
  {
    id: 'summary-1',
    campus_id: 'tigers',
    date: '2026-06-08',
    total_enrolled: 100,
    total_present: 90,
    total_absent: 10,
    total_tardy: 3,
    attendance_percentage: 90,
    recorded_by: 'director-1',
    notes: null,
  },
  {
    id: 'summary-2',
    campus_id: 'gators',
    date: '2026-06-08',
    total_enrolled: 50,
    total_present: 40,
    total_absent: 10,
    total_tardy: 1,
    attendance_percentage: 80,
    recorded_by: 'director-1',
    notes: null,
  },
  {
    id: 'summary-3',
    campus_id: 'tigers',
    date: '2026-06-09',
    total_enrolled: 100,
    total_present: 95,
    total_absent: 5,
    total_tardy: 2,
    attendance_percentage: 95,
    recorded_by: 'director-1',
    notes: null,
  },
];

describe('campus attendance selectors', () => {
  it('calculates Monday and Friday boundaries for a midweek date', () => {
    const date = new Date('2026-06-10T12:00:00Z');

    expect(getWeekStart(date)).toBe('2026-06-08');
    expect(getWeekEnd(date)).toBe('2026-06-12');
  });

  it('builds validated attendance input and normalizes optional notes', () => {
    const draft: CampusAttendanceEntryDraft = {
      date: '2026-06-08',
      campusId: 'tigers',
      enrolled: '25',
      present: '21',
      absent: '4',
      tardy: '',
      notes: '  ',
    };

    expect(buildAttendanceEntryInput(draft, 'tigers')).toEqual({
      campusId: 'tigers',
      date: '2026-06-08',
      totalEnrolled: 25,
      totalPresent: 21,
      totalAbsent: 4,
      totalTardy: 0,
      notes: null,
    });
  });

  it('rejects attendance input without a positive enrollment count', () => {
    const draft: CampusAttendanceEntryDraft = {
      date: '2026-06-08',
      campusId: 'tigers',
      enrolled: '0',
      present: '0',
      absent: '0',
      tardy: '0',
      notes: 'Closed',
    };

    expect(buildAttendanceEntryInput(draft, 'tigers')).toBeNull();
  });

  it('aggregates daily and weekly attendance percentages across campuses', () => {
    expect(
      buildOverallAttendanceStats(summaries, '2026-06-08', '2026-06-08', '2026-06-12'),
    ).toMatchObject({
      todayEnrolled: 150,
      todayPresent: 130,
      todayPct: 86.67,
      weekPct: 90.83,
    });
  });

  it('builds scope-aware attendance titles and descriptions', () => {
    expect(
      buildCampusAttendanceScopeModel(
        'organization',
        { level: 'organization', id: 'org-1', name: 'Demo Academy', logo: null },
        null,
        'Tigers Campus',
      ),
    ).toMatchObject({
      mode: 'organization',
      title: 'Organization Attendance',
      reportLabel: 'Organization',
    });

    expect(
      buildCampusAttendanceScopeModel(
        'school',
        { level: 'school', id: 'school-1', name: 'Demo Academy North', logo: null },
        null,
        'Tigers Campus',
      ),
    ).toMatchObject({
      mode: 'school',
      title: 'School Attendance',
      reportLabel: 'School',
    });

    expect(
      buildCampusAttendanceScopeModel('campus', null, 'campus-1', 'Tigers Campus'),
    ).toMatchObject({
      mode: 'campus',
      title: 'Campus Attendance',
      reportLabel: 'Campus',
      campusId: 'campus-1',
    });

    expect(
      buildCampusAttendanceScopeModel(
        'class',
        { level: 'class', id: 'class-1', name: 'Tigers Homeroom 1', logo: null },
        'campus-1',
        'Tigers Campus',
      ),
    ).toMatchObject({
      mode: 'campus',
      title: 'Classroom Attendance',
      reportLabel: 'Classroom',
      campusId: 'campus-1',
    });
  });

  it('combines student attendance aggregates with staff attendance summary', () => {
    const overallStats = buildOverallAttendanceStats(summaries, '2026-06-08', '2026-06-08', '2026-06-12');

    expect(
      buildCombinedAttendanceStats(overallStats, {
        staffCount: 12,
        recordsCount: 10,
        present: 8,
        late: 1,
        absent: 1,
      }),
    ).toEqual({
      studentTodayPct: 86.67,
      studentWeekPct: 90.83,
      staffTodayPct: 90,
      combinedTodayPct: 86.88,
    });
  });
});
