use std::cell::RefCell;
use std::rc::Weak;

use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;

use crate::windows::surface::Surface as _;
use crate::windows::Window;

/// The single thing that currently holds input focus.
///
/// Every path that wants to focus something — a pointer/touch press, an
/// activation request, the task switcher, unminimize, an exclusive
/// layer-shell surface — names one of these and routes through
/// [`Windows::set_focus`](crate::windows::Windows::set_focus). Keyboard
/// focus and the xdg `Activated` state are both derived from it, so
/// "focused" and "has the keyboard" cannot drift apart.
#[derive(Clone, Debug)]
pub enum FocusTarget {
    Layout(Weak<RefCell<Window>>),
    Layer(WlSurface, Option<String>),
    X11(WlSurface),
}

impl FocusTarget {
    /// Resolve to the keyboard surface and app id, or `None` if the target
    /// no longer exists (its window was dropped).
    pub fn resolve(&self) -> Option<(WlSurface, Option<String>)> {
        match self {
            Self::Layout(weak) => weak.upgrade().map(|w| {
                let w = w.borrow();
                (w.surface.surface().clone(), w.app_id.clone())
            }),
            Self::Layer(surface, app_id) => Some((surface.clone(), app_id.clone())),
            Self::X11(surface) => Some((surface.clone(), None)),
        }
    }
}
