// use ::tap::*;
//
// use std::{collections::BTreeMap, sync::Arc};
//
// use gpui::{
//     App, Application, Bounds, ClickEvent, Context, ImageId, ImageSource, RenderImage, Resource,
//     SharedString, Window, WindowBounds, WindowOptions, actions, div, prelude::*, px, rgb, size,
// };
//
// #[derive(Clone, Debug)]
// pub struct AppState {
//     pub title: SharedString,
//     pub items: BTreeMap<SharedString, Item>,
//     pub item_ids: BTreeMap<usize, SharedString>,
//     pub current_item: Option<SharedString>,
//     pub errors: Vec<String>,
//     pub jellyfin_client: api::JellyfinClient,
// }
//
// #[derive(Clone, Debug)]
// pub struct Item {
//     pub id: SharedString,
//     pub name: SharedString,
//     pub item_type: SharedString,
//     pub media_type: SharedString,
// }
//
// impl Render for AppState {
//     fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
//         div()
//             .flex()
//             .flex_col()
//             .size_full()
//             .justify_center()
//             .text_color(rgb(0xffffff))
//             .child(Self::header())
//             .child(Self::body(self, window, cx))
//             .child(Self::footer())
//     }
// }
//
// actions!(jello_actions, [OpenItem, OnLoadItem, MouseDownEvent]);
//
// impl AppState {
//     fn new(title: impl AsRef<str>, jellyfin_client: api::JellyfinClient) -> Self {
//         AppState {
//             title: SharedString::new(title.as_ref()),
//             items: BTreeMap::new(),
//             item_ids: BTreeMap::new(),
//             current_item: None,
//             errors: Vec::new(),
//             jellyfin_client,
//         }
//     }
//
//     // fn on_mouse_down(
//     //     &mut self,
//     //     event: &MouseDownEvent,
//     //     window: &mut Window,
//     //     cx: &mut Context<Self>,
//     // ) {
//     //     // Handle mouse down event
//     // }
//
//     fn load_item(id: usize) -> impl Fn(&mut Self, &ClickEvent, &mut Window, &mut Context<Self>) {
//         move |state: &mut Self, event: &ClickEvent, window: &mut Window, cx: &mut Context<Self>| {
//             let item_id = id;
//             cx.spawn(async move |entity, app| {
//                 tracing::info!("Loading item with id: {}", item_id);
//             });
//         }
//     }
//
//     fn hover_item(id: usize) -> impl Fn(&mut Self, &bool, &mut Window, &mut Context<Self>) {
//         move |state: &mut Self, item: &bool, window: &mut Window, cx: &mut Context<Self>| {
//             dbg!("Hovering over item: {:?}", id);
//         }
//     }
//
//     fn header() -> impl IntoElement {
//         div()
//             .flex()
//             .flex_row()
//             .w_full()
//             .justify_end()
//             .h_20()
//             .border_10()
//             .bg(rgb(0x333333))
//             .child(Self::button("Refresh"))
//     }
//
//     fn footer() -> impl IntoElement {
//         div().flex().flex_row().w_full().h_20().bg(rgb(0x333333))
//     }
//
//     fn body(&mut self, window: &mut Window, cx: &mut Context<AppState>) -> impl IntoElement {
//         div()
//             .flex()
//             .flex_row()
//             .size_full()
//             .child(Self::content(self, window, cx))
//             .child(Self::sidebar(self, window, cx))
//     }
//
//     fn button(label: &str) -> impl IntoElement {
//         div()
//             .flex()
//             .justify_center()
//             .items_center()
//             .bg(rgb(0xff00ff))
//             .text_color(rgb(0xffffff))
//             .border_5()
//             .rounded_lg()
//             .child(label.to_string())
//     }
//
//     fn content(&mut self, window: &mut Window, cx: &mut Context<AppState>) -> impl IntoElement {
//         div()
//             .debug_below()
//             .w_3_4()
//             // .flex()
//             // .flex_wrap()
//             .bg(rgb(0x111111))
//             .justify_start()
//             .items_start()
//             .overflow_hidden()
//             .child(
//                 div()
//                     .size_full()
//                     .flex()
//                     .flex_wrap()
//                     .justify_start()
//                     .items_start()
//                     .content_start()
//                     .gap_y_10()
//                     .gap_x_10()
//                     .border_t_10()
//                     .p_5()
//                     .child(Self::card(cx, 1))
//                     .child(Self::card(cx, 2))
//                     .child(Self::card(cx, 3))
//                     .child(Self::card(cx, 4))
//                     .child(Self::card(cx, 5))
//                     .child(Self::card(cx, 6))
//                     .child(Self::card(cx, 7))
//                     .child(Self::card(cx, 8))
//                     .child(Self::card(cx, 9)),
//             )
//     }
//
//     fn sidebar(&mut self, window: &mut Window, cx: &mut Context<AppState>) -> impl IntoElement {
//         div()
//             .flex()
//             .flex_col()
//             .w_1_4()
//             .min_w_1_6()
//             .bg(rgb(0x222222))
//             .child(div().size_full().bg(gpui::yellow()))
//     }
//
//     fn card(cx: &mut Context<AppState>, number: usize) -> impl IntoElement {
//         div()
//             .id(number)
//             .on_click(cx.listener(Self::load_item(number)))
//             .on_hover(cx.listener(Self::hover_item(number)))
//             .flex()
//             .flex_col()
//             .w_48()
//             .h_64()
//             .p_10()
//             .bg(rgb(0xff00ff))
//             .rounded_lg()
//     }
// }
//
// pub fn ui(jellyfin_client: api::JellyfinClient) {
//     Application::new().run(|cx: &mut App| {
//         let bounds = Bounds::centered(None, size(px(500.0), px(500.0)), cx);
//         cx.open_window(
//             WindowOptions {
//                 window_bounds: Some(WindowBounds::Windowed(bounds)),
//                 ..Default::default()
//             },
//             |_, cx| cx.new(|_| AppState::new("Jello Media Browser", jellyfin_client)),
//         )
//         .expect("Failed to open window");
//     })
// }
//
// #[derive(Clone, Debug)]
// pub struct Card {
//     pub id: usize,
//     pub title: SharedString,
//     pub description: SharedString,
//     pub image: SharedString,
//     pub image_blurhash: BlurHash,
//     pub media_type: SharedString,
//     pub loading: bool,
// }
//
// impl Render for Card {
//     fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
//         div()
//             .id(self.id)
//             .flex()
//             .flex_col()
//             .w_48()
//             .h_64()
//             .p_10()
//             .bg(rgb(0xff00ff))
//             .rounded_lg()
//             .pipe(|card| {
//                 if self.loading {
//                     card.child(self.image_blurhash.clone())
//                 } else {
//                     card.child(gpui::img(self.image.clone()))
//                 }
//             })
//     }
// }
//
// #[derive(Clone, Debug)]
// pub struct BlurHash {
//     pub id: ImageId,
//     pub data: Arc<RenderImage>,
// }
//
// impl BlurHash {
//     pub fn new(
//         data: impl AsRef<str>,
//         width: u32,
//         height: u32,
//         punch: f32,
//     ) -> Result<Self, error_stack::Report<crate::Error>> {
//         use error_stack::ResultExt;
//         let decoded =
//             blurhash::decode(data.as_ref(), width, height, punch).change_context(crate::Error)?;
//         let buffer = image::RgbaImage::from_raw(width, height, decoded)
//             .ok_or(crate::Error)
//             .attach("Failed to convert")?;
//         let frame = image::Frame::new(buffer);
//         let render_image = RenderImage::new([frame]);
//         Ok(Self {
//             id: render_image.id,
//             data: Arc::from(render_image),
//         })
//     }
// }
//
// impl Render for BlurHash {
//     fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
//         gpui::img(ImageSource::Render(self.data.clone()))
//     }
// }
//
// impl IntoElement for BlurHash {
//     type Element = gpui::Img;
//
//     fn into_element(self) -> Self::Element {
//         gpui::img(ImageSource::Render(self.data.clone()))
//     }
// }
