As per my understanding exposed filter works for this requirement. So maybe you can try combining contextual filter with exposed filter.
You can use the Views Filter Harmonizer module for that. Here is a quote about it (from its project page):
Views Filter Harmonizer solves an operational foible with the Views
module regarding filtering.
Normally, when a Views field has been assigned both an exposed filter
and a contextual filter, then both filters get applied to the View's
results set -- always. This is not configurable behaviour. It's
hard-coded.
As a consequence, contradictory search clauses easily occur, causing a
counter-intuitive user experience with some White Screens of
Disillusionment. Since the contextual filter sets the "bounds" for the
page, any filtering by the visitor through the exposed filter on that
page can only narrow down the results set, not broaden it. In other
words the exposed filter appears not to be working properly.
This small module allows you to have a contextual filter argument
apply only when there is no corresponding regular (exposed) filter
value present.
This is most common on initial page load. After that the contextual
filters will silently retreat and let the exposed filter values as
selected by the visitor do their thing without interfering.
This means that you can take advantage of friendly URLs using
contextual arguments instead of ugly and verbose query parameters. Put
the URLs anywhere on your site, in emails and in newsletters to take
visitors to tailored Views pages. Having arrived there, visitors may
then further filter these pages to their heart's content using the
View's regular filters you exposed. And they won't experience any odd
behaviour.