use super::Message as ShowMessage;
use crate::ui::Message;
use crate::ui::shared::cover::{
    COVER_HEIGHT, COVER_WIDTH, cover_placeholder, cover_with_watched_badge, media_card,
};
use crate::ui::shared::media_grid::{ScrollConfig, media_grid};
use crate::ui::shared::styles::{self, GRAY_50, GRAY_80};
use iced::Element;
use std::path::PathBuf;

pub(crate) const SHOW_LIBRARY_SCROLLABLE_ID: &str = "show-library-scroll";

pub(crate) struct ShowLibraryItem {
    pub(crate) id: i64,
    pub(crate) tmdb_id: Option<i64>,
    pub(crate) title: String,
    pub(crate) release_year: Option<i64>,
    pub(crate) cover_path: Option<PathBuf>,
    pub(crate) backdrop_path: Option<PathBuf>,
    pub(crate) description: Option<String>,
    pub(crate) rating: Option<f64>,
    pub(crate) watched: bool,
}

pub(crate) fn view<'a>(
    items: &'a [ShowLibraryItem],
    search_query: &str,
    scroll_offset: f32,
    viewport_height: f32,
    ui_scale: f32,
) -> Element<'a, Message> {
    let cover_w = COVER_WIDTH * ui_scale;
    let cover_h = COVER_HEIGHT * ui_scale;
    let row_h = cover_h + 20.0 * ui_scale + 12.0 + 8.0;

    let query_lower = search_query.to_lowercase();
    let filtered_indices: Vec<usize> = items
        .iter()
        .enumerate()
        .filter(|(_, item)| {
            query_lower.is_empty() || item.title.to_lowercase().contains(&query_lower)
        })
        .map(|(i, _)| i)
        .collect();

    let show_list: Element<_> = if filtered_indices.is_empty() {
        iced::widget::text("No TV shows found. Use --scan-shows <path> to add shows.")
            .color(GRAY_50)
            .into()
    } else {
        media_grid(
            filtered_indices.len(),
            cover_w,
            move |idx| {
                let original_idx = filtered_indices[idx];
                let item = &items[original_idx];
                let year_str = item
                    .release_year
                    .map(|y| format!("({})", y))
                    .unwrap_or_default();

                let cover_content: Element<_> = if let Some(path) = &item.cover_path {
                    iced::widget::image(iced::widget::image::Handle::from_path(path))
                        .width(cover_w)
                        .height(cover_h)
                        .into()
                } else {
                    cover_placeholder(&item.title, &year_str, cover_w, cover_h, ui_scale)
                };

                let cover_content = cover_with_watched_badge(
                    cover_content,
                    item.watched,
                    cover_w,
                    cover_h,
                    ui_scale,
                );

                let label = iced::widget::text(format!("{} {}", item.title, year_str))
                    .size(styles::CARD_LABEL_SIZE * ui_scale)
                    .color(GRAY_80)
                    .wrapping(iced::widget::text::Wrapping::WordOrGlyph);

                iced::widget::mouse_area(media_card(
                    cover_content,
                    label.into(),
                    iced::Length::Fill,
                    Message::ShowDetail(original_idx),
                ))
                .on_enter(Message::Show(ShowMessage::LibraryItemHover(Some(
                    original_idx,
                ))))
                .on_exit(Message::Show(ShowMessage::LibraryItemHover(None)))
                .into()
            },
            Some(ScrollConfig {
                scroll_offset,
                viewport_height,
                row_height: row_h,
                scrollable_id: SHOW_LIBRARY_SCROLLABLE_ID,
                on_scroll: |v| Message::Show(ShowMessage::LibraryScrolled(v)),
            }),
        )
    };

    iced::widget::column![show_list]
        .spacing(16)
        .padding(iced::Padding::new(styles::PADDING_STANDARD))
        .width(iced::Length::Fill)
        .height(iced::Length::Fill)
        .into()
}
