import { ReportFieldDef } from '../types/report-field.types'
import { FEATURE_FLAG_KEYS, REPORT_PURPOSE_FEATURE_FLAGS } from 'src/common/constants/constants'

// Hardcoded field-set shortcuts for the session-wise attendance report, so callers can skip the
// `fields[]` picker for known report types. Add a new key (and its field list) here per report
// type instead of adding a new endpoint — see GenerateSessionAttendanceReportDto.purpose.
export const SESSION_ATTENDANCE_REPORT_PURPOSE_FIELDS = {
  'single-session-attendance': [
    'sessionName', 'sessionStartsAt',
    'registrationSeqNumber', 'fullName', 'email', 'phone', 'activationStatus',
    'attendanceStatus', 'systemAttendance', 'rmAttendance', 'coordinatorAttendance',
    'joinedTime', 'noOfLogins', 'duration', 'durationSeconds',
  ],
  // Attendees screen "download all sessions" report — every eligible (seat-allocated)
  // registration × every session of the program in one call (leave filters.sessionId
  // unset). attendanceStatus/systemAttendance/rmAttendance/coordinatorAttendance come back
  // null for sessions that haven't finished yet (see the view migration) rather than a
  // misleading "Not Attended".
  'all-sessions-attendance': [
    'sessionName', 'sessionStartsAt',
    'registrationSeqNumber', 'fullName', 'email', 'phone', 'activationStatus',
    'attendanceStatus', 'systemAttendance', 'rmAttendance', 'coordinatorAttendance',
    'joinedTime', 'noOfLogins',
  ],
  // Eligible Registrations screen "download" report — one row per registrant (not per
  // registrant × session) with the per-session attendanceStatus pivoted into dynamic
  // "Session 1".."Session N" columns and eligibility collapsed to a single Absent/Eligible
  // column. The column count depends on the program's session count, so this purpose is
  // special-cased in ReportsService.generateEligibleRegistrationsAttendanceReport rather than
  // resolved through this field list — the array below is documentation-only (base attendee
  // fields), kept here just so SESSION_ATTENDANCE_REPORT_PURPOSES/DTO validation accepts the key.
  'eligible-registrations-attendance': [
    'registrationSeqNumber', 'fullName', 'email', 'phone', 'activationStatus',
  ],
  // Full per-session detail report — every attendance-family column merged into one
  // row per registrant × session, single session only (mirrors 'single-session-attendance'
  // plus lateBy/dropoffCount/joinCount/lastDropoffAt from migration 5). joinCount here is
  // zas.rejoin_count + 1 (or 0 if never joined) — a coarser, pre-aggregated count than
  // session-dropoffs' own joinCount (raw live-event JOINED tally); see migration 5 point 5.
  // durationSeconds/lateBySeconds are the raw-seconds companions to duration/lateBy
  // (migration 5 point 6) — kept alongside, not replacing, the minutes versions.
  'session-report': [
    'sessionName', 'sessionStartsAt',
    'registrationSeqNumber', 'fullName', 'email', 'phone', 'activationStatus',
    'attendanceStatus', 'systemAttendance', 'rmAttendance', 'coordinatorAttendance',
    'joinedTime', 'noOfLogins', 'duration', 'durationSeconds', 'lateBy', 'lateBySeconds',
    'dropoffCount', 'joinCount', 'lastDropoffAt',
  ],
  // Late Comers report — one row per registrant × session, focused on join timing.
  // lateBy/lateBySeconds are the exact minutes/seconds past the scheduled start they
  // joined (null for on-time/never-joined registrants — see migration 5) — rows with a
  // null lateBy are filtered out server-side (ReportsService.generateSessionAttendanceReport),
  // since this purpose should surface only registrants who actually joined late.
  'late-comer-report': [
    'sessionName', 'sessionStartsAt',
    'registrationSeqNumber', 'fullName', 'email', 'phone',
    'joinedTime', 'lateBy', 'lateBySeconds',
  ],
  // Single-session drop-off report — one row per registrant who left the session at
  // least once, with join count, drop-off count, and every leave_reason they triggered.
  // dropoffCount is every raw LEFT event before the session's scheduled end EXCLUDING
  // ones caused by the host closing the meeting (that's the session ending for
  // everyone, not a per-seeker drop) — see fn_generate_session_dropoff_report's header
  // (migration 10; supersedes migration 9's device-aware "concurrent connections hit
  // zero" definition, which undercounted for registrant emails shared across many
  // simultaneous devices).
  // Reads zoom_analytics_live_event directly (not vw_program_session_attendance_report),
  // so it's fully special-cased in ReportsService.generateSessionDropoffsReport rather than
  // resolved through this field list — the array below is documentation-only, kept here
  // just so SESSION_ATTENDANCE_REPORT_PURPOSES/DTO validation accepts the key. Requires
  // filters.sessionId (RPT_BR_003 if omitted).
  'session-dropoffs': [
    'registrationId', 'fullName', 'phone', 'email', 'rmName',
    'zoomTaggedEmail', 'joinCount', 'dropoffCount', 'leaveReasons',
  ],
  // General Attendees screen "download" report — one row per shared/common-link
  // attendee (no ProgramRegistration of their own, i.e. registration_id IS NULL),
  // mirroring the live screen's GENERAL_ATTENDEE_TABLE_HEADERS column set exactly.
  // Reads zoom_analytics_attendee_summary joined against zoom_generated_registrant_link
  // (not vw_program_session_attendance_report), so it's fully special-cased in
  // ReportsService.generateGeneralAttendeesReport rather than resolved through this
  // field list — the array below is documentation-only, kept here just so
  // SESSION_ATTENDANCE_REPORT_PURPOSES/DTO validation accepts the key. Requires
  // filters.sessionId (RPT_BR_003 if omitted), same as session-dropoffs.
  'general-attendees': [
    'fullName', 'email', 'mobile', 'attendance', 'joinedAt',
    'noOfDevices', 'dropoffCount', 'durationSeconds', 'sourceTag',
  ],
  // General Attendees screen counterpart to 'session-report' — every column
  // fn_generate_general_attendees_report returns, including lateBy/lateBySeconds/
  // joinCount/lastDropoffAt (same formulas migration 5 added for the registered
  // family, see migration 7's own header). Special-cased in
  // ReportsService.generateGeneralAttendeeFamilyReport; documentation-only here,
  // same as 'general-attendees'. Requires filters.sessionId.
  'general-session-report': [
    'fullName', 'email', 'mobile', 'attendance', 'joinedAt', 'noOfDevices',
    'dropoffCount', 'durationSeconds', 'lateBy', 'lateBySeconds', 'joinCount',
    'lastDropoffAt', 'sourceTag',
  ],
  // General Attendees screen counterpart to 'late-comer-report' — join timing only,
  // from the same fn_generate_general_attendees_report call as the other 2
  // general-* purposes (no separate function needed, unlike the registered family's
  // late-comer-report which shares vw_program_session_attendance_report too).
  // Special-cased in ReportsService.generateGeneralAttendeeFamilyReport;
  // documentation-only here. Requires filters.sessionId.
  'general-late-comer-report': [
    'fullName', 'email', 'mobile', 'joinedAt', 'lateBy', 'lateBySeconds', 'sourceTag',
  ],
  // General Attendees screen counterpart to 'session-dropoffs' — one row per
  // shared/common-link attendee who left this session at least once, with join/leave
  // counts and every leave_reason they triggered. Reads zoom_analytics_live_event
  // directly (not fn_generate_general_attendees_report), scoped to '+gen'-tagged
  // emails instead of '+reg' — see fn_generate_general_session_dropoff_report's
  // header (migration 8). Special-cased in
  // ReportsService.generateGeneralSessionDropoffsReport; documentation-only here.
  // Requires filters.sessionId.
  'general-session-dropoffs': [
    'fullName', 'email', 'mobile', 'sourceTag',
    'zoomTaggedEmail', 'joinCount', 'dropoffCount', 'leaveReasons',
  ],
} as const

export type SessionAttendanceReportPurpose = keyof typeof SESSION_ATTENDANCE_REPORT_PURPOSE_FIELDS

// Program-TYPE-scoped feature-flag gate per purpose (checked by
// ReportsService.generateSessionAttendanceReport before dispatching, resolved through the
// requested program's own program_type_id) — a purpose with no entry here isn't gated at all.
// Sourced from the shared REPORT_PURPOSE_FEATURE_FLAGS (src/common/constants/constants.ts) rather
// than redefined here, since ZoomAnalyticsFacadeService.getAttendeeTableV1 needs the exact same
// purpose-code -> required-flags mapping (for its `reports[].isActive`) without the zoom module
// importing from the reports module. One flag per report, purpose-to-flag is 1:1 — see that
// constant's own comment for why ENABLE_SINGLE_SESSION_REPORT (present in
// REPORT_DOWNLOAD_FEATURE_FLAG_KEYS below, for the UI's benefit) is NOT one of the keys here.
// 'all-sessions-attendance' and ad-hoc `fields` requests (no `purpose`) are intentionally left
// ungated — no flag was requested for those.
export const SESSION_ATTENDANCE_REPORT_FEATURE_FLAGS =
  REPORT_PURPOSE_FEATURE_FLAGS as Partial<Record<SessionAttendanceReportPurpose, readonly string[]>>

// The 11 report-download flag keys the UI (infinipath-web-admin) needs to know about, for
// ReportsService.getReportFeatureFlags — one per report, plus ENABLE_SINGLE_SESSION_REPORT (which
// gates isSessionReportEnabled specifically, unrelated to the 4 individual single-session purpose
// flags — see SESSION_ATTENDANCE_REPORT_FEATURE_FLAGS above for the purpose-to-keys mapping).
export const REPORT_DOWNLOAD_FEATURE_FLAG_KEYS = [
  FEATURE_FLAG_KEYS.ENABLE_ZOOM_LINKS_REPORT,
  FEATURE_FLAG_KEYS.ENABLE_ELIGIBLE_REGISTRATIONS_REPORT,
  FEATURE_FLAG_KEYS.ENABLE_SINGLE_SESSION_REPORT,
  FEATURE_FLAG_KEYS.ENABLE_SINGLE_SESSION_ATTENDANCE_REPORT,
  FEATURE_FLAG_KEYS.ENABLE_SESSION_DETAIL_REPORT,
  FEATURE_FLAG_KEYS.ENABLE_LATE_COMER_REPORT,
  FEATURE_FLAG_KEYS.ENABLE_SESSION_DROPOFFS_REPORT,
  FEATURE_FLAG_KEYS.ENABLE_ATTENDEES_LIVE_REPORT,
  FEATURE_FLAG_KEYS.ENABLE_GENERAL_SESSION_REPORT,
  FEATURE_FLAG_KEYS.ENABLE_GENERAL_LATE_COMER_REPORT,
  FEATURE_FLAG_KEYS.ENABLE_GENERAL_SESSION_DROPOFFS_REPORT,
] as const

export const SESSION_ATTENDANCE_REPORT_PURPOSES = Object.keys(
  SESSION_ATTENDANCE_REPORT_PURPOSE_FIELDS,
) as SessionAttendanceReportPurpose[]

// Fixed field registry for the 'session-dropoffs' purpose — sourced from
// fn_generate_session_dropoff_report, which returns exactly these 9 columns
// (no dynamic/per-program shape), so a hardcoded map is simpler than a DB registry
// function for a set this small and fixed.
export const SESSION_DROPOFF_FIELD_DEFS: Record<string, ReportFieldDef> = {
  registrationId:  { key: 'registrationId',  alias: 'registrationId',  label: 'Registration ID',   group: 'Attendee',   order: 1, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  fullName:        { key: 'fullName',        alias: 'fullName',        label: 'Full Name',         group: 'Attendee',   order: 2, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  phone:           { key: 'phone',           alias: 'phone',           label: 'Mobile',            group: 'Attendee',   order: 3, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  email:           { key: 'email',           alias: 'email',           label: 'Email',             group: 'Attendee',   order: 4, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  rmName:          { key: 'rmName',          alias: 'rmName',          label: 'RM Name',           group: 'Attendee',   order: 5, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  zoomTaggedEmail: { key: 'zoomTaggedEmail', alias: 'zoomTaggedEmail', label: 'Zoom Tagged Email', group: 'Attendance', order: 6, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  joinCount:       { key: 'joinCount',       alias: 'joinCount',       label: 'Join Count',        group: 'Attendance', order: 7, format: 'number', dependsOn: null, requiredFlags: null, conditionalFormat: null },
  dropoffCount:    { key: 'dropoffCount',    alias: 'dropoffCount',    label: 'Drop-off Count',    group: 'Attendance', order: 8, format: 'number', dependsOn: null, requiredFlags: null, conditionalFormat: null },
  leaveReasons:    { key: 'leaveReasons',    alias: 'leaveReasons',    label: 'Leave Reasons',     group: 'Attendance', order: 9, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
}

// Fixed field registry for the 'general-attendees' purpose — sourced from
// fn_generate_general_attendees_report, which returns exactly these 9 columns
// (no dynamic/per-program shape), same rationale as SESSION_DROPOFF_FIELD_DEFS.
export const GENERAL_ATTENDEE_REPORT_FIELD_DEFS: Record<string, ReportFieldDef> = {
  fullName:        { key: 'fullName',        alias: 'fullName',        label: 'Full Name',         group: 'Attendee',   order: 1, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  email:           { key: 'email',           alias: 'email',           label: 'Email',             group: 'Attendee',   order: 2, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  mobile:          { key: 'mobile',          alias: 'mobile',          label: 'Phone Number',      group: 'Attendee',   order: 3, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  attendance:      { key: 'attendance',      alias: 'attendance',      label: 'In-session Status', group: 'Attendance', order: 4, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  joinedAt:        { key: 'joinedAt',        alias: 'joinedAt',        label: 'Logged In',         group: 'Attendance', order: 5, format: 'datetime', dependsOn: null, requiredFlags: null, conditionalFormat: null },
  noOfDevices:     { key: 'noOfDevices',     alias: 'noOfDevices',     label: 'No. of Login(s)',   group: 'Attendance', order: 6, format: 'number', dependsOn: null, requiredFlags: null, conditionalFormat: null },
  dropoffCount:    { key: 'dropoffCount',    alias: 'dropoffCount',    label: 'Drop-off(s)',       group: 'Attendance', order: 7, format: 'number', dependsOn: null, requiredFlags: null, conditionalFormat: null },
  durationSeconds: { key: 'durationSeconds', alias: 'durationSeconds', label: 'Duration (secs)',   group: 'Attendance', order: 8, format: 'number', dependsOn: null, requiredFlags: null, conditionalFormat: null },
  sourceTag:       { key: 'sourceTag',       alias: 'sourceTag',       label: 'Type',              group: 'Attendee',   order: 9, format: 'source-tag-role',     dependsOn: null, requiredFlags: null, conditionalFormat: null },
}

// Fixed field registry for the 'general-session-report' purpose — the same
// fn_generate_general_attendees_report call as GENERAL_ATTENDEE_REPORT_FIELD_DEFS,
// just picking up its lateBy/lateBySeconds/joinCount/lastDropoffAt columns too.
export const GENERAL_SESSION_REPORT_FIELD_DEFS: Record<string, ReportFieldDef> = {
  fullName:        { key: 'fullName',        alias: 'fullName',        label: 'Full Name',         group: 'Attendee',   order: 1,  format: null,      dependsOn: null, requiredFlags: null, conditionalFormat: null },
  email:           { key: 'email',           alias: 'email',           label: 'Email',             group: 'Attendee',   order: 2,  format: null,      dependsOn: null, requiredFlags: null, conditionalFormat: null },
  mobile:          { key: 'mobile',          alias: 'mobile',          label: 'Phone Number',      group: 'Attendee',   order: 3,  format: null,      dependsOn: null, requiredFlags: null, conditionalFormat: null },
  attendance:      { key: 'attendance',      alias: 'attendance',      label: 'In-session Status', group: 'Attendance', order: 4,  format: null,      dependsOn: null, requiredFlags: null, conditionalFormat: null },
  joinedAt:        { key: 'joinedAt',        alias: 'joinedAt',        label: 'Logged In',         group: 'Attendance', order: 5,  format: 'datetime', dependsOn: null, requiredFlags: null, conditionalFormat: null },
  noOfDevices:     { key: 'noOfDevices',     alias: 'noOfDevices',     label: 'No. of Login(s)',   group: 'Attendance', order: 6,  format: 'number',   dependsOn: null, requiredFlags: null, conditionalFormat: null },
  dropoffCount:    { key: 'dropoffCount',    alias: 'dropoffCount',    label: 'Drop-off(s)',       group: 'Attendance', order: 7,  format: 'number',   dependsOn: null, requiredFlags: null, conditionalFormat: null },
  durationSeconds: { key: 'durationSeconds', alias: 'durationSeconds', label: 'Duration (secs)',   group: 'Attendance', order: 8,  format: 'number',   dependsOn: null, requiredFlags: null, conditionalFormat: null },
  lateBy:          { key: 'lateBy',          alias: 'lateBy',          label: 'Late By (mins)',    group: 'Attendance', order: 9,  format: 'number',   dependsOn: null, requiredFlags: null, conditionalFormat: null },
  lateBySeconds:   { key: 'lateBySeconds',   alias: 'lateBySeconds',   label: 'Late By (secs)',    group: 'Attendance', order: 10, format: 'number',   dependsOn: null, requiredFlags: null, conditionalFormat: null },
  joinCount:       { key: 'joinCount',       alias: 'joinCount',       label: 'Join Count',        group: 'Attendance', order: 11, format: 'number',   dependsOn: null, requiredFlags: null, conditionalFormat: null },
  lastDropoffAt:   { key: 'lastDropoffAt',   alias: 'lastDropoffAt',   label: 'Last Drop-off At',  group: 'Attendance', order: 12, format: 'datetime', dependsOn: null, requiredFlags: null, conditionalFormat: null },
  sourceTag:       { key: 'sourceTag',       alias: 'sourceTag',       label: 'Type',              group: 'Attendee',   order: 13, format: 'source-tag-role',      dependsOn: null, requiredFlags: null, conditionalFormat: null },
}

// Fixed field registry for the 'general-late-comer-report' purpose — same
// fn_generate_general_attendees_report call, join-timing columns only.
export const GENERAL_LATE_COMER_REPORT_FIELD_DEFS: Record<string, ReportFieldDef> = {
  fullName:      { key: 'fullName',      alias: 'fullName',      label: 'Full Name',      group: 'Attendee',   order: 1, format: null,      dependsOn: null, requiredFlags: null, conditionalFormat: null },
  email:         { key: 'email',         alias: 'email',         label: 'Email',          group: 'Attendee',   order: 2, format: null,      dependsOn: null, requiredFlags: null, conditionalFormat: null },
  mobile:        { key: 'mobile',        alias: 'mobile',        label: 'Phone Number',   group: 'Attendee',   order: 3, format: null,      dependsOn: null, requiredFlags: null, conditionalFormat: null },
  joinedAt:      { key: 'joinedAt',      alias: 'joinedAt',      label: 'Logged In',      group: 'Attendance', order: 4, format: 'datetime', dependsOn: null, requiredFlags: null, conditionalFormat: null },
  lateBy:        { key: 'lateBy',        alias: 'lateBy',        label: 'Late By (mins)', group: 'Attendance', order: 5, format: 'number',   dependsOn: null, requiredFlags: null, conditionalFormat: null },
  lateBySeconds: { key: 'lateBySeconds', alias: 'lateBySeconds', label: 'Late By (secs)', group: 'Attendance', order: 6, format: 'number',   dependsOn: null, requiredFlags: null, conditionalFormat: null },
  sourceTag:     { key: 'sourceTag',     alias: 'sourceTag',     label: 'Type',           group: 'Attendee',   order: 7, format: 'source-tag-role',      dependsOn: null, requiredFlags: null, conditionalFormat: null },
}

// Fixed field registry for the 'general-session-dropoffs' purpose — sourced from
// fn_generate_general_session_dropoff_report, which returns exactly these 8
// columns (no dynamic/per-program shape), same rationale as SESSION_DROPOFF_FIELD_DEFS.
export const GENERAL_SESSION_DROPOFF_FIELD_DEFS: Record<string, ReportFieldDef> = {
  fullName:        { key: 'fullName',        alias: 'fullName',        label: 'Full Name',         group: 'Attendee',   order: 1, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  email:           { key: 'email',           alias: 'email',           label: 'Email',             group: 'Attendee',   order: 2, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  mobile:          { key: 'mobile',          alias: 'mobile',          label: 'Phone Number',      group: 'Attendee',   order: 3, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  sourceTag:       { key: 'sourceTag',       alias: 'sourceTag',       label: 'Type',              group: 'Attendee',   order: 4, format: 'source-tag-role',     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  zoomTaggedEmail: { key: 'zoomTaggedEmail', alias: 'zoomTaggedEmail', label: 'Zoom Tagged Email', group: 'Attendance', order: 5, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
  joinCount:       { key: 'joinCount',       alias: 'joinCount',       label: 'Join Count',        group: 'Attendance', order: 6, format: 'number', dependsOn: null, requiredFlags: null, conditionalFormat: null },
  dropoffCount:    { key: 'dropoffCount',    alias: 'dropoffCount',    label: 'Drop-off Count',    group: 'Attendance', order: 7, format: 'number', dependsOn: null, requiredFlags: null, conditionalFormat: null },
  leaveReasons:    { key: 'leaveReasons',    alias: 'leaveReasons',    label: 'Leave Reasons',     group: 'Attendance', order: 8, format: null,     dependsOn: null, requiredFlags: null, conditionalFormat: null },
}
