use crate::ui::Message;
use iced::Element;
use iced::widget::{button, container};
use std::path::Path;

// ── Spacing scale (column/row .spacing()) ────────────────────────────
pub(crate) const SPACING_TIGHT: f32 = 4.0;
pub(crate) const SPACING_DEFAULT: f32 = 8.0;
pub(crate) const SPACING_MEDIUM: f32 = 12.0;
pub(crate) const SPACING_LARGE: f32 = 24.0;

// ── Padding scale (Padding::new) ──────────────────────────────────────
pub(crate) const PADDING_CARD: f32 = 4.0;
pub(crate) const PADDING_SMALL: f32 = 8.0;
pub(crate) const PADDING_STANDARD: f32 = 16.0;
pub(crate) const PADDING_LARGE: f32 = 32.0;

// ── Content text sizes (logical px; global zoom via application scale_factor) ─
pub(crate) const TEXT_SIZE_SMALL: f32 = 12.0;
pub(crate) const CARD_LABEL_SIZE: f32 = 14.0;
pub(crate) const TEXT_SIZE_BODY: f32 = 16.0;
pub(crate) const TEXT_SIZE_SECTION: f32 = 18.0;
pub(crate) const TEXT_SIZE_SUBSECTION: f32 = 20.0;
pub(crate) const TEXT_SIZE_TITLE: f32 = 28.0;

// ── Border radius ─────────────────────────────────────────────────────
pub(crate) const RADIUS_STANDARD: f32 = 4.0;

// ── Background colors ──────────────────────────────────────────────────
pub(crate) const BG_APP: iced::Color = iced::Color::from_rgb(0.08, 0.08, 0.08);
pub(crate) const BG_TAB_BAR: iced::Color = iced::Color::from_rgb(0.10, 0.10, 0.10);
pub(crate) const BG_BREADCRUMB: iced::Color = iced::Color::from_rgb(0.09, 0.09, 0.09);
pub(crate) const BG_CARD: iced::Color = iced::Color::from_rgb(0.12, 0.12, 0.12);
pub(crate) const BG_PLACEHOLDER: iced::Color = iced::Color::from_rgb(0.15, 0.15, 0.15);
pub(crate) const BG_CONTROL_BAR: iced::Color = iced::Color::from_rgb(0.12, 0.12, 0.12);
pub(crate) const BG_INPUT: iced::Color = iced::Color::from_rgb(0.18, 0.18, 0.18);
pub(crate) const BG_INPUT_INACTIVE: iced::Color = iced::Color::from_rgb(0.15, 0.15, 0.15);
pub(crate) const BG_HOVER: iced::Color = iced::Color::from_rgb(0.14, 0.14, 0.14);
pub(crate) const BG_LAST_PLAYED: iced::Color = iced::Color::from_rgb(0.2, 0.1, 0.1);
pub(crate) const BG_WATCHED_ROW: iced::Color = iced::Color::from_rgb(0.1, 0.18, 0.1);

// ── Gray scale (text & borders) ────────────────────────────────────────
pub(crate) const GRAY_20: iced::Color = iced::Color::from_rgb(0.2, 0.2, 0.2);
pub(crate) const GRAY_25: iced::Color = iced::Color::from_rgb(0.25, 0.25, 0.25);
pub(crate) const GRAY_30: iced::Color = iced::Color::from_rgb(0.3, 0.3, 0.3);
pub(crate) const GRAY_35: iced::Color = iced::Color::from_rgb(0.35, 0.35, 0.35);
pub(crate) const GRAY_40: iced::Color = iced::Color::from_rgb(0.4, 0.4, 0.4);
pub(crate) const GRAY_50: iced::Color = iced::Color::from_rgb(0.5, 0.5, 0.5);
pub(crate) const GRAY_60: iced::Color = iced::Color::from_rgb(0.6, 0.6, 0.6);
pub(crate) const GRAY_70: iced::Color = iced::Color::from_rgb(0.7, 0.7, 0.7);
pub(crate) const GRAY_80: iced::Color = iced::Color::from_rgb(0.8, 0.8, 0.8);
pub(crate) const GRAY_85: iced::Color = iced::Color::from_rgb(0.85, 0.85, 0.85);
pub(crate) const GRAY_90: iced::Color = iced::Color::from_rgb(0.9, 0.9, 0.9);

// ── Accent colors ──────────────────────────────────────────────────────
pub(crate) const ACCENT_RED: iced::Color = iced::Color::from_rgb(1.0, 0.0, 0.0);
pub(crate) const ACCENT_RED_HOVER: iced::Color = iced::Color::from_rgb(1.0, 0.2, 0.2);
pub(crate) const ACCENT_BLUE: iced::Color = iced::Color::from_rgb(0.2, 0.4, 0.8);
pub(crate) const ACCENT_BLUE_HOVER: iced::Color = iced::Color::from_rgb(0.3, 0.5, 0.9);
pub(crate) const ACCENT_GREEN: iced::Color = iced::Color::from_rgb(0.2, 0.4, 0.2);
pub(crate) const ACCENT_GREEN_HOVER: iced::Color = iced::Color::from_rgb(0.25, 0.5, 0.25);
pub(crate) const WATCHED_GREEN: iced::Color = iced::Color::from_rgb(0.2, 0.7, 0.3);
pub(crate) const WATCHED_GREEN_HOVER: iced::Color = iced::Color::from_rgb(0.15, 0.55, 0.25);
pub(crate) const RATING_GOLD: iced::Color = iced::Color::from_rgb(0.9, 0.75, 0.2);
pub(crate) const ACCENT_RED_SOFT: iced::Color = iced::Color::from_rgb(1.0, 0.4, 0.4);
pub(crate) const ERROR_RED: iced::Color = iced::Color::from_rgb(0.9, 0.3, 0.3);
pub(crate) const TEXT_SELECTION: iced::Color = iced::Color::from_rgb(0.3, 0.3, 0.5);
pub(crate) const OVERLAY_SCRIM: iced::Color = iced::Color::from_rgba(0.0, 0.0, 0.0, 0.75);

// ── Button styles ──────────────────────────────────────────────────────

/// Solid accent button with configurable hover color and corner radius.
pub(crate) fn solid_button_style(
    bg: iced::Color,
    hover: iced::Color,
    radius: f32,
) -> impl Fn(&iced::Theme, button::Status) -> button::Style {
    move |_theme, status| button::Style {
        background: Some(iced::Background::Color(match status {
            button::Status::Hovered => hover,
            _ => bg,
        })),
        text_color: iced::Color::WHITE,
        border: iced::border::rounded(radius),
        ..Default::default()
    }
}

/// Chrome-less text button: gray text that brightens on hover.
pub(crate) fn text_button_style(_theme: &iced::Theme, status: button::Status) -> button::Style {
    let text_color = match status {
        button::Status::Hovered => GRAY_70,
        _ => GRAY_50,
    };
    button::Style {
        background: None,
        text_color,
        ..Default::default()
    }
}

pub(crate) fn card_button_style(_theme: &iced::Theme, status: button::Status) -> button::Style {
    let bg = match status {
        button::Status::Hovered => BG_PLACEHOLDER,
        _ => iced::Color::TRANSPARENT,
    };
    button::Style {
        background: Some(iced::Background::Color(bg)),
        text_color: iced::Color::WHITE,
        border: iced::border::rounded(4),
        ..Default::default()
    }
}

pub(crate) fn play_button_style(theme: &iced::Theme, status: button::Status) -> button::Style {
    solid_button_style(ACCENT_RED, ACCENT_RED_HOVER, RADIUS_STANDARD)(theme, status)
}

pub(crate) fn play_button(msg: Message) -> Element<'static, Message> {
    iced::widget::button(
        iced::widget::text("Play")
            .size(12.0)
            .color(iced::Color::WHITE),
    )
    .on_press(msg)
    .padding(iced::Padding::from([4.0, 12.0]))
    .style(play_button_style)
    .into()
}

pub(crate) fn play_button_large(msg: Message) -> Element<'static, Message> {
    iced::widget::button(
        iced::widget::text("Play")
            .size(16.0)
            .color(iced::Color::WHITE),
    )
    .on_press(msg)
    .padding(iced::Padding::from([8.0, 24.0]))
    .style(solid_button_style(ACCENT_RED, ACCENT_RED_HOVER, 6.0))
    .into()
}

pub(crate) fn blue_button_style(theme: &iced::Theme, status: button::Status) -> button::Style {
    solid_button_style(ACCENT_BLUE, ACCENT_BLUE_HOVER, RADIUS_STANDARD)(theme, status)
}

pub(crate) fn green_button_style(theme: &iced::Theme, status: button::Status) -> button::Style {
    solid_button_style(ACCENT_GREEN, ACCENT_GREEN_HOVER, RADIUS_STANDARD)(theme, status)
}

pub(crate) fn tmdb_toggle_button_style(
    _theme: &iced::Theme,
    status: button::Status,
) -> button::Style {
    let bg = match status {
        button::Status::Hovered => GRAY_20,
        _ => BG_PLACEHOLDER,
    };
    button::Style {
        background: Some(iced::Background::Color(bg)),
        text_color: GRAY_70,
        border: iced::border::rounded(4),
        ..Default::default()
    }
}

// ── Container styles ───────────────────────────────────────────────────

pub(crate) fn cover_border_shadow_style(_theme: &iced::Theme) -> container::Style {
    container::Style {
        border: iced::Border {
            color: iced::Color::from_rgba(1.0, 1.0, 1.0, 0.15),
            width: 1.0,
            radius: 4.0.into(),
        },
        shadow: iced::Shadow {
            color: iced::Color::BLACK,
            offset: iced::Vector::new(0.0, 4.0),
            blur_radius: 16.0,
        },
        ..Default::default()
    }
}

pub(crate) fn result_row_style(_theme: &iced::Theme) -> container::Style {
    container::Style {
        background: Some(iced::Background::Color(BG_CARD)),
        border: iced::border::rounded(6),
        ..Default::default()
    }
}

pub(crate) fn placeholder_style(_theme: &iced::Theme) -> container::Style {
    container::Style {
        background: Some(iced::Background::Color(BG_PLACEHOLDER)),
        border: iced::border::rounded(4),
        ..Default::default()
    }
}

// ── Layout helpers ─────────────────────────────────────────────────────

pub(crate) fn cover_with_border_shadow<'a>(
    cover_image: Element<'a, Message>,
) -> Element<'a, Message> {
    iced::widget::container(cover_image)
        .style(cover_border_shadow_style)
        .into()
}

pub(crate) fn rating_and_description<'a>(
    rating: Option<f64>,
    description: Option<&'a str>,
) -> Option<Element<'a, Message>> {
    if rating.is_none() && description.is_none() {
        return None;
    }

    let mut col = iced::widget::column![].spacing(8);

    if let Some(r) = rating {
        col = col.push(
            iced::widget::text(format!("{:.1} / 10", r))
                .size(16.0)
                .color(RATING_GOLD),
        );
    }

    if let Some(desc) = description
        && !desc.is_empty()
    {
        col = col.push(
            iced::widget::text(desc)
                .size(14.0)
                .color(GRAY_70)
                .wrapping(iced::widget::text::Wrapping::WordOrGlyph)
                .width(600.0),
        );
    }

    Some(col.into())
}

pub(crate) fn detail_layout<'a>(
    cover: Element<'a, Message>,
    info: Element<'a, Message>,
    extras: Vec<Element<'a, Message>>,
    backdrop_path: Option<&Path>,
) -> Element<'a, Message> {
    let header: Element<'a, Message> = if backdrop_path.is_some() {
        iced::widget::row![cover, info]
            .spacing(SPACING_LARGE)
            .align_y(iced::Alignment::End)
            .into()
    } else {
        iced::widget::row![cover, info]
            .spacing(SPACING_LARGE)
            .into()
    };

    let mut content = iced::widget::column![header]
        .spacing(SPACING_LARGE)
        .padding(iced::Padding::new(PADDING_LARGE));
    for extra in extras {
        content = content.push(extra);
    }

    if let Some(path) = backdrop_path {
        backdrop_fullscreen(path, content.into())
    } else {
        iced::widget::scrollable(content)
            .width(iced::Length::Fill)
            .height(iced::Length::Fill)
            .into()
    }
}

pub(crate) fn backdrop_fullscreen<'a>(
    path: &Path,
    foreground: Element<'a, Message>,
) -> Element<'a, Message> {
    let image = iced::widget::image(iced::widget::image::Handle::from_path(path))
        .width(iced::Length::Fill)
        .height(iced::Length::Fill)
        .content_fit(iced::ContentFit::Cover);

    let gradient_overlay = iced::widget::container(iced::widget::Space::new())
        .width(iced::Length::Fill)
        .height(iced::Length::Fill)
        .style(|_theme| container::Style {
            background: Some(iced::Background::Gradient(iced::Gradient::Linear(
                iced::gradient::Linear::new(std::f32::consts::PI)
                    .add_stop(0.0, iced::Color::from_rgba(0.0, 0.0, 0.0, 0.5))
                    .add_stop(1.0, iced::Color::from_rgba(0.0, 0.0, 0.0, 0.7)),
            ))),
            ..Default::default()
        });

    let content_layer = iced::widget::container(foreground)
        .width(iced::Length::Fill)
        .height(iced::Length::Fill);

    iced::widget::stack![image, gradient_overlay, content_layer]
        .width(iced::Length::Fill)
        .height(iced::Length::Fill)
        .into()
}
