import * as THREE from 'three';

export type TMovementSensor = 'I' | 'U' | 'D' | '?' | '';

export type TDoorPositions = '' | '?' | 'C' | 'O' | '-' | '+' | 'x';

export interface ILiftStatusRow {
  date_value: string;
  duration?: number;
  next_ts?: Date;
  next_val: string;
  pos: number;
  prev_duration?: number;
  prev_ts?: Date;
  prev_val: string;
  ts: Date;
  val: string;
  start?: number;
  end?: number;
  from_ts?: string;
  to_ts?: string;
}

export interface ILiftStatusSensor {
  id: string;
  type: string;
  name: string;
  internal: string;
  high_volume: string;
}

export interface ILiftStatusSensorResponse {
  rows: ILiftStatusRow[];
  sensor: ILiftStatusSensor;
}

export interface ILiftStatusAuth {
  tokenData: ITokenData;
  response: IAuthResponse;
  type: string;
}

export interface ITokenData {
  org: string;
  oid: string;
  otype: string;
  cmds: boolean;
  iat: number;
  exp: number;
  aud: string;
  iss: string;
  sub: string;
}

export interface IAuthResponse {
  es_number: string;
  capability: IAuthResponseCapability;
  permissions: IAuthResponsePermissions;
}

export interface IAuthResponseCapability {
  lift_controller: ILiftController;
}

export interface ILiftController {
  type: string;
}

export interface IAuthResponsePermissions {
  lift_flow: ILiftFlow;
  commands: boolean;
}

export interface ILiftFlow {
  data: ILiftFlowData;
}

export interface ILiftFlowData {
  realtime: boolean;
  statuses: boolean;
  counters: boolean;
  history: boolean;
}

export interface ILiftStatusValues {
  /** Sense module verbonden met SenseCloud, de verbinding tussen de Sense Module en SenseCloud. (1 is verbonden) */
  10?: boolean;

  /** Mobiele signaalsterkte, waarde in procenten */
  23?: number;

  // Unknown sensors
  25?: any;
  26?: any;

  /** Sturing verbinding met Sense module gezond (1 indien gezond) */
  50?: boolean;

  /** Rittenteller */
  100?: number;

  /** Installatie onbeschikbaar (1 indien onbeschikbaar) */
  103?: boolean;

  /** Sense visit actief */
  104?: boolean;

  /** Storing sensor */
  105?: boolean;

  /** Storing sensor buiten bezoek */
  106?: boolean;

  /** Noodstop verzamel */
  107?: boolean;

  /** Voeding installatie */
  108?: boolean;

  /** Energieverbruik teller */
  109?: number;

  /** Status reset contact */
  110?: boolean;

  /** Storingscontact */
  201?: boolean;

  /** Data storingsverzamelsensor met beschikbaarheidsimpact */
  210?: boolean;

  /** Data storingsverzamelsensor zonder beschikbaarheidsimpact */
  211?: boolean;

  /** Bewegingstoestand */
  500?: TMovementSensor;

  /** Huidige stopplaats (geopende deuren) */
  501?: number;

  /** Deur positie (status) - voor */
  502?: TDoorPositions;

  /** Deur positie (status) - achter */
  503?: TDoorPositions;

  // Unknown sensors
  505?: any;
  506?: any;

  /** Richtingveranderingenteller */
  507?: number;

  /** Deurcyclus teller - deur voor */
  508?: number;

  /** Deurcyclus teller - deur achter */
  509?: number;

  /** Deurcyclus teller per stopplaats - deur voor */
  510?: string; // TODO: this is a counter LIST, figure out what this sensor returns. we can prob do better than string

  /** Deurcyclus teller per stopplaats - deur achter */
  511?: string; // TODO: this is a counter LIST, figure out what this sensor returns. we can prob do better than string

  /** Stopplaatsteller */
  512?: string; // TODO: this is a counter LIST, figure out what this sensor returns. we can prob do better than string

  /** Statuscodes
   * Comma separated list of:
   * identifier:timestamp:status
   *
   * Where the identifier is the status code identifier,
   * timestamp is Unix timestamp in milliseconds and
   * status is 1 or 0 based on the status being active or not.
   */
  513?: string;

  /** Laatst gepasseerde stopplaats */
  514?: number;

  /** Huidige stopplaats */
  515?: number;

  /** Deurbeweging teller - deur voor */
  516?: number;

  /** Deurbeweging teller - deur achter */
  517?: number;

  /** Deurbeweging teller per stopplaats - deur voor */
  518?: string; // TODO: this is a counter LIST, figure out what this sensor returns. we can prob do better than string

  /** Deurbeweging teller per stopplaats - deur achter */
  519?: string; // TODO: this is a counter LIST, figure out what this sensor returns. we can prob do better than string

  /** Deur pendeling teller - deur voor */
  520?: number;

  /** Deur pendeling teller - deur achter */
  521?: number;

  /** Deur pendeling teller per stopplaats - deur voor */
  522?: string; // TODO: this is a counter LIST, figure out what this sensor returns. we can prob do better than string

  /** Deur pendeling teller per stopplaats - deur voor */
  523?: number; // TODO: this is a counter LIST, figure out what this sensor returns. we can prob do better than string

  // Unknown sensor
  524?: any;

  /** Na oproep geen reactie (Carcall request no response) */
  550?: boolean;

  /** Sturing informatie */
  590?: string;
}

export interface ILiftStatusUpdated {
  /** Sense module verbonden met SenseCloud, de verbinding tussen de Sense Module en SenseCloud. (1 is verbonden) */
  10?: number;

  /** Mobiele signaalsterkte, waarde in procenten */
  23?: number;

  // Unknown sensors
  25?: number;
  26?: number;

  /** Sturing verbinding met Sense module gezond (1 indien gezond) */
  50?: number;

  /** Rittenteller */
  100?: number;

  /** Installatie onbeschikbaar (1 indien onbeschikbaar) */
  103?: number;

  /** Sense visit actief */
  104?: number;

  /** Storing sensor */
  105?: number;

  /** Storing sensor buiten bezoek */
  106?: number;

  /** Noodstop verzamel */
  107?: number;

  /** Voeding installatie */
  108?: number;

  /** Energieverbruik teller */
  109?: number;

  /** Status reset contact */
  110?: number;

  /** Storingscontact */
  201?: number;

  /** Data storingsverzamelsensor met beschikbaarheidsimpact */
  210?: number;

  /** Data storingsverzamelsensor zonder beschikbaarheidsimpact */
  211?: number;

  /** Bewegingstoestand */
  500?: number;

  /** Huidige stopplaats (geopende deuren) */
  501?: number;

  /** Deur positie (status) - voor */
  502?: number;

  /** Deur positie (status) - achter */
  503?: number;

  // Unknown sensors
  505?: number;
  506?: number;

  /** Richtingveranderingenteller */
  507?: number;

  /** Deurcyclus teller - deur voor */
  508?: number;

  /** Deurcyclus teller - deur achter */
  509?: number;

  /** Deurcyclus teller per stopplaats - deur voor */
  510?: number;

  /** Deurcyclus teller per stopplaats - deur achter */
  511?: number;

  /** Stopplaatsteller */
  512?: number;

  /** Statuscodes
   * Comma separated list of:
   * identifier:timestamp:status
   *
   * Where the identifier is the status code identifier,
   * timestamp is Unix timestamp in milliseconds and
   * status is 1 or 0 based on the status being active or not.
   */
  513?: number;

  /** Laatst gepasseerde stopplaats */
  514?: number;

  /** Huidige stopplaats */
  515?: number;

  /** Deurbeweging teller - deur voor */
  516?: number;

  /** Deurbeweging teller - deur achter */
  517?: number;

  /** Deurbeweging teller per stopplaats - deur voor */
  518?: number;

  /** Deurbeweging teller per stopplaats - deur achter */
  519?: number;

  /** Deur pendeling teller - deur voor */
  520?: number;

  /** Deur pendeling teller - deur achter */
  521?: number;

  /** Deur pendeling teller per stopplaats - deur voor */
  522?: number;

  /** Deur pendeling teller per stopplaats - deur voor */
  523?: number;

  // Unknown sensor
  524?: number;

  /** Na oproep geen reactie (Carcall request no response) */
  550?: number;

  /** Sturing informatie */
  590?: number;
}

export interface ILiftStatusSensorDataResponse {
  lastUpdate: number;
  values: ILiftStatusValues;
  updated: ILiftStatusUpdated;
}

export interface ILiftStatusMessage {
  mid: string;
  f: string;
  data: ILiftStatusValues;
  ts: number;
  mc: number;
  rts: number;
}

export interface ILiftStatusModuleStatus {
  es: string;
  message: ILiftStatusMessage;
}

export interface IElevatorMaterials {
  active: THREE.MeshStandardMaterial;
  normal: THREE.MeshStandardMaterial;
  pulseOn: THREE.MeshStandardMaterial;
  pulseOff: THREE.MeshStandardMaterial;
  transparent: THREE.MeshStandardMaterial;
  floor: THREE.MeshStandardMaterial;
  door: THREE.MeshStandardMaterial;
}

export interface ITimePoint {
  name: string;
  x: Date;
  y: number;
  id: string;
  sensor: number;
  fake: boolean;
}

export type TLiftStatusWebComponentErrorType = '' | 'Socket' | 'API' | 'Token';

export interface ILiftStatusWebComponentError {
  message: string;
  type: TLiftStatusWebComponentErrorType;
}

// Changes to this type need to be reflected in isSeverity function
export type TSeverity = '' | 'impact' | 'informational' | 'non-impact';

export interface IStatusMessage {
  id: string;
  humanReadableTimestamp: string;
  relativeTimestamp: string;
  description: string;
  severity: TSeverity;
}

export interface IStatusCode {
  description: string;
  level: TSeverity;
}

/**
 * The ID type in the object ID claim. Can be internal, installation or external. Derived from the token.
 */
export type TObjectType = 'internal' | 'installation' | 'external';

export interface DatePicker {
  /**
   * The start date/time in ISO 8601 format
   */
  start: string;
  /**
   * The end date/time in ISO 8601 format
   */
  end: string;
}
