export type SightingType = {
  ref: number;
  SaFID: string;
  overviewUrl: string;
  plateUrlInfrared: string;
  plateUrlColour: string;
  vrm: string;
  vrmSecondary: string;
  countryCode: string;
  timeStamp: string;
  detailsUrl: string;
  overviewPlateRect?: [number, number, number, number];
  plateTrack?: [number, number, number, number][];
  make: string;
  model: string;
  color: string;
  category: string;
  charHeight: string;
  seenCount: string;
  timeStampMillis: number;
  motion: string;
  debug: string;
  srcCam: number;
  locationName: string;
  laneID: string;
  plateSize: string;
  overviewSize: string;
  radarSpeed: string;
  trackSpeed: string;
  metadata?: Metadata;
};

export type ReducedSightingType = {
  vrm: string;
  metadata?: Metadata;
};

export type CameraSettingValues = {
  friendlyName: string;
  cameraAddress: string;
  userName: string;
  password: string;
  id: number | string;
  mode: string;
};

export type CameraSettingErrorValues = Partial<Record<keyof CameraSettingValues, string>>;

export type BearerTypeFieldType = {
  format: string;
  enabled: boolean;
  verbose?: boolean;
};

export type InitialValuesForm = {
  format: string;
  backOfficeURL: string;
  username: string;
  password: string;
  connectTimeoutSeconds: number;
  readTimeoutSeconds: number;
  overviewQuality?: string;
  cropSizeFactor?: string;
};

export type InitialValuesFormErrors = {
  backOfficeURL?: string;
  username?: string;
  password?: string;
  connectTimeoutSeconds?: string;
  readTimeoutSeconds?: string;
};

export type OptionalBOF2Constants = {
  FFID?: string;
  SCID?: string;
  timestampSource?: string;
  GPSFormat?: string;
};

export type OptionalBOF2LaneIDs = {
  laneId?: string;
  LID1?: string;
  LID2?: string;
  LID3?: string;
};

export type NPEDFieldType = {
  frontId: string;
  username: string | undefined;
  password: string | undefined;
  clientId: string | undefined;
  rearId: string;
};

export type HotlistUploadType = {
  file: File | null;
};

export type VersionFieldType = {
  version: string;
  revision: string;
  buildtime: string;
  MAC: string;
  timeStamp: number;
  UUID: string;
  "Serial No.": string;
  "Model No.": string;
};

export type Metadata = {
  npedJSON: NpedJSON;
  "hotlist-matches": HotlistMatches;
  hotlistMatches: HotlistMatches;
};

export type HotlistMatches = {
  Hotlist0: boolean;
  Hotlist1: boolean;
  Hotlist2: boolean;
};

export type NpedJSON = {
  status_code: number;
  reason_phrase: string;
  "NPED CATEGORY": "A" | "B" | "C" | "D";
  "MOT STATUS": boolean;
  "TAX STATUS": boolean;
  vrm: string;
  "INSURANCE STATUS": string;
};

export type NPEDUser = {
  propUsername?: Prop;
  propClientID?: Prop;
  propPassword?: Prop;
};

export type NPEDErrorValues = {
  username?: string | undefined;
  password?: string | undefined;
  clientId?: string | undefined;
};

export type NPEDCameraConfig = {
  id: string;
  configHash: string;
  propEnabled: Prop;
  propUsername: Prop;
  propPassword: Prop;
  propClientID: Prop;
  propConnectTimeoutSeconds: Prop;
  propReadTimeoutSeconds: Prop;
  propNPEDAuthTokenURL: Prop;
  propNPEDLookupURL: Prop;
  propVerbose: Prop;
};

export interface Prop {
  value: string;
  datatype: string;
}

export type SystemValues = {
  deviceName: string;
  sntpServer: string;
  sntpInterval: number;
  timeZone: string;
  softwareUpdate?: File | null;
  serverPrimary?: string;
  serverSecondary?: string;
};

export type DNSSettingsType = {
  serverPrimary?: string;
  serverSecondary?: string;
};

export type SystemValuesErrors = {
  deviceName?: string | undefined;
  sntpServer?: string | undefined;
  sntpInterval?: string | undefined;
  timeZone?: string | undefined;
  softwareUpdate?: File | null;
};

export type AlertState = {
  alertList: SightingType[];
  allAlerts: SightingType[];
};

export type AlertPayload =
  | {
      payload: SightingType;
      type: "ADD";
    }
  | {
      payload: string;
      type: "SEARCH";
    }
  | {
      type: "REMOVE";
      payload: SightingType;
    }
  | {
      type: "DELETE";
      payload: [];
    };

export type ActionType = {
  payload: SightingType | string;
  type: string;
};

export type CameraConfig = {
  id: string;
  configHash: string;
  propURI: {
    value: string;
    datatype: "java.lang.String";
  };
  propMonochrome: {
    value: string; // "true" or "false" as string
    datatype: "boolean";
  };
  propControlProtocol: {
    value: "NONE" | "VISCA_KTNC" | "VISCA_WONWOO" | "DUMMY";
    datatype: "mav.cameracontrol.CameraController$CameraControlProtocol";
    accepted: "[NONE, VISCA_KTNC, VISCA_WONWOO, DUMMY]";
  };
  propAllowControlProtocolInference: {
    value: string;
    datatype: "boolean";
  };
  propCameraControlDeviceURI: {
    value: string;
    datatype: "java.lang.String";
  };
  propCameraControllerBaudRate: {
    value: string; // "115200" as string
    datatype: "int";
  };
  propLEDControllerType: {
    value: "None" | "Serial" | "I2C";
    datatype: "mav.flexi.modules.originators.video.LEDController$InterfaceType";
    accepted: "[None, Serial, I2C]";
  };
  propLEDDriverControlURI: {
    value: string;
    datatype: "java.lang.String";
  };
  propSourceIdentifier: {
    value: string;
    datatype: "java.lang.String";
  };
  propI2CLEDDriverSafeHex: {
    value: string;
    datatype: "java.lang.String";
  };
  propI2CLEDDriverLowHex: {
    value: string;
    datatype: "java.lang.String";
  };
  propI2CLEDDriverMidHex: {
    value: string;
    datatype: "java.lang.String";
  };
  propI2CLEDDriverHighHex: {
    value: string;
    datatype: "java.lang.String";
  };
  propRecordCameraControllerLogs: {
    value: string;
    datatype: "boolean";
  };
  propVideoFeedWatchdogEnabled: {
    value: string;
    datatype: "boolean";
  };
};

export type CameraBlackBoardOptions = {
  operation?: string;
  path?: string;
  value?: object | string | number | (string | number)[];
};

export type CameraBlackboardResponse = {
  data: object;
};

export type ZoomLevel = {
  left: number;
  top: number;
  x: number;
  y: number;
  px: number;
  py: number;
  level?: number;
};

export type SoundValue = string;

export type Hotlist = {
  name: string;
  sound: SoundValue;
};

export type FormValues = {
  sightingSound: SoundValue;
  NPEDsound: SoundValue;
  hotlists: Hotlist[];
  hotlistSound: SoundValue;
  soundOptions?: SoundUploadValue[];
};

export type SoundUploadValue = {
  name: string;
  soundFileName?: string;
  soundFile?: File | null;
  soundUrl?: string;
  uploadedAt?: number;
};

export type SoundState = {
  sightingSound: SoundValue;
  NPEDsound: SoundValue;
  hotlists: Hotlist[];
  hotlistSound: SoundValue;
  soundOptions?: SoundUploadValue[];
  sightingVolume: number;
  NPEDsoundVolume: number;
  hotlistSoundVolume: number;
  uploadedSound?: Blob | null;
};

type UpdateAction = {
  type: "UPDATE";
  payload: {
    sightingSound: SoundValue;
    NPEDsound: SoundValue;
    hotlists: Hotlist[];
    sightingVolume: number;
    NPEDsoundVolume: number;
    hotlistSoundVolume: number;
    hotlistSound: SoundValue;
    soundOptions?: SoundUploadValue[];
  };
};

type AddAction = {
  type: "ADD";
  payload: SoundUploadValue;
};

type VolumeAction = {
  type: "SIGHTINGVOLUME" | "NPEDVOLUME" | "HOTLISTVOLUME";
  payload: number;
};

type UploadedState = {
  type: "UPLOADEDSOUND";
  payload: Blob | undefined;
};

export type SoundAction = UpdateAction | AddAction | VolumeAction | UploadedState;
export type WifiSettingValues = {
  ssid: string;
  password: string;
  encryption: string;
};
export type ModemConfigPayload = {
  property: string;
  value: string;
};
export type WifiConfigPayload = {
  property: string;
  value: string;
};

export type WifiConfig = {
  id: string;
  fields: WifiConfigPayload[];
};

export type ModemConfig = {
  id: string;
  fields: ModemConfigPayload[];
};

export type ZoomInOptions = {
  camera: string;
  multiplier: number;
  multiplierText?: string;
};

export type zoomConfig = {
  camera: string;
};

export type ModemSettingsType = {
  apn: string;
  username: string;
  password: string;
  authenticationType: string;
};

export type HitKind = "NPED" | "HOTLIST";

export type QueuedHit = {
  id: number | string;
  sighting: SightingType;
  kind: HitKind;
};

export type DedupedSightings = ReducedSightingType[];

export type NPEDSTATE = {
  sessionStarted: boolean;
  sessionList: ReducedSightingType[];
  sessionPaused: boolean;
  savedSightings: DedupedSightings;
  npedUser: NPEDUser;
};

export type NPEDACTION = {
  type: string;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  payload: any;
};
