/**
 * Tipos para eventos y respuestas de Asterisk Manager Interface (AMI)
 */

// ============================================================================
// Eventos Base de AMI
// ============================================================================

export interface BaseAmiEvent {
  event: string;
  privilege?: string;
  actionid?: string;
  [key: string]: unknown; // Permite propiedades adicionales
}

// ============================================================================
// Eventos de Estado de Peers
// ============================================================================

export interface PeerStatusEvent extends BaseAmiEvent {
  event: "PeerStatus";
  channeltype: "PJSIP" | "SIP";
  peer: string;
  peerstatus: "Registered" | "Unregistered" | "Reachable" | "Unreachable" | "Lagged" | "Unknown";
  address?: string;
  port?: string;
  cause?: string;
  time?: string;
}

// ============================================================================
// Eventos de Llamadas
// ============================================================================

export interface DialBeginEvent extends BaseAmiEvent {
  event: "DialBegin";
  channel: string;
  channelstate?: string;
  channelstatedesc?: string;
  calleridnum?: string;
  calleridname?: string;
  connectedlinenum?: string;
  connectedlinename?: string;
  destchannel?: string;
  destchannelstate?: string;
  destchannelstatedesc?: string;
  destcalleridnum?: string;
  destcalleridname?: string;
  destconnectedlinenum?: string;
  destconnectedlinename?: string;
  dialstring?: string;
  uniqueid?: string;
  destuniqueid?: string;
}

export interface DialEndEvent extends BaseAmiEvent {
  event: "DialEnd";
  channel: string;
  channelstate?: string;
  channelstatedesc?: string;
  calleridnum?: string;
  calleridname?: string;
  connectedlinenum?: string;
  connectedlinename?: string;
  destchannel?: string;
  destchannelstate?: string;
  destchannelstatedesc?: string;
  destcalleridnum?: string;
  destcalleridname?: string;
  dialstatus?: string;
  forward?: string;
  uniqueid?: string;
  destuniqueid?: string;
}

export interface HangupEvent extends BaseAmiEvent {
  event: "Hangup";
  channel: string;
  channelstate?: string;
  channelstatedesc?: string;
  calleridnum?: string;
  calleridname?: string;
  connectedlinenum?: string;
  connectedlinename?: string;
  cause?: string;
  causeTxt?: string;
  uniqueid?: string;
}

export interface BridgeEnterEvent extends BaseAmiEvent {
  event: "BridgeEnter";
  channel: string;
  bridgeuniqueid?: string;
  bridgetype?: string;
  bridgetechnology?: string;
  bridgecreator?: string;
  bridgename?: string;
  bridgenumchannels?: string;
  uniqueid?: string;
}

export interface HoldEvent extends BaseAmiEvent {
  event: "Hold" | "MusicOnHoldStart";
  channel: string;
  uniqueid?: string;
  musicclass?: string;
}

export interface UnholdEvent extends BaseAmiEvent {
  event: "Unhold" | "MusicOnHoldStop";
  channel: string;
  uniqueid?: string;
}

// ============================================================================
// Eventos de Endpoints PJSIP
// ============================================================================

export interface EndpointListEvent extends BaseAmiEvent {
  event: "EndpointList";
  objecttype?: string;
  objectname?: string;
  transport?: string;
  aors?: string;
  auths?: string;
  contacts?: string;
  devicestate?: string;
  activechannels?: string;
  identify?: string;
}

export interface EndpointDetailEvent extends BaseAmiEvent {
  event: "EndpointDetail";
  objecttype?: string;
  objectname?: string;
  context?: string;
  disallow?: string;
  allow?: string;
  dtmfmode?: string;
  rtptimeout?: string;
  rtpholdtimeout?: string;
  rtpkeepalive?: string;
  callerid?: string;
  CallerID?: string;
  mailboxes?: string;
  transport?: string;
  identify?: string;
  devicestate?: string;
  activechannels?: string;
}

export interface AorDetailEvent extends BaseAmiEvent {
  event: "AorDetail";
  objecttype?: string;
  objectname?: string;
  ObjectName?: string;
  Aor?: string;
  aor?: string;
  contacts?: string;
  maxcontacts?: string;
  authenticatequalify?: string;
  qualifyfrequency?: string;
  qualifytimeout?: string;
  defaultexpiration?: string;
  maximumexpiration?: string;
  minimumexpiration?: string;
}

export interface ContactStatusDetailEvent extends BaseAmiEvent {
  event: "ContactStatusDetail";
  aor?: string;
  uri?: string;
  Uri?: string;
  contact?: string;
  Contact?: string;
  status?: string;
  roundtripusec?: string;
  endpointname?: string;
  useragent?: string;
  UserAgent?: string;
  Useragent?: string;
  "User-Agent"?: string;
  regexpire?: string;
  viaaddress?: string;
  callid?: string;
  qualifyfrequency?: string;
  qualifytimeout?: string;
}

export interface EndpointDetailCompleteEvent extends BaseAmiEvent {
  event: "EndpointDetailComplete";
  endpoint?: string;
  listItems?: string;
}

export interface ContactStatusDetailCompleteEvent extends BaseAmiEvent {
  event: "ContactStatusDetailComplete";
  listItems?: string;
}

// ============================================================================
// Respuestas de Acciones AMI
// ============================================================================

export interface AmiActionResponse {
  response?: string;
  message?: string;
  actionid?: string;
  [key: string]: unknown;
}

export interface AmiActionResult<T = unknown> {
  success: boolean;
  data?: T;
  error?: string;
}

// ============================================================================
// Datos de Endpoints
// ============================================================================

export interface EndpointData {
  objectname: string;
  devicestate: string;
  aors?: string;
  contacts?: string;
  transport?: string;
  activechannels?: string;
}

export interface EndpointDetailsResponse {
  success: boolean;
  grouped?: {
    EndpointDetail?: EndpointDetailEvent[];
    AorDetail?: AorDetailEvent[];
    AuthDetail?: unknown[];
    TransportDetail?: unknown[];
  };
  contacts?: Record<string, ContactStatusDetailEvent[]>;
  error?: string;
}

export interface ContactInfo {
  uri: string;
  status: string;
  roundtripUsec?: number;
  roundtripMs?: number;
}

export interface EndpointLatencyData {
  latencyMs?: number;
  status: string;
}

// ============================================================================
// Eventos de Estado de Conexión
// ============================================================================

export interface AmiStatusEvent extends BaseAmiEvent {
  event: "AmiConnected" | "AmiDisconnected";
  connected?: boolean;
}

// ============================================================================
// Tipo Unión de Todos los Eventos
// ============================================================================

export type AmiEvent =
  | PeerStatusEvent
  | DialBeginEvent
  | DialEndEvent
  | HangupEvent
  | BridgeEnterEvent
  | HoldEvent
  | UnholdEvent
  | EndpointListEvent
  | EndpointDetailEvent
  | AorDetailEvent
  | ContactStatusDetailEvent
  | EndpointDetailCompleteEvent
  | ContactStatusDetailCompleteEvent
  | AmiStatusEvent
  | BaseAmiEvent;

// ============================================================================
// Helpers de Tipo
// ============================================================================

export function isDialBeginEvent(event: AmiEvent): event is DialBeginEvent {
  return event.event === "DialBegin";
}

export function isDialEndEvent(event: AmiEvent): event is DialEndEvent {
  return event.event === "DialEnd";
}

export function isHangupEvent(event: AmiEvent): event is HangupEvent {
  return event.event === "Hangup";
}

export function isBridgeEnterEvent(event: AmiEvent): event is BridgeEnterEvent {
  return event.event === "BridgeEnter";
}

export function isEndpointListEvent(event: AmiEvent): event is EndpointListEvent {
  return event.event === "EndpointList";
}

export function isPeerStatusEvent(event: AmiEvent): event is PeerStatusEvent {
  return event.event === "PeerStatus";
}
