export interface WlanConfRaw {
  _id: string;
  name?: string;
  ssid?: string;
  x_passphrase?: string;
  [key: string]: unknown;
}

export interface WlanConf {
  id: string;
  name: string;
  siteId: string;
  enabled: boolean;
  security: string;
  wpaMode: string;
  wpaEnc: string;
  wpa3Support: boolean;
  wpa3Transition: boolean;
  wpa3FastRoaming: boolean;
  wpa3Enhanced192: boolean;
  passphrase: string | null;
  passphraseAutogenerated: boolean;
  hideSSID: boolean;
  isGuest: boolean;
  band: string;
  bands: string[];
  networkconfId: string;
  usergroupId: string;
  apGroupIds: string[];
  apGroupMode: string;
  pmfMode: string;
  groupRekey: number;
  dtimMode: string;
  dtimNg: number;
  dtimNa: number;
  dtim6e: number;
  l2Isolation: boolean;
  fastRoamingEnabled: boolean;
  bssTransition: boolean;
  uapsdEnabled: boolean;
  iappEnabled: boolean;
  proxyArp: boolean;
  mcastenhanceEnabled: boolean;
  macFilterEnabled: boolean;
  macFilterPolicy: string;
  macFilterList: string[];
  radiusDasEnabled: boolean;
  radiusMacAuthEnabled: boolean;
  radiusMacaclFormat: string;
  minrateSettingPreference: string;
  minrateNgEnabled: boolean;
  minrateNgDataRateKbps: number;
  minrateNgAdvertisingRates: boolean;
  minrateNaEnabled: boolean;
  minrateNaDataRateKbps: number;
  minrateNaAdvertisingRates: boolean;
  settingPreference: string;
  no2ghzOui: boolean;
  privatePreSharedKeysEnabled: boolean;
  privatePreSharedKeys: unknown[];
  saeGroups: unknown[];
  saePsk: unknown[];
  schedule: unknown[];
  scheduleWithDuration: unknown[];
  bcFilterList: unknown[];
  externalId: string | null;
}

export interface WlanConfUpdate {
  name?: string;
  x_passphrase?: string;
  enabled?: boolean;
  security?: "wpapsk" | "wpaeap" | "open" | "osen";
  wpa_mode?: "wpa2" | "wpa3" | "wpa2wpa3";
  wpa_enc?: "ccmp" | "gcmp" | "ccmp-gcmp";
  hide_ssid?: boolean;
  mac_filter_enabled?: boolean;
  mac_filter_policy?: "allow" | "deny";
  is_guest?: boolean;
  l2_isolation?: boolean;
  fast_roaming_enabled?: boolean;
  bss_transition?: boolean;
  uapsd_enabled?: boolean;
  group_rekey?: number;
  dtim_mode?: "default" | "custom";
  dtim_ng?: number;
  dtim_na?: number;
  minrate_ng_enabled?: boolean;
  minrate_na_enabled?: boolean;
  radius_das_enabled?: boolean;
  radius_mac_auth_enabled?: boolean;
  pmf_mode?: "disabled" | "optional" | "required";
  wlan_band?: "both" | "2g" | "5g";
  usergroup_id?: string;
  proxy_arp?: boolean;
  mcastenhance_enabled?: boolean;
  mac_filter_list?: string[];
  no2ghz_oui?: boolean;
  ap_group_ids?: string[];
  ap_group_mode?: string;
}

/**
 * CamelCase update input matching the WlanConf return shape.
 * Accepted by the API and converted to WlanConfUpdate (snake_case) before
 * being sent to the UniFi controller.
 */
export interface WlanConfUpdateInput {
  name?: string;
  passphrase?: string;
  enabled?: boolean;
  security?: "wpapsk" | "wpaeap" | "open" | "osen";
  wpaMode?: "wpa2" | "wpa3" | "wpa2wpa3";
  wpaEnc?: "ccmp" | "gcmp" | "ccmp-gcmp";
  hideSSID?: boolean;
  macFilterEnabled?: boolean;
  macFilterPolicy?: "allow" | "deny";
  isGuest?: boolean;
  l2Isolation?: boolean;
  fastRoamingEnabled?: boolean;
  bssTransition?: boolean;
  uapsdEnabled?: boolean;
  groupRekey?: number;
  dtimMode?: "default" | "custom";
  dtimNg?: number;
  dtimNa?: number;
  minrateNgEnabled?: boolean;
  minrateNaEnabled?: boolean;
  radiusDasEnabled?: boolean;
  radiusMacAuthEnabled?: boolean;
  pmfMode?: "disabled" | "optional" | "required";
  band?: "both" | "2g" | "5g";
  usergroupId?: string;
  proxyArp?: boolean;
  mcastenhanceEnabled?: boolean;
  macFilterList?: string[];
  no2ghzOui?: boolean;
  apGroupIds?: string[];
  apGroupMode?: string;
}

/**
 * Converts a camelCase WlanConfUpdateInput to the snake_case WlanConfUpdate
 * expected by the UniFi controller API.
 */
export function toWlanConfUpdate(input: WlanConfUpdateInput): WlanConfUpdate {
  const result: WlanConfUpdate = {};

  if (input.name !== undefined) result.name = input.name;
  if (input.passphrase !== undefined) result.x_passphrase = input.passphrase;
  if (input.enabled !== undefined) result.enabled = input.enabled;
  if (input.security !== undefined) result.security = input.security;
  if (input.wpaMode !== undefined) result.wpa_mode = input.wpaMode;
  if (input.wpaEnc !== undefined) result.wpa_enc = input.wpaEnc;
  if (input.hideSSID !== undefined) result.hide_ssid = input.hideSSID;
  if (input.macFilterEnabled !== undefined)
    result.mac_filter_enabled = input.macFilterEnabled;
  if (input.macFilterPolicy !== undefined)
    result.mac_filter_policy = input.macFilterPolicy;
  if (input.isGuest !== undefined) result.is_guest = input.isGuest;
  if (input.l2Isolation !== undefined) result.l2_isolation = input.l2Isolation;
  if (input.fastRoamingEnabled !== undefined)
    result.fast_roaming_enabled = input.fastRoamingEnabled;
  if (input.bssTransition !== undefined)
    result.bss_transition = input.bssTransition;
  if (input.uapsdEnabled !== undefined)
    result.uapsd_enabled = input.uapsdEnabled;
  if (input.groupRekey !== undefined) result.group_rekey = input.groupRekey;
  if (input.dtimMode !== undefined) result.dtim_mode = input.dtimMode;
  if (input.dtimNg !== undefined) result.dtim_ng = input.dtimNg;
  if (input.dtimNa !== undefined) result.dtim_na = input.dtimNa;
  if (input.minrateNgEnabled !== undefined)
    result.minrate_ng_enabled = input.minrateNgEnabled;
  if (input.minrateNaEnabled !== undefined)
    result.minrate_na_enabled = input.minrateNaEnabled;
  if (input.radiusDasEnabled !== undefined)
    result.radius_das_enabled = input.radiusDasEnabled;
  if (input.radiusMacAuthEnabled !== undefined)
    result.radius_mac_auth_enabled = input.radiusMacAuthEnabled;
  if (input.pmfMode !== undefined) result.pmf_mode = input.pmfMode;
  if (input.band !== undefined) result.wlan_band = input.band;
  if (input.usergroupId !== undefined) result.usergroup_id = input.usergroupId;
  if (input.proxyArp !== undefined) result.proxy_arp = input.proxyArp;
  if (input.mcastenhanceEnabled !== undefined)
    result.mcastenhance_enabled = input.mcastenhanceEnabled;
  if (input.macFilterList !== undefined)
    result.mac_filter_list = input.macFilterList;
  if (input.no2ghzOui !== undefined) result.no2ghz_oui = input.no2ghzOui;
  if (input.apGroupIds !== undefined) result.ap_group_ids = input.apGroupIds;
  if (input.apGroupMode !== undefined) result.ap_group_mode = input.apGroupMode;

  return result;
}

// --- Site overview types ---

export interface SubsystemHealth {
  subsystem: "wlan" | "wan" | "www" | "lan" | "vpn";
  status: "ok" | "warn" | "error" | "unknown";
  numUser?: number;
  numGuest?: number;
  numIot?: number;
  txBytesR?: number;
  rxBytesR?: number;
  // WLAN-specific
  numAp?: number;
  // LAN-specific
  numSw?: number;
  // WAN-specific
  numGw?: number;
  // Shared device counts
  numAdopted?: number;
  numDisconnected?: number;
  numPending?: number;
  numDisabled?: number;
}

export interface SysInfo {
  name: string;
  hostname: string;
  version: string;
  build: string;
  timezone: string;
  uptime: number;
  ipAddresses: string[];
  updateAvailable: boolean;
  isCloudConsole: boolean;
  dataRetentionDays: number;
  informPort: number;
  httpsPort: number;
  unsupportedDeviceCount: number;
}

export interface SiteInfo {
  id: string;
  name: string;
  description: string;
  deviceCount: number;
  role: string;
}

export interface SiteOverview {
  site: SiteInfo;
  health: SubsystemHealth[];
  sysInfo: SysInfo;
}

// --- Device types ---

export type DeviceType = "uap" | "usw" | "ugw" | "uxg" | "ubb" | "udm";
export type DeviceState =
  | "connected"
  | "disconnected"
  | "pending"
  | "adopting"
  | "unknown";

export interface DeviceUplink {
  type?: string;
  mac?: string;
  ip?: string;
  uplinkRemotePort?: number;
  speed?: number;
  fullDuplex?: boolean;
}

export interface DeviceRadio {
  name: string;
  radio: string;
  channel: number;
  txPower: number;
  txPowerMode: string;
  minRssiEnabled: boolean;
  numSta: number;
  satisfaction: number | null;
}

export interface Device {
  id: string;
  mac: string;
  ip: string;
  name: string;
  model: string;
  shortname: string;
  type: DeviceType;
  version: string;
  serial: string;
  state: DeviceState;
  adopted: boolean;
  uptime: number;
  lastSeen: number;
  upgradable: boolean;
  satisfaction: number | null;
  numClients: number;
  numUserClients: number;
  numGuestClients: number;
  txBytes: number;
  rxBytes: number;
  uplink: DeviceUplink | null;
  radios: DeviceRadio[];
  modelInLts: boolean;
  modelInEol: boolean;
}

// --- Network types ---

export type NetworkPurpose =
  | "corporate"
  | "vlan-only"
  | "wan"
  | "vpn-client"
  | "remote-user-vpn"
  | "site-vpn";

export interface Network {
  id: string;
  name: string;
  purpose: NetworkPurpose;
  enabled: boolean;
  ipSubnet: string | null;
  vlan: number | null;
  vlanEnabled: boolean;
  isNat: boolean;
  domainName: string | null;
  networkGroup: string | null;
  dhcpdEnabled: boolean;
  dhcpdStart: string | null;
  dhcpdStop: string | null;
  dhcpdLeasetime: number | null;
  dhcpRelayEnabled: boolean;
  dhcpGuardEnabled: boolean;
  igmpSnooping: boolean;
  ipv6Enabled: boolean;
  ipv6InterfaceType: string | null;
  internetAccessEnabled: boolean | null;
}

// --- Site create types ---

export interface CreateSiteOptions {
  /** Human-readable description / display name for the site */
  description: string;
}

// --- Site list types ---

export interface SiteListItem {
  id: string;
  name: string;
  description: string;
  deviceCount: number;
  role: string;
}

// --- WLAN Group types ---

export interface WlanGroup {
  id: string;
  name: string;
  siteId: string;
  noDelete: boolean;
  noEdit: boolean;
  hidden: boolean;
}

export interface WlanGroupCreateInput {
  name: string;
}

// --- AP Group types ---

export interface ApGroup {
  id: string;
  name: string;
  deviceMacs: string[];
  noDelete: boolean;
  forWlanconf: boolean;
}

// --- User Group (Speed Profile) types ---

export interface UserGroup {
  id: string;
  name: string;
  siteId: string;
  noDelete: boolean;
  /** Download rate limit in Kbps. -1 means unlimited. */
  downloadLimitKbps: number;
  /** Upload rate limit in Kbps. -1 means unlimited. */
  uploadLimitKbps: number;
}

export interface UserGroupCreateInput {
  name: string;
  /** Download rate limit in Kbps. -1 or omit for unlimited. */
  downloadLimitKbps?: number;
  /** Upload rate limit in Kbps. -1 or omit for unlimited. */
  uploadLimitKbps?: number;
}

// --- Private PSK types ---

export interface PrivatePSK {
  key: string;
  name: string;
  mac: string | null;
  vlanId: number | null;
}

export interface PrivatePSKCreateInput {
  key: string;
  name: string;
  mac?: string;
  vlanId?: number;
}

// --- WiFi Limit types ---

export interface ApRadioWifiUsage {
  radio: string;
  band: string;
  activeWlans: number;
  limit: number;
  remaining: number;
  wlanNames: string[];
}

export interface ApWifiLimits {
  apId: string;
  apName: string;
  mac: string;
  model: string;
  radios: ApRadioWifiUsage[];
}
