import type { IServiceCallResult } from '../../core/types.js';

export const adguardDefaultPort = 3000;
export const adguardDefaultTimeoutMs = 10000;

export type TAdguardJsonValue = string | number | boolean | null | TAdguardJsonValue[] | {
  [key: string]: TAdguardJsonValue | undefined;
};

export type TAdguardSnapshotSource = 'snapshot' | 'http' | 'manual' | 'runtime';

export type TAdguardHttpMethod = 'GET' | 'POST' | 'PUT';

export type TAdguardSwitchKey = 'protection' | 'filtering' | 'querylog' | 'safebrowsing' | 'safesearch' | 'parental';

export type TAdguardCommandType =
  | 'set_protection'
  | 'set_filtering'
  | 'set_querylog'
  | 'set_safebrowsing'
  | 'set_safesearch'
  | 'set_parental'
  | 'add_filter_url'
  | 'remove_filter_url'
  | 'set_filter_url_enabled'
  | 'refresh_filters'
  | 'begin_update';

export interface IAdguardServerStatus {
  dns_addresses?: string[];
  dns_port?: number;
  http_port?: number;
  protection_enabled?: boolean;
  protection_disabled_until?: string | null;
  protection_disabled_duration?: number;
  dhcp_available?: boolean;
  running?: boolean;
  version?: string;
  language?: string;
  start_time?: number;
  [key: string]: TAdguardJsonValue | undefined;
}

export interface IAdguardFilterSubscription {
  enabled?: boolean;
  id?: number;
  name?: string;
  rules_count?: number;
  url?: string;
  last_updated?: string;
  [key: string]: TAdguardJsonValue | undefined;
}

export interface IAdguardFilteringStatus {
  enabled?: boolean;
  interval?: number;
  filters?: IAdguardFilterSubscription[];
  whitelist_filters?: IAdguardFilterSubscription[];
  user_rules?: string[];
  [key: string]: TAdguardJsonValue | IAdguardFilterSubscription[] | string[] | undefined;
}

export interface IAdguardQueryLogConfig {
  enabled?: boolean;
  interval?: number;
  anonymize_client_ip?: boolean;
  ignored?: string[];
  ignored_enabled?: boolean;
  [key: string]: TAdguardJsonValue | string[] | undefined;
}

export interface IAdguardBooleanStatus {
  enabled?: boolean;
  enable?: boolean;
  sensitivity?: number;
  [key: string]: TAdguardJsonValue | undefined;
}

export interface IAdguardSafeSearchConfig {
  enabled?: boolean;
  bing?: boolean;
  duckduckgo?: boolean;
  ecosia?: boolean;
  google?: boolean;
  pixabay?: boolean;
  yandex?: boolean;
  youtube?: boolean;
  [key: string]: TAdguardJsonValue | undefined;
}

export interface IAdguardStats {
  time_units?: 'hours' | 'days' | string;
  num_dns_queries?: number;
  num_blocked_filtering?: number;
  num_replaced_safebrowsing?: number;
  num_replaced_safesearch?: number;
  num_replaced_parental?: number;
  avg_processing_time?: number;
  dns_queries?: number[];
  blocked_filtering?: number[];
  replaced_safebrowsing?: number[];
  replaced_parental?: number[];
  replaced_safesearch?: number[];
  [key: string]: TAdguardJsonValue | number[] | undefined;
}

export interface IAdguardVersionInfo {
  disabled?: boolean;
  new_version?: string;
  announcement?: string;
  announcement_url?: string;
  can_autoupdate?: boolean;
  [key: string]: TAdguardJsonValue | undefined;
}

export interface IAdguardSnapshot {
  online: boolean;
  status: IAdguardServerStatus;
  filtering: IAdguardFilteringStatus;
  queryLog: IAdguardQueryLogConfig;
  safebrowsing: IAdguardBooleanStatus;
  safesearch: IAdguardSafeSearchConfig;
  parental: IAdguardBooleanStatus;
  stats: IAdguardStats;
  update?: IAdguardVersionInfo;
  host?: string;
  port?: number;
  ssl?: boolean;
  basePath?: string;
  name?: string;
  uniqueId?: string;
  updatedAt?: string;
  source?: TAdguardSnapshotSource;
  error?: string;
}

export interface IAdguardClientCommand {
  type: TAdguardCommandType;
  service: string;
  method: TAdguardHttpMethod;
  path: string;
  payload?: Record<string, unknown>;
  target?: {
    entityId?: string;
    deviceId?: string;
  };
  entityId?: string;
  deviceId?: string;
  uniqueId?: string;
  switchKey?: TAdguardSwitchKey;
  enabled?: boolean;
  url?: string;
  name?: string;
  force?: boolean;
}

export interface IAdguardCommandResult extends IServiceCallResult {}

export type TAdguardCommandExecutor = (
  commandArg: IAdguardClientCommand
) => Promise<IAdguardCommandResult | unknown> | IAdguardCommandResult | unknown;

export interface IAdguardConfig {
  host?: string;
  port?: number;
  ssl?: boolean;
  verifySsl?: boolean;
  username?: string;
  password?: string;
  basePath?: string;
  name?: string;
  uniqueId?: string;
  timeoutMs?: number;
  snapshot?: IAdguardSnapshot;
  commandExecutor?: TAdguardCommandExecutor;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IAdguardManualEntry {
  host?: string;
  port?: number;
  ssl?: boolean;
  verifySsl?: boolean;
  basePath?: string;
  username?: string;
  password?: string;
  id?: string;
  name?: string;
  model?: string;
  manufacturer?: string;
  snapshot?: IAdguardSnapshot;
  metadata?: Record<string, unknown>;
  integrationDomain?: string;
  [key: string]: unknown;
}

export interface IHomeAssistantAdguardConfig extends IAdguardConfig {}
