// Generated by ./scripts/gen_openapi_types.ts

/** PATHS **/

// /api/account
export type ACCOUNT_UPDATE_REQUEST_PARAMS = Record<string, never>;
export type ACCOUNT_UPDATE_REQUEST_PATH = `/api/account`;
export type ACCOUNT_UPDATE_REQUEST_BODY = AccountUpdateRequest;

// /api/elections
export type ELECTION_LIST_REQUEST_PARAMS = Record<string, never>;
export type ELECTION_LIST_REQUEST_PATH = `/api/elections`;

// /api/elections/import
export type ELECTION_IMPORT_REQUEST_PARAMS = Record<string, never>;
export type ELECTION_IMPORT_REQUEST_PATH = `/api/elections/import`;
export type ELECTION_IMPORT_REQUEST_BODY = ElectionAndCandidatesDefinitionImportRequest;

// /api/elections/import/validate
export type ELECTION_IMPORT_VALIDATE_REQUEST_PARAMS = Record<string, never>;
export type ELECTION_IMPORT_VALIDATE_REQUEST_PATH = `/api/elections/import/validate`;
export type ELECTION_IMPORT_VALIDATE_REQUEST_BODY = ElectionAndCandidateDefinitionValidateRequest;

// /api/elections/{election_id}
export interface ELECTION_DETAILS_REQUEST_PARAMS {
  election_id: number;
}
export type ELECTION_DETAILS_REQUEST_PATH = `/api/elections/${number}`;

// /api/elections/{election_id}/committee_sessions
export interface COMMITTEE_SESSION_CREATE_REQUEST_PARAMS {
  election_id: number;
}
export type COMMITTEE_SESSION_CREATE_REQUEST_PATH = `/api/elections/${number}/committee_sessions`;

// /api/elections/{election_id}/committee_sessions/{committee_session_id}
export interface COMMITTEE_SESSION_UPDATE_REQUEST_PARAMS {
  election_id: number;
  committee_session_id: number;
}
export type COMMITTEE_SESSION_UPDATE_REQUEST_PATH = `/api/elections/${number}/committee_sessions/${number}`;
export type COMMITTEE_SESSION_UPDATE_REQUEST_BODY = CommitteeSessionUpdateRequest;
export interface COMMITTEE_SESSION_DELETE_REQUEST_PARAMS {
  election_id: number;
  committee_session_id: number;
}
export type COMMITTEE_SESSION_DELETE_REQUEST_PATH = `/api/elections/${number}/committee_sessions/${number}`;

// /api/elections/{election_id}/committee_sessions/{committee_session_id}/download_pdf_results
export interface ELECTION_DOWNLOAD_PDF_RESULTS_REQUEST_PARAMS {
  election_id: number;
  committee_session_id: number;
}
export type ELECTION_DOWNLOAD_PDF_RESULTS_REQUEST_PATH =
  `/api/elections/${number}/committee_sessions/${number}/download_pdf_results`;

// /api/elections/{election_id}/committee_sessions/{committee_session_id}/download_zip_results
export interface ELECTION_DOWNLOAD_ZIP_RESULTS_REQUEST_PARAMS {
  election_id: number;
  committee_session_id: number;
}
export type ELECTION_DOWNLOAD_ZIP_RESULTS_REQUEST_PATH =
  `/api/elections/${number}/committee_sessions/${number}/download_zip_results`;

// /api/elections/{election_id}/committee_sessions/{committee_session_id}/investigations
export interface COMMITTEE_SESSION_INVESTIGATIONS_REQUEST_PARAMS {
  election_id: number;
  committee_session_id: number;
}
export type COMMITTEE_SESSION_INVESTIGATIONS_REQUEST_PATH =
  `/api/elections/${number}/committee_sessions/${number}/investigations`;

// /api/elections/{election_id}/committee_sessions/{committee_session_id}/status
export interface COMMITTEE_SESSION_STATUS_CHANGE_REQUEST_PARAMS {
  election_id: number;
  committee_session_id: number;
}
export type COMMITTEE_SESSION_STATUS_CHANGE_REQUEST_PATH =
  `/api/elections/${number}/committee_sessions/${number}/status`;
export type COMMITTEE_SESSION_STATUS_CHANGE_REQUEST_BODY = CommitteeSessionStatusChangeRequest;

// /api/elections/{election_id}/committee_sessions/{committee_session_id}/voters
export interface COMMITTEE_SESSION_NUMBER_OF_VOTERS_CHANGE_REQUEST_PARAMS {
  election_id: number;
  committee_session_id: number;
}
export type COMMITTEE_SESSION_NUMBER_OF_VOTERS_CHANGE_REQUEST_PATH =
  `/api/elections/${number}/committee_sessions/${number}/voters`;
export type COMMITTEE_SESSION_NUMBER_OF_VOTERS_CHANGE_REQUEST_BODY = CommitteeSessionNumberOfVotersChangeRequest;

// /api/elections/{election_id}/download_n_10_2
export interface ELECTION_DOWNLOAD_N_10_2_REQUEST_PARAMS {
  election_id: number;
}
export type ELECTION_DOWNLOAD_N_10_2_REQUEST_PATH = `/api/elections/${number}/download_n_10_2`;

// /api/elections/{election_id}/download_na_31_2_bijlage1
export interface ELECTION_DOWNLOAD_NA_31_2_BIJLAGE1_REQUEST_PARAMS {
  election_id: number;
}
export type ELECTION_DOWNLOAD_NA_31_2_BIJLAGE1_REQUEST_PATH = `/api/elections/${number}/download_na_31_2_bijlage1`;

// /api/elections/{election_id}/download_na_31_2_inlegvel
export interface ELECTION_DOWNLOAD_NA_31_2_INLEGVEL_REQUEST_PARAMS {
  election_id: number;
}
export type ELECTION_DOWNLOAD_NA_31_2_INLEGVEL_REQUEST_PATH = `/api/elections/${number}/download_na_31_2_inlegvel`;

// /api/elections/{election_id}/polling_stations
export interface POLLING_STATION_LIST_REQUEST_PARAMS {
  election_id: number;
}
export type POLLING_STATION_LIST_REQUEST_PATH = `/api/elections/${number}/polling_stations`;
export interface POLLING_STATION_CREATE_REQUEST_PARAMS {
  election_id: number;
}
export type POLLING_STATION_CREATE_REQUEST_PATH = `/api/elections/${number}/polling_stations`;
export type POLLING_STATION_CREATE_REQUEST_BODY = PollingStationRequest;

// /api/elections/{election_id}/polling_stations/import
export interface POLLING_STATION_IMPORT_REQUEST_PARAMS {
  election_id: number;
}
export type POLLING_STATION_IMPORT_REQUEST_PATH = `/api/elections/${number}/polling_stations/import`;
export type POLLING_STATION_IMPORT_REQUEST_BODY = PollingStationsRequest;

// /api/elections/{election_id}/polling_stations/validate-import
export interface POLLING_STATION_VALIDATE_IMPORT_REQUEST_PARAMS {
  election_id: number;
}
export type POLLING_STATION_VALIDATE_IMPORT_REQUEST_PATH = `/api/elections/${number}/polling_stations/validate-import`;
export type POLLING_STATION_VALIDATE_IMPORT_REQUEST_BODY = PollingStationFileRequest;

// /api/elections/{election_id}/polling_stations/{polling_station_id}
export interface POLLING_STATION_GET_REQUEST_PARAMS {
  election_id: number;
  polling_station_id: number;
}
export type POLLING_STATION_GET_REQUEST_PATH = `/api/elections/${number}/polling_stations/${number}`;
export interface POLLING_STATION_UPDATE_REQUEST_PARAMS {
  election_id: number;
  polling_station_id: number;
}
export type POLLING_STATION_UPDATE_REQUEST_PATH = `/api/elections/${number}/polling_stations/${number}`;
export type POLLING_STATION_UPDATE_REQUEST_BODY = PollingStationRequest;
export interface POLLING_STATION_DELETE_REQUEST_PARAMS {
  election_id: number;
  polling_station_id: number;
}
export type POLLING_STATION_DELETE_REQUEST_PATH = `/api/elections/${number}/polling_stations/${number}`;

// /api/elections/{election_id}/status
export interface ELECTION_STATUS_REQUEST_PARAMS {
  election_id: number;
}
export type ELECTION_STATUS_REQUEST_PATH = `/api/elections/${number}/status`;

// /api/generate_test_election
export type GENERATE_ELECTION_HANDLER_REQUEST_PARAMS = Record<string, never>;
export type GENERATE_ELECTION_HANDLER_REQUEST_PATH = `/api/generate_test_election`;
export type GENERATE_ELECTION_HANDLER_REQUEST_BODY = GenerateElectionArgs;

// /api/initialise/admin-exists
export type ADMIN_EXISTS_REQUEST_PARAMS = Record<string, never>;
export type ADMIN_EXISTS_REQUEST_PATH = `/api/initialise/admin-exists`;

// /api/initialise/first-admin
export type CREATE_FIRST_ADMIN_REQUEST_PARAMS = Record<string, never>;
export type CREATE_FIRST_ADMIN_REQUEST_PATH = `/api/initialise/first-admin`;
export type CREATE_FIRST_ADMIN_REQUEST_BODY = CreateUserRequest;

// /api/initialised
export type INITIALISED_REQUEST_PARAMS = Record<string, never>;
export type INITIALISED_REQUEST_PATH = `/api/initialised`;

// /api/log
export interface AUDIT_LOG_LIST_REQUEST_PARAMS {
  page: number;
  per_page: number;
  level: string[];
  event: string[];
  user: number[];
  since: number | null;
}
export type AUDIT_LOG_LIST_REQUEST_PATH = `/api/log`;

// /api/log-users
export type AUDIT_LOG_LIST_USERS_REQUEST_PARAMS = Record<string, never>;
export type AUDIT_LOG_LIST_USERS_REQUEST_PATH = `/api/log-users`;

// /api/login
export type LOGIN_REQUEST_PARAMS = Record<string, never>;
export type LOGIN_REQUEST_PATH = `/api/login`;
export type LOGIN_REQUEST_BODY = Credentials;

// /api/logout
export type LOGOUT_REQUEST_PARAMS = Record<string, never>;
export type LOGOUT_REQUEST_PATH = `/api/logout`;

// /api/polling_stations/{polling_station_id}/data_entries
export interface POLLING_STATION_DATA_ENTRIES_AND_RESULT_DELETE_REQUEST_PARAMS {
  polling_station_id: number;
}
export type POLLING_STATION_DATA_ENTRIES_AND_RESULT_DELETE_REQUEST_PATH =
  `/api/polling_stations/${number}/data_entries`;

// /api/polling_stations/{polling_station_id}/data_entries/get
export interface POLLING_STATION_DATA_ENTRY_GET_REQUEST_PARAMS {
  polling_station_id: number;
}
export type POLLING_STATION_DATA_ENTRY_GET_REQUEST_PATH = `/api/polling_stations/${number}/data_entries/get`;

// /api/polling_stations/{polling_station_id}/data_entries/resolve_differences
export interface POLLING_STATION_DATA_ENTRY_GET_DIFFERENCES_REQUEST_PARAMS {
  polling_station_id: number;
}
export type POLLING_STATION_DATA_ENTRY_GET_DIFFERENCES_REQUEST_PATH =
  `/api/polling_stations/${number}/data_entries/resolve_differences`;
export interface POLLING_STATION_DATA_ENTRY_RESOLVE_DIFFERENCES_REQUEST_PARAMS {
  polling_station_id: number;
}
export type POLLING_STATION_DATA_ENTRY_RESOLVE_DIFFERENCES_REQUEST_PATH =
  `/api/polling_stations/${number}/data_entries/resolve_differences`;
export type POLLING_STATION_DATA_ENTRY_RESOLVE_DIFFERENCES_REQUEST_BODY = ResolveDifferencesAction;

// /api/polling_stations/{polling_station_id}/data_entries/resolve_errors
export interface POLLING_STATION_DATA_ENTRY_RESOLVE_ERRORS_REQUEST_PARAMS {
  polling_station_id: number;
}
export type POLLING_STATION_DATA_ENTRY_RESOLVE_ERRORS_REQUEST_PATH =
  `/api/polling_stations/${number}/data_entries/resolve_errors`;
export type POLLING_STATION_DATA_ENTRY_RESOLVE_ERRORS_REQUEST_BODY = ResolveErrorsAction;

// /api/polling_stations/{polling_station_id}/data_entries/{entry_number}
export interface POLLING_STATION_DATA_ENTRY_SAVE_REQUEST_PARAMS {
  polling_station_id: number;
  entry_number: number;
}
export type POLLING_STATION_DATA_ENTRY_SAVE_REQUEST_PATH = `/api/polling_stations/${number}/data_entries/${number}`;
export type POLLING_STATION_DATA_ENTRY_SAVE_REQUEST_BODY = DataEntry;
export interface POLLING_STATION_DATA_ENTRY_DELETE_REQUEST_PARAMS {
  polling_station_id: number;
  entry_number: number;
}
export type POLLING_STATION_DATA_ENTRY_DELETE_REQUEST_PATH = `/api/polling_stations/${number}/data_entries/${number}`;

// /api/polling_stations/{polling_station_id}/data_entries/{entry_number}/claim
export interface POLLING_STATION_DATA_ENTRY_CLAIM_REQUEST_PARAMS {
  polling_station_id: number;
  entry_number: number;
}
export type POLLING_STATION_DATA_ENTRY_CLAIM_REQUEST_PATH =
  `/api/polling_stations/${number}/data_entries/${number}/claim`;

// /api/polling_stations/{polling_station_id}/data_entries/{entry_number}/finalise
export interface POLLING_STATION_DATA_ENTRY_FINALISE_REQUEST_PARAMS {
  polling_station_id: number;
  entry_number: number;
}
export type POLLING_STATION_DATA_ENTRY_FINALISE_REQUEST_PATH =
  `/api/polling_stations/${number}/data_entries/${number}/finalise`;

// /api/polling_stations/{polling_station_id}/investigation
export interface POLLING_STATION_INVESTIGATION_UPDATE_REQUEST_PARAMS {
  polling_station_id: number;
}
export type POLLING_STATION_INVESTIGATION_UPDATE_REQUEST_PATH = `/api/polling_stations/${number}/investigation`;
export type POLLING_STATION_INVESTIGATION_UPDATE_REQUEST_BODY = PollingStationInvestigationUpdateRequest;
export interface POLLING_STATION_INVESTIGATION_CREATE_REQUEST_PARAMS {
  polling_station_id: number;
}
export type POLLING_STATION_INVESTIGATION_CREATE_REQUEST_PATH = `/api/polling_stations/${number}/investigation`;
export type POLLING_STATION_INVESTIGATION_CREATE_REQUEST_BODY = PollingStationInvestigationCreateRequest;
export interface POLLING_STATION_INVESTIGATION_DELETE_REQUEST_PARAMS {
  polling_station_id: number;
}
export type POLLING_STATION_INVESTIGATION_DELETE_REQUEST_PATH = `/api/polling_stations/${number}/investigation`;

// /api/polling_stations/{polling_station_id}/investigation/conclude
export interface POLLING_STATION_INVESTIGATION_CONCLUDE_REQUEST_PARAMS {
  polling_station_id: number;
}
export type POLLING_STATION_INVESTIGATION_CONCLUDE_REQUEST_PATH =
  `/api/polling_stations/${number}/investigation/conclude`;
export type POLLING_STATION_INVESTIGATION_CONCLUDE_REQUEST_BODY = PollingStationInvestigationConcludeRequest;

// /api/polling_stations/{polling_station_id}/investigation/download_corrigendum_pdf
export interface POLLING_STATION_INVESTIGATION_DOWNLOAD_CORRIGENDUM_PDF_REQUEST_PARAMS {
  polling_station_id: number;
}
export type POLLING_STATION_INVESTIGATION_DOWNLOAD_CORRIGENDUM_PDF_REQUEST_PATH =
  `/api/polling_stations/${number}/investigation/download_corrigendum_pdf`;

// /api/user
export type USER_LIST_REQUEST_PARAMS = Record<string, never>;
export type USER_LIST_REQUEST_PATH = `/api/user`;
export type USER_CREATE_REQUEST_PARAMS = Record<string, never>;
export type USER_CREATE_REQUEST_PATH = `/api/user`;
export type USER_CREATE_REQUEST_BODY = CreateUserRequest;

// /api/user/{user_id}
export interface USER_GET_REQUEST_PARAMS {
  user_id: number;
}
export type USER_GET_REQUEST_PATH = `/api/user/${number}`;
export interface USER_UPDATE_REQUEST_PARAMS {
  user_id: number;
}
export type USER_UPDATE_REQUEST_PATH = `/api/user/${number}`;
export type USER_UPDATE_REQUEST_BODY = UpdateUserRequest;
export interface USER_DELETE_REQUEST_PARAMS {
  user_id: number;
}
export type USER_DELETE_REQUEST_PATH = `/api/user/${number}`;

// /api/whoami
export type WHOAMI_REQUEST_PARAMS = Record<string, never>;
export type WHOAMI_REQUEST_PATH = `/api/whoami`;

/** TYPES **/

export interface AccountUpdateRequest {
  fullname?: string;
  password: string;
  username: string;
}

export interface ApplicationStartedDetails {
  commit: string;
  version: string;
}

export type AuditEvent =
  | (UserLoggedInDetails & { event_type: "UserLoggedIn" })
  | (UserLoginFailedDetails & { event_type: "UserLoginFailed" })
  | (UserLoggedOutDetails & { event_type: "UserLoggedOut" })
  | (UserDetails & { event_type: "UserAccountUpdated" })
  | { event_type: "UserSessionExtended" }
  | (UserDetails & { event_type: "UserCreated" })
  | (UserDetails & { event_type: "UserUpdated" })
  | (UserDetails & { event_type: "UserDeleted" })
  | (ElectionDetails & { event_type: "ElectionCreated" })
  | (CommitteeSessionDetails & { event_type: "CommitteeSessionCreated" })
  | (CommitteeSessionDetails & { event_type: "CommitteeSessionDeleted" })
  | (CommitteeSessionDetails & { event_type: "CommitteeSessionUpdated" })
  | (PollingStationInvestigation & { event_type: "PollingStationInvestigationCreated" })
  | (PollingStationInvestigation & { event_type: "PollingStationInvestigationConcluded" })
  | (PollingStationInvestigation & { event_type: "PollingStationInvestigationUpdated" })
  | (PollingStationInvestigation & { event_type: "PollingStationInvestigationDeleted" })
  | (FileDetails & { event_type: "FileCreated" })
  | (FileDetails & { event_type: "FileDeleted" })
  | (PollingStationDetails & { event_type: "PollingStationCreated" })
  | (PollingStationDetails & { event_type: "PollingStationUpdated" })
  | (PollingStationDetails & { event_type: "PollingStationDeleted" })
  | (PollingStationImportDetails & { event_type: "PollingStationsImported" })
  | (DataEntryDetails & { event_type: "DataEntryStarted" })
  | (DataEntryDetails & { event_type: "DataEntrySaved" })
  | (DataEntryDetails & { event_type: "DataEntryResumed" })
  | (DataEntryDetails & { event_type: "DataEntryDeleted" })
  | (DataEntryDetails & { event_type: "DataEntryFinalised" })
  | (ResultDetails & { event_type: "ResultDeleted" })
  | (DataEntryDetails & { event_type: "DataEntryDiscardedFirst" })
  | (DataEntryDetails & { event_type: "DataEntryReturnedFirst" })
  | (DataEntryDetails & { event_type: "DataEntryKeptFirst" })
  | (DataEntryDetails & { event_type: "DataEntryKeptSecond" })
  | (DataEntryDetails & { event_type: "DataEntryDiscardedBoth" })
  | { event_type: "AirGapViolationDetected" }
  | { event_type: "AirGapViolationResolved" }
  | (ApplicationStartedDetails & { event_type: "ApplicationStarted" })
  | (ErrorDetails & { event_type: "Error" })
  | { event_type: "UnknownEvent" };

export type AuditEventLevel = "info" | "success" | "warning" | "error";

export interface AuditLogEvent {
  event: AuditEvent;
  event_level: AuditEventLevel;
  id: number;
  ip: string;
  message?: string;
  time: string;
  user_fullname?: string;
  user_id?: number;
  user_role?: Role;
  username?: string;
}

export interface AuditLogListResponse {
  events: AuditLogEvent[];
  page: number;
  pages: number;
  per_page: number;
}

export interface AuditLogUser {
  fullname: string;
  id: number;
  role: Role;
  username: string;
}

/**
 * CSOFirstSessionResults, following the fields in Model Na 31-2 Bijlage 2.
 *
 * See "Model Na 31-2. Proces-verbaal van een gemeentelijk stembureau/stembureau voor het openbaar
 * lichaam in een gemeente/openbaar lichaam waar een centrale stemopneming wordt verricht,
 * Bijlage 2: uitkomsten per stembureau" from the
 * [Kiesregeling](https://wetten.overheid.nl/BWBR0034180/2024-04-01#Bijlage1_DivisieNa31.2) or
 * [Verkiezingstoolbox](https://www.rijksoverheid.nl/onderwerpen/verkiezingen/verkiezingentoolkit/modellen).
 */
export interface CSOFirstSessionResults {
  /** Counting Differences Polling Station ("B1-2 Verschillen met telresultaten van het stembureau") */
  counting_differences_polling_station: CountingDifferencesPollingStation;
  /** Differences counts ("3. Verschil tussen het aantal toegelaten kiezers en het aantal getelde stembiljetten") */
  differences_counts: DifferencesCounts;
  /** Extra investigation ("B1-1 Alleen bij extra onderzoek") */
  extra_investigation: ExtraInvestigation;
  /** Vote counts per list and candidate (5. "Aantal stemmen per lijst en kandidaat") */
  political_group_votes: PoliticalGroupCandidateVotes[];
  /** Voters counts ("1. Aantal toegelaten kiezers") */
  voters_counts: VotersCounts;
  /** Votes counts ("2. Aantal getelde stembiljetten") */
  votes_counts: VotesCounts;
}

/**
 * CSONextSessionResults, following the fields in Model Na 14-2 Bijlage 1.
 *
 * See "Model Na 14-2. Corrigendum bij het proces-verbaal van een gemeentelijk stembureau/
 * stembureau voor het openbaar lichaam, Bijlage 1: uitkomsten per stembureau" from the
 * [Kiesregeling](https://wetten.overheid.nl/BWBR0034180/2024-04-01#Bijlage1_DivisieNa14.2) or
 * [Verkiezingstoolbox](https://www.rijksoverheid.nl/onderwerpen/verkiezingen/verkiezingentoolkit/modellen).
 */
export interface CSONextSessionResults {
  /** Differences counts ("Verschil tussen het aantal toegelaten kiezers en het aantal getelde stembiljetten") */
  differences_counts: DifferencesCounts;
  /** Vote counts per list and candidate ("Aantal stemmen per lijst en kandidaat") */
  political_group_votes: PoliticalGroupCandidateVotes[];
  /** Voters counts ("Aantal toegelaten kiezers") */
  voters_counts: VotersCounts;
  /** Votes counts ("Aantal getelde stembiljetten") */
  votes_counts: VotesCounts;
}

/**
 * Candidate
 */
export interface Candidate {
  country_code?: string;
  first_name?: string;
  gender?: CandidateGender;
  initials: string;
  last_name: string;
  last_name_prefix?: string;
  locality: string;
  number: number;
}

/**
 * Candidate gender
 */
export type CandidateGender = "Male" | "Female" | "X";

export interface CandidateVotes {
  number: number;
  votes: number;
}

/**
 * Response structure for getting data entry of polling station results
 */
export interface ClaimDataEntryResponse {
  client_state: unknown;
  data: PollingStationResults;
  previous_results?: CommonPollingStationResults;
  validation_results: ValidationResults;
}

/**
 * Committee session
 */
export interface CommitteeSession {
  election_id: number;
  id: number;
  location: string;
  number: number;
  number_of_voters: number;
  overview_pdf?: number;
  results_eml?: number;
  results_pdf?: number;
  start_date_time?: string;
  status: CommitteeSessionStatus;
}

export interface CommitteeSessionDetails {
  session_election_id: number;
  session_id: number;
  session_location: string;
  session_number: number;
  session_number_of_voters: number;
  session_overview_pdf?: number;
  session_results_eml?: number;
  session_results_pdf?: number;
  session_start_date_time?: string | null;
  session_status: string;
}

/**
 * Committee session number of voters change request
 */
export interface CommitteeSessionNumberOfVotersChangeRequest {
  number_of_voters: number;
}

/**
 * Committee session status
 */
export type CommitteeSessionStatus =
  | "created"
  | "data_entry_not_started"
  | "data_entry_in_progress"
  | "data_entry_paused"
  | "data_entry_finished";

/**
 * Committee session status change request
 */
export interface CommitteeSessionStatusChangeRequest {
  status: CommitteeSessionStatus;
}

/**
 * Committee session update request
 */
export interface CommitteeSessionUpdateRequest {
  location: string;
  start_date: string;
  start_time: string;
}

/**
 * CommonPollingStationResults contains the common fields for polling station results,
 */
export interface CommonPollingStationResults {
  /** Differences counts ("Verschil tussen het aantal toegelaten kiezers en het aantal getelde stembiljetten") */
  differences_counts: DifferencesCounts;
  /** Vote counts per list and candidate ("Aantal stemmen per lijst en kandidaat") */
  political_group_votes: PoliticalGroupCandidateVotes[];
  /** Voters counts ("Aantal toegelaten kiezers") */
  voters_counts: VotersCounts;
  /** Votes counts ("Aantal getelde stembiljetten") */
  votes_counts: VotesCounts;
}

/**
 * Counting Differences Polling Station,
 * part of the polling station results ("B1-2 Verschillen met telresultaten van het stembureau")
 */
export interface CountingDifferencesPollingStation {
  /** Whether there was a difference between the total votes per list as determined by the polling station and by the typist
("Is er een verschil tussen het totaal aantal getelde stembiljetten per lijst zoals eerder vastgesteld door het stembureau en zoals door u geteld op het gemeentelijk stembureau?") */
  difference_ballots_per_list: YesNo;
  /** Whether there was an unexplained difference between the number of voters and votes
("Was er in de telresultaten van het stembureau een onverklaard verschil tussen het totaal aantal getelde stembiljetten en het aantal toegelaten kiezers?") */
  unexplained_difference_ballots_voters: YesNo;
}

/**
 * Struct used to create a new user
 */
export interface CreateUserRequest {
  fullname?: string;
  role: Role;
  temp_password: string;
  username: string;
}

export interface Credentials {
  password: string;
  username: string;
}

/**
 * Request structure for saving data entry of polling station results
 */
export interface DataEntry {
  /** Client state for the data entry (arbitrary JSON) */
  client_state: unknown;
  /** Data entry for a polling station */
  data: PollingStationResults;
  /** Data entry progress between 0 and 100 */
  progress: number;
}

export interface DataEntryDetails {
  committee_session_id: number;
  data_entry_progress: string;
  data_entry_status: string;
  finished_at?: string | null;
  first_entry_user_id?: number | null;
  polling_station_id: number;
  second_entry_user_id?: number | null;
}

export interface DataEntryGetDifferencesResponse {
  first_entry: PollingStationResults;
  first_entry_user_id: number;
  second_entry: PollingStationResults;
  second_entry_user_id: number;
}

export interface DataEntryGetResponse {
  data: PollingStationResults;
  status: DataEntryStatusName;
  user_id?: number;
  validation_results: ValidationResults;
}

export type DataEntryStatusName =
  | "first_entry_not_started"
  | "first_entry_in_progress"
  | "first_entry_has_errors"
  | "second_entry_not_started"
  | "second_entry_in_progress"
  | "entries_different"
  | "definitive";

export interface DataEntryStatusResponse {
  status: DataEntryStatusName;
}

/**
 * Compare votes cast admitted voters, part of the differences counts.
 */
export interface DifferenceCountsCompareVotesCastAdmittedVoters {
  /** Whether total of admitted voters and total of votes cast match.
("D en H zijn gelijk") */
  admitted_voters_equal_votes_cast: boolean;
  /** Whether total of admitted voters is greater than total of votes cast match.
("H is groter dan D (meer uitgebrachte stemmen dan toegelaten kiezers)") */
  votes_cast_greater_than_admitted_voters: boolean;
  /** Whether total of admitted voters is less than total of votes cast match.
("H is kleiner dan D (minder uitgebrachte stemmen dan toegelaten kiezers)") */
  votes_cast_smaller_than_admitted_voters: boolean;
}

/**
 * Differences counts, part of the polling station results.
 * (B1-3.3 "Verschillen tussen aantal kiezers en uitgebrachte stemmen")
 */
export interface DifferencesCounts {
  /** Whether total of admitted voters and total of votes cast match.
(B1-3.3.1 "Vergelijk D (totaal toegelaten kiezers) en H (totaal uitgebrachte stemmen)") */
  compare_votes_cast_admitted_voters: DifferenceCountsCompareVotesCastAdmittedVoters;
  /** Whether the difference between the total of admitted voters and total of votes cast is explained.
(B1-3.3.2 "Zijn er tijdens de stemming dingen opgeschreven die het verschil tussen D en H volledig verklaren?") */
  difference_completely_accounted_for: YesNo;
  /** Number of fewer counted ballots ("Aantal minder getelde stemmen (bereken: D min H)") */
  fewer_ballots_count: number;
  /** Number of more counted ballots ("Aantal méér getelde stemmen (bereken: H min D)") */
  more_ballots_count: number;
}

/**
 * Election without political groups
 */
export interface Election {
  category: ElectionCategory;
  counting_method: VoteCountingMethod;
  domain_id: string;
  election_date: string;
  election_id: string;
  id: number;
  location: string;
  name: string;
  nomination_date: string;
  number_of_seats: number;
}

export interface ElectionAndCandidateDefinitionValidateRequest {
  candidate_data?: string | null;
  candidate_hash?: string[];
  counting_method?: VoteCountingMethod;
  election_data: string;
  election_hash?: string[];
  number_of_voters?: number;
  polling_station_data?: string;
  polling_station_file_name?: string;
}

export interface ElectionAndCandidatesDefinitionImportRequest {
  candidate_data: string;
  candidate_hash: string[];
  counting_method: VoteCountingMethod;
  election_data: string;
  election_hash: string[];
  number_of_voters: number;
  polling_station_data?: string;
  polling_station_file_name?: string;
}

/**
 * Election category (limited for now)
 */
export type ElectionCategory = "Municipal";

export interface ElectionDefinitionValidateResponse {
  election: NewElection;
  hash: RedactedEmlHash;
  number_of_voters: number;
  polling_station_definition_matches_election?: boolean;
  polling_stations?: PollingStationRequest[];
}

export interface ElectionDetails {
  election_category: string;
  election_counting_method: string;
  election_domain_id: string;
  election_election_date: string;
  election_election_id: string;
  election_id: number;
  election_location: string;
  election_name: string;
  election_nomination_date: string;
  election_number_of_seats: number;
}

/**
 * Election details response, including the election's candidate list (political groups),
 * its polling stations and its committee sessions and current committee session
 */
export interface ElectionDetailsResponse {
  committee_sessions: CommitteeSession[];
  current_committee_session: CommitteeSession;
  election: ElectionWithPoliticalGroups;
  investigations: PollingStationInvestigation[];
  polling_stations: PollingStation[];
}

/**
 * Election list response
 *
 * Also includes a list of the current committee session for each election.
 * Does not include the candidate list (political groups) to keep the response size small.
 */
export interface ElectionListResponse {
  committee_sessions: CommitteeSession[];
  elections: Election[];
}

/**
 * Election polling stations data entry statuses response
 */
export interface ElectionStatusResponse {
  statuses: ElectionStatusResponseEntry[];
}

/**
 * Election polling stations data entry statuses response
 */
export interface ElectionStatusResponseEntry {
  /** Whether the finalised first or second data entry has warnings */
  finalised_with_warnings?: boolean;
  /** Time when the data entry was finalised */
  finished_at?: string;
  /** First entry progress as a percentage (0 to 100) */
  first_entry_progress?: number;
  /** First entry user id */
  first_entry_user_id?: number;
  /** Polling station id */
  polling_station_id: number;
  /** Second entry progress as a percentage (0 to 100) */
  second_entry_progress?: number;
  /** Second entry user id */
  second_entry_user_id?: number;
  /** Data entry status */
  status: DataEntryStatusName;
}

/**
 * Election with political groups
 */
export interface ElectionWithPoliticalGroups {
  category: ElectionCategory;
  counting_method: VoteCountingMethod;
  domain_id: string;
  election_date: string;
  election_id: string;
  id: number;
  location: string;
  name: string;
  nomination_date: string;
  number_of_seats: number;
  political_groups: PoliticalGroup[];
}

export interface ErrorDetails {
  level: AuditEventLevel;
  path: string;
  reference: ErrorReference;
}

/**
 * Error reference used to show the corresponding error message to the end-user
 */
export type ErrorReference =
  | "AirgapViolation"
  | "AlreadyInitialised"
  | "CommitteeSessionPaused"
  | "DatabaseError"
  | "DataEntryAlreadyClaimed"
  | "DataEntryAlreadyFinalised"
  | "DataEntryCannotBeDeleted"
  | "DataEntryGetNotAllowed"
  | "DataEntryNotAllowed"
  | "EmlImportError"
  | "EntryNotFound"
  | "EntryNotUnique"
  | "Forbidden"
  | "InternalServerError"
  | "InvalidCommitteeSessionStatus"
  | "InvalidData"
  | "InvalidHash"
  | "InvalidJson"
  | "InvalidPassword"
  | "InvalidPoliticalGroup"
  | "InvalidSession"
  | "InvalidStateTransition"
  | "InvalidUsernameOrPassword"
  | "InvalidVoteCandidate"
  | "InvalidVoteGroup"
  | "InvalidXml"
  | "InvestigationHasDataEntryOrResult"
  | "InvestigationRequiresCorrectedResults"
  | "NotInitialised"
  | "OwnAccountCannotBeDeleted"
  | "PasswordRejection"
  | "PdfGenerationError"
  | "PollingStationCannotBeDeleted"
  | "PollingStationRepeated"
  | "PollingStationValidationErrors"
  | "RequestPayloadTooLarge"
  | "Unauthorized"
  | "UsernameNotUnique"
  | "UserNotFound";

/**
 * Response structure for errors
 */
export interface ErrorResponse {
  error: string;
  fatal: boolean;
  reference: ErrorReference;
}

/**
 * Extra investigation, part of the polling station results ("B1-1 Alleen bij extra onderzoek")
 */
export interface ExtraInvestigation {
  /** Whether ballots were (partially) recounted following the extra investigation
("Zijn de stembiljetten naar aanleiding van het extra onderzoek (gedeeltelijk) herteld?") */
  ballots_recounted_extra_investigation: YesNo;
  /** Whether extra investigation was done for another reason than an unexplained difference
("Heeft het gemeentelijk stembureau extra onderzoek gedaan vanwege een andere reden dan een onverklaard verschil?") */
  extra_investigation_other_reason: YesNo;
}

export interface FileDetails {
  file_created_at: string;
  file_id: number;
  file_mime_type: string;
  file_name: string;
  file_size_bytes: number;
}

/**
 * Abacus API and asset server
 */
export interface GenerateElectionArgs {
  candidate_distribution_slope: RandomRange;
  /** Number of candidates to create */
  candidates_per_group: RandomRange;
  /** Percentage of the first data entry to complete if data entry is included */
  first_data_entry: RandomRange;
  political_group_distribution_slope: RandomRange;
  /** Number of political groups to create */
  political_groups: RandomRange;
  /** Number of polling stations to create */
  polling_stations: RandomRange;
  /** Number of seats in the election */
  seats: RandomRange;
  /** Percentage of the completed first data entries that also get a second data entry */
  second_data_entry: RandomRange;
  /** Percentage of voters that voted (given we generate data entries) */
  turnout: RandomRange;
  /** Number of voters to create */
  voters: RandomRange;
  /** Include (part of) data entry for this election */
  with_data_entry: boolean;
}

/**
 * Investigation list response
 */
export interface InvestigationListResponse {
  investigations: PollingStationInvestigation[];
}

export interface LoginResponse {
  fullname?: string;
  needs_password_change: boolean;
  role: Role;
  user_id: number;
  username: string;
}

/**
 * Election request
 */
export interface NewElection {
  category: ElectionCategory;
  counting_method: VoteCountingMethod;
  domain_id: string;
  election_date: string;
  election_id: string;
  location: string;
  name: string;
  nomination_date: string;
  number_of_seats: number;
  political_groups: PoliticalGroup[];
}

/**
 * Political group with its candidates
 */
export interface PoliticalGroup {
  candidates: Candidate[];
  name: string;
  number: number;
}

export interface PoliticalGroupCandidateVotes {
  candidate_votes: CandidateVotes[];
  number: number;
  total: number;
}

export interface PoliticalGroupTotalVotes {
  number: number;
  total: number;
}

/**
 * Polling station of a certain [crate::election::Election]
 */
export interface PollingStation {
  address: string;
  committee_session_id: number;
  election_id: number;
  id: number;
  id_prev_session?: number;
  locality: string;
  name: string;
  number: number;
  number_of_voters?: number;
  polling_station_type?: PollingStationType;
  postal_code: string;
}

export interface PollingStationDetails {
  polling_station_address: string;
  polling_station_committee_session_id: number;
  polling_station_election_id: number;
  polling_station_id: number;
  polling_station_id_prev_session?: number;
  polling_station_locality: string;
  polling_station_name: string;
  polling_station_number: number;
  polling_station_number_of_voters?: number;
  polling_station_postal_code: string;
  polling_station_type?: string;
}

export interface PollingStationFileRequest {
  data: string;
}

export interface PollingStationImportDetails {
  import_election_id: number;
  import_file_name: string;
  import_number_of_polling_stations: number;
}

export interface PollingStationInvestigation {
  corrected_results?: boolean;
  findings?: string;
  polling_station_id: number;
  reason: string;
}

export interface PollingStationInvestigationConcludeRequest {
  corrected_results: boolean;
  findings: string;
}

export interface PollingStationInvestigationCreateRequest {
  reason: string;
}

export interface PollingStationInvestigationUpdateRequest {
  accept_data_entry_deletion?: boolean;
  corrected_results?: boolean;
  findings?: string;
  reason: string;
}

/**
 * Polling station list response
 */
export interface PollingStationListResponse {
  polling_stations: PollingStation[];
}

/**
 * Polling station of a certain [crate::election::Election]
 */
export interface PollingStationRequest {
  address: string;
  locality: string;
  name: string;
  number?: number;
  number_of_voters?: number;
  polling_station_type?: PollingStationType;
  postal_code: string;
}

export interface PollingStationRequestListResponse {
  polling_stations: PollingStationRequest[];
}

/**
 * PollingStationResults contains the results for a polling station.
 *
 * The exact type of results depends on the election counting method and
 * whether this is the first or any subsequent data entry session. Based on
 * this, any of four different models can apply
 */
export type PollingStationResults =
  | (CSOFirstSessionResults & { model: "CSOFirstSession" })
  | (CSONextSessionResults & { model: "CSONextSession" });

/**
 * Type of Polling station
 */
export type PollingStationType = "FixedLocation" | "Special" | "Mobile";

export interface PollingStationsRequest {
  file_name: string;
  polling_stations: string;
}

export type RandomRange = string;

export interface RedactedEmlHash {
  /** Array holding the hash chunks as text */
  chunks: string[];
  /** Indexes of chunks that will be empty, sorted */
  redacted_indexes: number[];
}

export type ResolveDifferencesAction = "keep_first_entry" | "keep_second_entry" | "discard_both_entries";

export type ResolveErrorsAction = "discard_first_entry" | "resume_first_entry";

export interface ResultDetails {
  committee_session_id: number;
  created_at: string;
  polling_station_id: number;
}

export type Role = "administrator" | "typist" | "coordinator";

/**
 * Response structure for saving data entry of polling station results
 */
export interface SaveDataEntryResponse {
  validation_results: ValidationResults;
}

export interface UpdateUserRequest {
  fullname?: string;
  temp_password?: string;
}

/**
 * User object, corresponds to a row in the users table
 */
export interface User {
  created_at: string;
  fullname?: string;
  id: number;
  last_activity_at?: string;
  role: Role;
  updated_at: string;
  username: string;
}

export interface UserDetails {
  fullname?: string;
  role: string;
  user_id: number;
  username: string;
}

export interface UserListResponse {
  users: User[];
}

export interface UserLoggedInDetails {
  logged_in_users_count: number;
  user_agent: string;
}

export interface UserLoggedOutDetails {
  session_duration: number;
}

export interface UserLoginFailedDetails {
  user_agent: string;
  username: string;
}

export interface ValidationResult {
  code: ValidationResultCode;
  context?: ValidationResultContext;
  fields: string[];
}

export type ValidationResultCode =
  | "F101"
  | "F102"
  | "F111"
  | "F112"
  | "F201"
  | "F202"
  | "F203"
  | "F301"
  | "F302"
  | "F303"
  | "F304"
  | "F305"
  | "F306"
  | "F307"
  | "F308"
  | "F309"
  | "F310"
  | "F401"
  | "F402"
  | "F403"
  | "W001"
  | "W201"
  | "W202"
  | "W203"
  | "W204";

export interface ValidationResultContext {
  political_group_number?: number;
}

export interface ValidationResults {
  errors: ValidationResult[];
  warnings: ValidationResult[];
}

export type VoteCountingMethod = "CSO" | "DSO";

/**
 * Voters counts, part of the polling station results.
 */
export interface VotersCounts {
  /** Number of valid poll cards ("Aantal geldige stempassen") */
  poll_card_count: number;
  /** Number of valid proxy certificates ("Aantal geldige volmachtbewijzen") */
  proxy_certificate_count: number;
  /** Total number of admitted voters ("Totaal aantal toegelaten kiezers") */
  total_admitted_voters_count: number;
}

/**
 * Votes counts, part of the polling station results.
 * Following the fields in Model CSO Na 31-2 Bijlage 1.
 */
export interface VotesCounts {
  /** Number of blank votes ("Blanco stembiljetten") */
  blank_votes_count: number;
  /** Number of invalid votes ("Ongeldige stembiljetten") */
  invalid_votes_count: number;
  /** Total votes per list */
  political_group_total_votes: PoliticalGroupTotalVotes[];
  /** Total number of valid votes on candidates
("Totaal stemmen op kandidaten") */
  total_votes_candidates_count: number;
  /** Total number of votes cast ("Totaal uitgebrachte stemmen") */
  total_votes_cast_count: number;
}

/**
 * Yes/No response structure for boolean questions with separate yes and no fields.
 */
export interface YesNo {
  no: boolean;
  yes: boolean;
}
