export type CallNotificationKind = 'incoming' | 'active';

export type CallNotificationActionId = 'answer' | 'mute' | 'hangup';

export type CallNotificationActionIntent = 'answer' | 'toggle-mute' | 'hang-up';

export interface CallNotificationPayload {
  id: number;
  title: string;
  body: string;
  callId: string;
  kind: CallNotificationKind;
  actions?: { id: CallNotificationActionId; title: string }[];
}

const INCOMING_CALL_NOTIFICATION_BASE_ID = 1000;
const ACTIVE_CALL_NOTIFICATION_BASE_ID = 2000;

/** Build a local notification payload for an incoming direct call. */
export function buildIncomingCallNotification(displayName: string, callId: string): CallNotificationPayload {
  return {
    id: INCOMING_CALL_NOTIFICATION_BASE_ID + hashCallId(callId),
    title: 'Incoming call',
    body: `${displayName} is calling you`,
    callId,
    kind: 'incoming',
    actions: [{ id: 'answer', title: 'Answer' }, { id: 'hangup', title: 'Decline' }]
  };
}

/** Build a persistent in-call notification payload with quick actions. */
export function buildInCallNotification(input: {
  callId: string;
  displayName: string;
  isMuted: boolean;
}): CallNotificationPayload {
  return {
    id: ACTIVE_CALL_NOTIFICATION_BASE_ID + hashCallId(input.callId),
    title: input.displayName,
    body: input.isMuted ? 'Call in progress · muted' : 'Call in progress',
    callId: input.callId,
    kind: 'active',
    actions: [{ id: 'mute', title: input.isMuted ? 'Unmute' : 'Mute' }, { id: 'hangup', title: 'Hang up' }]
  };
}

/** Map a notification action button id to a call-control intent. */
export function resolveCallNotificationAction(actionId: string): CallNotificationActionIntent | null {
  switch (actionId) {
    case 'answer':
      return 'answer';
    case 'mute':
      return 'toggle-mute';
    case 'hangup':
      return 'hang-up';
    default:
      return null;
  }
}

function hashCallId(callId: string): number {
  let hash = 0;

  for (let index = 0; index < callId.length; index += 1) {
    hash = (hash * 31 + callId.charCodeAt(index)) % 997;
  }

  return hash;
}
