use std::{rc::Rc, time::Duration};

use druid::{
	widget::{Button, Container, Flex, Label, List, Maybe, Painter, SizedBox},
	BoxConstraints, Data, EventCtx, Lens, Size, Widget, WidgetExt,
};
use tf_db::Song;
use tf_player::player::state::Playing;

use super::{draw_icon_button, ICON_NEXT, ICON_PAUSE, ICON_PLAY, ICON_PREV};
use crate::{
	command, theme,
	widget::{overlay, player_bar::PlayerBar},
	State,
};

#[derive(Clone, Data, Lens)]
pub struct MediaBarState {
	pub playing: Rc<Playing>,
	pub current_song: Option<Rc<Song>>,
}

pub fn ui() -> impl Widget<MediaBarState> {
	let buttons = Flex::row()
		.with_child(prev_button())
		.with_default_spacer()
		.with_child(play_pause_button())
		.with_default_spacer()
		.with_child(next_button());

	let right_buttons = Flex::row()
		.with_flex_spacer(1.0)
		.with_child(Button::new("").on_click(
			move |ctx: &mut EventCtx, _: &mut MediaBarState, _| {
				ctx.submit_command(overlay::SHOW_MIDDLE.with((
					BoxConstraints::tight(Size::new(300.0, 300.0)),
					Box::new(move |env| {
						Box::new(
							Container::new(
								Flex::column()
									.with_child(
										Maybe::new(
											|| {
												Label::new(|data: &Rc<Song>, _: &_| {
													data.title.clone()
												})
											},
											|| SizedBox::empty(),
										)
										.lens(State::current_song),
									)
									.with_flex_child(
										List::new(|| {
											Label::new(|data: &Rc<Song>, _: &_| data.title.clone())
										})
										.lens(State::queue),
										1.0,
									),
							)
							.border(env.get(theme::FOREGROUND), 1.0),
						)
					}),
				)))
			},
		));

	let song_info = Maybe::new(
		|| Label::new(|data: &Rc<Song>, _: &_| data.title.clone()),
		|| SizedBox::empty(),
	)
	.expand_width();

	Flex::column()
		.with_child(
			Flex::row()
				.with_flex_child(song_info.lens(MediaBarState::current_song), 1.0)
				.with_child(buttons.lens(MediaBarState::playing))
				.with_flex_child(right_buttons, 1.0),
		)
		.with_child(
			Flex::row()
				.with_child(Label::new(|data: &Rc<Playing>, _: &_| {
					format_duration(&data.offset)
				}))
				.with_default_spacer()
				.with_flex_child(PlayerBar::default(), 1.0)
				.with_default_spacer()
				.with_child(Label::new(|data: &Rc<Playing>, _: &_| {
					format_duration(&data.song.duration)
				}))
				.lens(MediaBarState::playing),
		)
		.expand_width()
}

fn play_pause_button() -> impl Widget<Rc<Playing>> {
	Painter::new(|ctx, data: &Rc<Playing>, env| {
		draw_icon_button(ctx, env, if data.paused { ICON_PLAY } else { ICON_PAUSE })
	})
	.fix_size(36.0, 36.0)
	.on_click(|ctx: &mut EventCtx, _, _| {
		ctx.submit_command(command::PLAYER_PLAY_PAUSE);
	})
}

fn prev_button() -> impl Widget<Rc<Playing>> {
	Painter::new(|ctx, _, env| draw_icon_button(ctx, env, ICON_PREV))
		.fix_size(36.0, 36.0)
		.on_click(|ctx: &mut EventCtx, _, _| {
			ctx.submit_command(command::PLAYER_PREV);
		})
}

fn next_button() -> impl Widget<Rc<Playing>> {
	Painter::new(|ctx, _, env| draw_icon_button(ctx, env, ICON_NEXT))
		.fix_size(36.0, 36.0)
		.on_click(|ctx: &mut EventCtx, _, _| {
			ctx.submit_command(command::PLAYER_NEXT);
		})
}

fn format_duration(d: &Duration) -> String {
	format!("{:02}:{:02}", d.as_secs() / 60, d.as_secs() % 60)
}