// Import shared types
import CourseEventType from './CourseEventType';
import DayOfWeek from './DayOfWeek';
import PointWindow from './PointWindow';
import AssignToGroups from './AssignToGroups';

/**
 * A single course event
 * @author Gabe Abrams
 */
type CourseEvent = (
  // Common types
  {
    // The key for unique indexing
    key: string, // `${courseId}-${ihid}`
    // Course CanvasId
    courseId: number,
    // Intra-Helix ID (only needs to be unique to the course)
    ihid: string,
    // Human-readable title
    name: string,
    // Event type
    type: CourseEventType,
    // If true, TTMs cannot toggle whether the event is held in Zoom
    // (cannot add or remove Zoom). If any lock is on, the event cannot
    // be deleted
    lockZoomToggle?: boolean,
    // If true, TTMs cannot edit Zoom auto record setting (cannot be toggled).
    // If any lock is on, the event cannot be deleted
    lockAutoRecordSetting?: boolean,
    // If true, DCE students will not see or be able to join this event
    banDCEStudents?: boolean,
    // If true, FAS students will not see or be able to join this event
    banFASStudents?: boolean,
    // If pinned, the event will be sorted above non-pinned events
    pinned?: boolean,
    // If true, the event has been archived
    archived?: boolean,
  }
  // Zoom
  & (
    // Held in Zoom
    | {
      // Current Zoom meeting id
      currentZoomId: number,
      // Past Zoom meeting ids
      pastZoomIds?: number[] | null,
      // Host id or email for the current meeting
      currentZoomHost: string,
      // Past Zoom hosts
      pastZoomHosts?: string[] | null,
      // Link to join Zoom meeting
      openZoomLink: string,
      // If true, the Zoom space is a webinar
      isWebinar?: boolean,
    }
    // Not held in Zoom
    | {
      currentZoomId?: null,
      pastZoomIds?: number[] | null,
      currentZoomHost?: null,
      pastZoomHosts?: string[] | null,
      openZoomLink?: null,
      isWebinar?: null,
    }
  )
  // In-person
  & (
    // Held in person
    | {
      // If true, event is held in person
      isHeldInPerson: true,
      // In-person configuration (only defined if held in-person)
      inPersonConfig: {
        // Whether or not the event always assigns to groups
        assignToGroups: AssignToGroups,
      },
    }
    // Not held in person
    | {
      isHeldInPerson?: false,
      inPersonConfig?: undefined,
    }
  )
  // Attendance
  & (
    // Taking attendance
    | {
      // The time window where you can get a point during.
      // E.g. if "day" you can get one point for each day you attend.
      pointWindow?: PointWindow,
      // Days of the week that the event occurs
      daysOfWeek?: DayOfWeek[],
      // Max number of points achievable
      // maxPoints = 0 if the event is not for attendance
      // maxPoints = null if unlimited
      // maxPoints = undefined if not taking attendance
      maxPoints?: number | null | undefined,
    }
    // Not taking attendance
    | {
      pointWindow?: null,
      daysOfWeek?: null,
      maxPoints?: null,
    }
  )
);

export default CourseEvent;
