export type TNanoleafProtocol = 'http' | 'https';
export type TNanoleafColorMode = 'hs' | 'ct' | 'effect' | string;
export type TNanoleafGesture = 'swipe_up' | 'swipe_down' | 'swipe_left' | 'swipe_right';

export interface INanoleafConfig {
  host?: string;
  port?: number;
  protocol?: TNanoleafProtocol;
  authToken?: string;
  token?: string;
  controllerInfo?: INanoleafControllerInfo;
  state?: INanoleafState;
  effects?: INanoleafEffects;
  panelLayout?: INanoleafPanelLayout;
  rhythm?: INanoleafRhythmInfo;
  snapshot?: INanoleafSnapshot;
}

export interface INanoleafValue<TValue> {
  value: TValue;
  min?: number;
  max?: number;
}

export interface INanoleafState {
  on?: INanoleafValue<boolean>;
  brightness?: INanoleafValue<number>;
  hue?: INanoleafValue<number>;
  sat?: INanoleafValue<number>;
  ct?: INanoleafValue<number>;
  colorMode?: TNanoleafColorMode | INanoleafValue<TNanoleafColorMode>;
}

export interface INanoleafPanelInfo {
  panelId: number;
  x?: number;
  y?: number;
  o?: number;
  shapeType?: number;
}

export interface INanoleafPanelLayout {
  globalOrientation?: INanoleafValue<number>;
  layout?: {
    numPanels?: number;
    sideLength?: number;
    positionData?: INanoleafPanelInfo[];
  };
}

export interface INanoleafRhythmInfo {
  rhythmConnected?: boolean | INanoleafValue<boolean>;
  rhythmActive?: boolean | INanoleafValue<boolean>;
  rhythmId?: number | INanoleafValue<number>;
  hardwareVersion?: string | INanoleafValue<string>;
  firmwareVersion?: string | INanoleafValue<string>;
  auxAvailable?: boolean | INanoleafValue<boolean>;
  rhythmMode?: number | string | INanoleafValue<number | string>;
  rhythmPos?: number | INanoleafValue<number>;
}

export interface INanoleafEffects {
  select?: string;
  effectsList?: string[];
  write?: INanoleafEffectsCommand;
}

export interface INanoleafEffectPaletteColor {
  hue?: number;
  saturation?: number;
  brightness?: number;
  probability?: number;
}

export interface INanoleafEffectPluginOption {
  name: string;
  value?: string | number | boolean;
  type?: string;
  defaultValue?: string | number | boolean;
  minValue?: number;
  maxValue?: number;
  strings?: string[];
}

export interface INanoleafEffectsCommand {
  command: 'add' | 'request' | 'delete' | 'display' | 'displayTemp' | 'rename' | 'requestAll' | 'requestPlugins' | string;
  version?: string;
  duration?: number;
  animName?: string;
  newName?: string;
  animType?: string;
  animData?: string | null;
  colorType?: string;
  palette?: INanoleafEffectPaletteColor[];
  Palette?: INanoleafEffectPaletteColor[];
  pluginUuid?: string;
  pluginType?: string;
  pluginOptions?: INanoleafEffectPluginOption[];
  loop?: boolean;
  [key: string]: unknown;
}

export interface INanoleafStateCommand {
  on?: INanoleafValue<boolean>;
  brightness?: INanoleafValue<number> & { duration?: number; increment?: number };
  hue?: INanoleafValue<number> & { increment?: number };
  sat?: INanoleafValue<number> & { increment?: number };
  ct?: INanoleafValue<number> & { increment?: number };
}

export interface INanoleafControllerInfo {
  name?: string;
  serialNo?: string;
  manufacturer?: string;
  firmwareVersion?: string;
  hardwareVersion?: string;
  model?: string;
  state?: INanoleafState;
  effects?: INanoleafEffects;
  panelLayout?: INanoleafPanelLayout;
  rhythm?: INanoleafRhythmInfo;
}

export interface INanoleafSnapshot {
  controllerInfo: INanoleafControllerInfo;
  state: INanoleafState;
  effects: INanoleafEffects;
  panelLayout?: INanoleafPanelLayout;
  rhythm?: INanoleafRhythmInfo;
}

export interface INanoleafAuthTokenResult {
  success: boolean;
  authToken?: string;
  error?: string;
}

export interface INanoleafEvent<TData = unknown> {
  type: 'state' | 'effects' | 'layout' | 'touch' | string;
  data: TData;
  timestamp?: number;
}

export interface INanoleafStateEventData {
  attribute: keyof INanoleafState | string;
  value: unknown;
}

export interface INanoleafEffectsEventData {
  effect?: string;
  effectsList?: string[];
}

export interface INanoleafTouchEventData {
  panelId?: number;
  gestureId?: number;
  gesture?: TNanoleafGesture;
}

export interface INanoleafMdnsRecord {
  name?: string;
  type?: string;
  host?: string;
  port?: number;
  txt?: Record<string, string | undefined>;
}

export interface INanoleafSsdpRecord {
  st?: string;
  usn?: string;
  location?: string;
  headers?: Record<string, string | undefined>;
}

export interface INanoleafManualEntry {
  host?: string;
  port?: number;
  id?: string;
  name?: string;
  model?: string;
  manufacturer?: string;
  metadata?: Record<string, unknown>;
}

export type IHomeAssistantNanoleafConfig = INanoleafConfig;
