public function message($type, array $replacements = [])
    {
        if (empty($type)) {
            throw new \Exception('Missing message type');
        }

        $crud = $this->_crud();

        $config = $this->getConfig('messages.' . $type);
        if (empty($config)) {
            $config = $crud->getConfig('messages.' . $type);
            if (empty($config)) {
                throw new \Exception(sprintf('Invalid message type "%s"', $type));
            }
        }

        if (is_string($config)) {
            $config = ['text' => $config];
        }

        $config = Hash::merge([
            'element' => 'default',
            'params' => ['class' => 'message'],
            'key' => 'flash',
            'type' => $this->getConfig('action') . '.' . $type,
            'name' => $this->resourceName()
        ], $config);

        if (!isset($config['text'])) {
            throw new \Exception(sprintf('Invalid message config for "%s" no text key found', $type));
        }

        $config['params']['original'] = ucfirst(str_replace('{name}', $config['name'], $config['text']));

        $domain = $this->getConfig('messages.domain');
        if (!$domain) {
            $domain = $crud->getConfig('messages.domain') ?: 'crud';
        }

        $config['text'] = __d($domain, $config['params']['original']);

        $config['text'] = Text::insert(
            $config['text'],
            $replacements + ['name' => $config['name']],
            ['before' => '{', 'after' => '}']
        );

        $config['params']['class'] .= ' ' . $type;

        return $config;
    }