use super::library::ShowLibraryItem;
use crate::ui::Message;
use crate::ui::shared::cover::{
    COVER_HEIGHT, COVER_WIDTH, cover_placeholder, cover_with_watched_badge, media_card,
    watched_toggle_button,
};
use crate::ui::shared::media_grid::media_grid;
use crate::ui::shared::styles::{self, GRAY_50, GRAY_60, GRAY_80};
use iced::Element;
use std::path::PathBuf;

const SEASON_COVER_WIDTH: f32 = 150.0;
const SEASON_COVER_HEIGHT: f32 = 225.0;

pub(crate) struct SeasonItem {
    pub(crate) id: i64,
    pub(crate) season_number: i64,
    pub(crate) title: Option<String>,
    pub(crate) cover_path: Option<PathBuf>,
    pub(crate) description: Option<String>,
    pub(crate) rating: Option<f64>,
    pub(crate) watched: bool,
}

pub(crate) fn view<'a>(
    show: &'a ShowLibraryItem,
    seasons: &'a [SeasonItem],
    tmdb_widget: Option<Element<'a, Message>>,
) -> Element<'a, Message> {
    let cover_w = COVER_WIDTH;
    let cover_h = COVER_HEIGHT;
    let s_cover_w = SEASON_COVER_WIDTH;
    let s_cover_h = SEASON_COVER_HEIGHT;

    let year_str = show.release_year.map(|y| y.to_string()).unwrap_or_default();

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

    let cover = styles::cover_with_border_shadow(cover_image);

    let title = iced::widget::text(&show.title)
        .size(styles::TEXT_SIZE_TITLE)
        .color(iced::Color::WHITE);

    let seasons_title = iced::widget::text("Seasons")
        .size(styles::TEXT_SIZE_SUBSECTION)
        .color(iced::Color::WHITE);

    let seasons_grid: Element<_> = media_grid(
        seasons.len(),
        s_cover_w,
        move |idx| {
            let season = &seasons[idx];
            let label_text = season
                .title
                .clone()
                .unwrap_or_else(|| format!("Season {}", season.season_number));

            let season_cover: Element<_> = if let Some(path) = &season.cover_path {
                iced::widget::image(iced::widget::image::Handle::from_path(path))
                    .width(s_cover_w)
                    .height(s_cover_h)
                    .into()
            } else {
                iced::widget::container(
                    iced::widget::text(format!("S{}", season.season_number))
                        .size(styles::TEXT_SIZE_SUBSECTION)
                        .color(GRAY_50),
                )
                .width(s_cover_w)
                .height(s_cover_h)
                .center_x(s_cover_w)
                .center_y(s_cover_h)
                .style(styles::placeholder_style)
                .into()
            };

            let season_cover =
                cover_with_watched_badge(season_cover, season.watched, s_cover_w, s_cover_h);

            let label = iced::widget::text(label_text)
                .size(styles::CARD_LABEL_SIZE)
                .color(GRAY_80)
                .wrapping(iced::widget::text::Wrapping::WordOrGlyph);

            media_card(
                season_cover,
                label.into(),
                iced::Length::Fill,
                Message::ShowSeasonDetail(season.id),
            )
        },
        None,
    );

    let has_backdrop = show.backdrop_path.is_some();
    let (year_color, season_count_color) = if has_backdrop {
        (GRAY_80, GRAY_60)
    } else {
        (GRAY_60, GRAY_50)
    };

    let mut info = iced::widget::column![title].spacing(styles::SPACING_DEFAULT);

    if !year_str.is_empty() {
        info = info.push(
            iced::widget::text(year_str)
                .size(styles::TEXT_SIZE_BODY)
                .color(year_color),
        );
    }

    if let Some(rd) = styles::rating_and_description(show.rating, show.description.as_deref()) {
        info = info.push(rd);
    }

    info = info.push(
        iced::widget::text(format!("{} season(s)", seasons.len()))
            .size(styles::CARD_LABEL_SIZE)
            .color(season_count_color),
    );

    info = info
        .push(iced::widget::Space::new().height(8))
        .push(watched_toggle_button(
            show.watched,
            Message::ToggleShowWatched,
        ));

    let mut extras: Vec<Element<Message>> = Vec::new();
    if let Some(widget) = tmdb_widget {
        extras.push(widget);
    }
    extras.push(seasons_title.into());
    extras.push(seasons_grid);

    styles::detail_layout(cover, info.into(), extras, show.backdrop_path.as_deref())
}
