export type ActionHandler = (messageData: unknown) => void | Promise<void>;

export interface ActionHandlerService {
  registerHandler(actionType: string, handler: ActionHandler): void;
  unregisterHandler(actionType: string): void;
  handleAction(actionType: string | undefined | null, messageData: unknown): Promise<void>;
  getRegisteredActions(): string[];
}

export function useActionHandler(): ActionHandlerService {
  const handlers = new Map<string, ActionHandler>();

  const defaultHandler: ActionHandler = (messageData) => {
    const message = (messageData as { actionType?: string } | undefined) ?? {};
    const actionType = message.actionType || '';
    if (actionType) {
      console.warn(
        `[ActionHandler] Unknown action type received: "${actionType}". Message data:`,
        messageData
      );
    }
  };

  function registerHandler(actionType: string, handler: ActionHandler) {
    if (!actionType) {
      console.warn('[ActionHandler] Attempted to register handler with empty action type. Ignored.');
      return;
    }
    if (handlers.has(actionType)) {
      console.warn(
        `[ActionHandler] Handler for action type "${actionType}" already exists. Overwriting.`
      );
    }
    handlers.set(actionType, handler);
  }

  function unregisterHandler(actionType: string) {
    if (!actionType) return;
    handlers.delete(actionType);
  }

  async function handleAction(actionType: string | undefined | null, messageData: unknown) {
    if (!actionType || actionType === '') return;

    const handler = handlers.get(actionType);
    if (handler) {
      try {
        await handler(messageData);
      } catch (error) {
        console.error(
          `[ActionHandler] Error executing handler for action type "${actionType}":`,
          error
        );
      }
      return;
    }

    try {
      await Promise.resolve(defaultHandler(messageData));
    } catch (error) {
      console.error(
        `[ActionHandler] Error executing default handler for unknown action type "${actionType}":`,
        error
      );
    }
  }

  function getRegisteredActions() {
    return Array.from(handlers.keys());
  }

  return { registerHandler, unregisterHandler, handleAction, getRegisteredActions };
}
