A spatial acceleration structure should help you finding the closest lights, brute force is also a viable option depending on the number of lights you have in your DataBase.
If you write a deferred renderer you won't need to find the closest lights at all.
A directionnal light is a point light at infinity, ie like the sun or moon or star lights, so you will always consider it visible (unless in a cave or such).
Without light the lighting part of your shader won't trigger, no light means pure black unless you have some ambient light to avoid the issue, but sure your per light function won't be called, I don't really see a problem with that...
There are many shadow tech, shadow buffers (usually called shadow maps, even though maps are typically used for precomputed things and not runtime computed things) are a popular tech, and there are plenty of variations, I'd try straightforward shadow mapping (ie depth buffer) + Parallel Split Shadows for the sun/moon/stars.
You could write the code in a flexible enough manner so that it would work, just have your light bucket, in the forward case send it to whatever needs to be rendered so it can pick the lights it needs, for the deferred case just render them and compute lighting.
In both cases you'll need to store light information in an array, and probably branch on light type (actually you'd rather have 3 loops for 3 different light types), if you have an array of lights (or 3 arrays, one for each type) you can as well have an array of textures (your shadow buffers, 3 arrays again)...
So I don't really see any difficulty here. Just try to cull as many lights as possible to generate the least amount of shadow buffers (you'll only have a maximum of n of them anyway), to save on processing.
That's pretty much how I made my engine work with any rendering technique I may want to try or fancy, having a plugin rendering process and a list of ordered Step/Groups that change depend on the rendering tech I chose. (Which would be similar to your buckets)