import type {
  NotificationDispatchStatus,
  NotificationProvider,
  NotificationProviderSendInput,
  NotificationProviderSendResult,
} from '../types';

export type NotificationDispatchExecutionInput = {
  provider: NotificationProvider;
  message: NotificationProviderSendInput;
  retryCount: number;
  maxRetryCount: number;
};

export type NotificationDispatchExecutionResult = {
  status: NotificationDispatchStatus;
  retryCount: number;
  sentAt: Date | null;
  providerResult: NotificationProviderSendResult | null;
  errorMessage: string | null;
  attemptedAt: Date;
};

function normalizeProviderError(error: unknown) {
  if (error instanceof Error) {
    return error.message.slice(0, 500);
  }

  return 'Unknown notification delivery error';
}

export async function executeNotificationDispatch(
  input: NotificationDispatchExecutionInput,
): Promise<NotificationDispatchExecutionResult> {
  const attemptedAt = new Date();

  try {
    await input.provider.validate();
    const providerResult = await input.provider.send(input.message);

    return {
      status: 'sent',
      retryCount: input.retryCount + 1,
      sentAt: attemptedAt,
      providerResult,
      errorMessage: null,
      attemptedAt,
    };
  } catch (error) {
    const retryCount = input.retryCount + 1;
    const shouldRetry = retryCount < input.maxRetryCount;

    return {
      status: shouldRetry ? 'retry' : 'failed',
      retryCount,
      sentAt: null,
      providerResult: null,
      errorMessage: normalizeProviderError(error),
      attemptedAt,
    };
  }
}
