import { NotificationIface } from "../constants/app";

/**
 * Notification utility methods to reduce code duplication
 * and provide consistent notification patterns across the app
 */

export interface NotificationHelper {
  notify: (notification: NotificationIface, timeout?: number) => void;
  success: (text: string, timeout?: number) => void;
  error: (text: string, timeout?: number) => void;
  warning: (text: string, timeout?: number) => void;
  info: (text: string, timeout?: number) => void;
  toast: (title: string, text?: string, timeout?: number) => void;
  copied: (item: string, timeout?: number) => void;
  sent: (timeout?: number) => void;
  confirm: (text: string, onYes: () => Promise<void>, timeout?: number) => void;
  confirmationSubmitted: (timeout?: number) => void;
  alreadyConfirmed: (timeout?: number) => void;
  cannotConfirmIssuer: (timeout?: number) => void;
  cannotConfirmHidden: (timeout?: number) => void;
  notRegistered: (timeout?: number) => void;
  notAGive: (timeout?: number) => void;
}

/**
 * Standard notification timeouts
 */
export const NOTIFICATION_TIMEOUTS = {
  BRIEF: 1000, // Very brief toasts ("Sent..." messages)
  SHORT: 2000, // Short notifications (clipboard copies, quick confirmations)
  STANDARD: 3000, // Standard notifications (success messages, general info)
  LONG: 5000, // Longer notifications (errors, warnings, important info)
  VERY_LONG: 7000, // Very long notifications (complex operations)
  MODAL: -1, // Modal confirmations (no auto-dismiss)
} as const;

/**
 * Standard notification titles
 */
export const NOTIFICATION_TITLES = {
  SUCCESS: "Success",
  ERROR: "Error",
  WARNING: "Warning",
  INFO: "Info",
  COPIED: "Copied",
  SENT: "Sent...",
  CONFIRM: "Confirm",
  NOT_REGISTERED: "Not Registered",
  ALREADY_CONFIRMED: "Already Confirmed",
  CANNOT_CONFIRM: "Cannot Confirm",
} as const;

/**
 * Standard notification messages
 */
export const NOTIFICATION_MESSAGES = {
  GENERIC_ERROR: "Something went wrong.",
  GENERIC_SUCCESS: "Operation completed successfully.",
  CLIPBOARD_COPIED: (item: string) => `${item} was copied to the clipboard.`,
  SENT_BRIEF: "Sent...",
  CONFIRMATION_SUBMITTED: "Confirmation submitted.",
  ALREADY_CONFIRMED: "You already confirmed this claim.",
  CANNOT_CONFIRM_ISSUER:
    "You cannot confirm this because you issued this claim.",
  CANNOT_CONFIRM_HIDDEN:
    "You cannot confirm this because some people are hidden.",
  NOT_REGISTERED: "Someone needs to register you before you can confirm.",
  NOT_A_GIVE: "This is not a giving action to confirm.",
} as const;

/**
 * Creates a notification helper with utility methods
 */
export function createNotificationHelper(
  notifyFn: (notification: NotificationIface, timeout?: number) => void,
): NotificationHelper {
  return {
    notify: notifyFn,

    // Success notifications
    success: (text: string, timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
      notifyFn(
        {
          group: "alert",
          type: "success",
          title: NOTIFICATION_TITLES.SUCCESS,
          text,
        },
        timeout,
      );
    },

    // Error notifications
    error: (text: string, timeout = NOTIFICATION_TIMEOUTS.LONG) => {
      notifyFn(
        {
          group: "alert",
          type: "danger",
          title: NOTIFICATION_TITLES.ERROR,
          text,
        },
        timeout,
      );
    },

    // Warning notifications
    warning: (text: string, timeout = NOTIFICATION_TIMEOUTS.LONG) => {
      notifyFn(
        {
          group: "alert",
          type: "warning",
          title: NOTIFICATION_TITLES.WARNING,
          text,
        },
        timeout,
      );
    },

    // Info notifications
    info: (text: string, timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
      notifyFn(
        {
          group: "alert",
          type: "info",
          title: NOTIFICATION_TITLES.INFO,
          text,
        },
        timeout,
      );
    },

    // Toast notifications (brief)
    toast: (
      title: string,
      text?: string,
      timeout = NOTIFICATION_TIMEOUTS.BRIEF,
    ) => {
      notifyFn(
        {
          group: "alert",
          type: "toast",
          title,
          text,
        },
        timeout,
      );
    },

    // Clipboard copy notifications
    copied: (item: string, timeout = NOTIFICATION_TIMEOUTS.SHORT) => {
      notifyFn(
        {
          group: "alert",
          type: "toast",
          title: NOTIFICATION_TITLES.COPIED,
          text: NOTIFICATION_MESSAGES.CLIPBOARD_COPIED(item),
        },
        timeout,
      );
    },

    // Sent brief notification
    sent: (timeout = NOTIFICATION_TIMEOUTS.BRIEF) => {
      notifyFn(
        {
          group: "alert",
          type: "toast",
          title: NOTIFICATION_TITLES.SENT,
        },
        timeout,
      );
    },

    // Confirmation modal
    confirm: (
      text: string,
      onYes: () => Promise<void>,
      timeout = NOTIFICATION_TIMEOUTS.MODAL,
    ) => {
      notifyFn(
        {
          group: "modal",
          type: "confirm",
          title: NOTIFICATION_TITLES.CONFIRM,
          text,
          onYes,
        },
        timeout,
      );
    },

    // Standard confirmation messages
    confirmationSubmitted: (timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
      notifyFn(
        {
          group: "alert",
          type: "success",
          title: NOTIFICATION_TITLES.SUCCESS,
          text: NOTIFICATION_MESSAGES.CONFIRMATION_SUBMITTED,
        },
        timeout,
      );
    },

    alreadyConfirmed: (timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
      notifyFn(
        {
          group: "alert",
          type: "info",
          title: NOTIFICATION_TITLES.ALREADY_CONFIRMED,
          text: NOTIFICATION_MESSAGES.ALREADY_CONFIRMED,
        },
        timeout,
      );
    },

    cannotConfirmIssuer: (timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
      notifyFn(
        {
          group: "alert",
          type: "info",
          title: NOTIFICATION_TITLES.CANNOT_CONFIRM,
          text: NOTIFICATION_MESSAGES.CANNOT_CONFIRM_ISSUER,
        },
        timeout,
      );
    },

    cannotConfirmHidden: (timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
      notifyFn(
        {
          group: "alert",
          type: "info",
          title: NOTIFICATION_TITLES.CANNOT_CONFIRM,
          text: NOTIFICATION_MESSAGES.CANNOT_CONFIRM_HIDDEN,
        },
        timeout,
      );
    },

    notRegistered: (timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
      notifyFn(
        {
          group: "alert",
          type: "info",
          title: NOTIFICATION_TITLES.NOT_REGISTERED,
          text: NOTIFICATION_MESSAGES.NOT_REGISTERED,
        },
        timeout,
      );
    },

    notAGive: (timeout = NOTIFICATION_TIMEOUTS.STANDARD) => {
      notifyFn(
        {
          group: "alert",
          type: "info",
          title: NOTIFICATION_TITLES.INFO,
          text: NOTIFICATION_MESSAGES.NOT_A_GIVE,
        },
        timeout,
      );
    },
  };
}

/**
 * Vue mixin to add notification helpers to components
 */
export const NotificationMixin = {
  computed: {
    $notifyHelper() {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      return createNotificationHelper((this as any).$notify);
    },
  },
};
