use based::format::format_number;
use based::ui::components::Shell;
use based::ui::primitives::space::Fraction;
use based::ui::{prelude::*, AttrExtendable};
use based::{
    auth::MaybeUser,
    format::format_date,
    request::{RequestContext, StringResponse},
};
use maud::{html, PreEscaped, Render};
use rocket::{get, State};

use crate::check_private;
use crate::config::Config;
use crate::library::Video;
use crate::{
    library::{history::VideoHistory, Library},
    pages::components::video_element_wide,
};

use super::components::render_page;

#[get("/watch?<v>")]
pub async fn watch_page(
    ctx: RequestContext,
    library: &State<Library>,
    v: String,
    user: MaybeUser,
    conf: &State<Config>,
    shell: &State<Shell>,
) -> StringResponse {
    check_private!(conf, user, shell, ctx);

    let video = if let Some(video) = library.get_video_by_id(&v).await {
        video
    } else {
        // TODO : Error handling
        library.get_video_by_youtube_id(&v).await.unwrap()
    };

    if let Some(user) = user.user() {
        user.insert_history(video.id).await;
    }

    let youtube_meta = video.youtube_meta().await;
    let rec = build_rec(&library, &video).await;

    let content = Margin(
        Screen::large(Flex(Nothing()).direction(Direction::Row)).on(
        Flex(
          Div().vanish()
          .push(
              Screen::large(Width(Fraction::_10on12, Nothing())).on(
                Div().push(
                  Context(Aspect::Video(
                    Background(
                      Rounded(
                                  Width(ScreenValue::full, Video().controls().autoplay().width(1080).add_src(
                                    Source(&format!("/video/raw?v={}", video.id), Some("video/mp4".to_string()))
                                  ).poster(&format!("/video/thumbnail?v={}", video.id)))
                      ).size(Size::Large)
                    ).color(Colors::Black)
                  ))
                ).push(
                  Context(Margin(Padding(
                    Background(
                      Rounded(
                        Shadow::large(
                          Div()
                          .push(
                            Text(&video.title)._2xl().semibold()
                          )
                          .push_some(youtube_meta.as_ref(), |meta: &_| {
                            Div()
                            .push(
                              Context(Margin(Flex(
                                Div().vanish().push(
                                  Margin(Text(&meta.uploader_name).color(&Gray::_300).xl()).bottom(ScreenValue::_4)
                                ).push(
                                  Margin(Text(&format!("{} Views ﹣ {}", format_number(meta.views), format_date(&meta.upload_date))).color(&Gray::_300).xl()).bottom(ScreenValue::_4)
                                )
                              ).justify(Justify::Between).group()).top(ScreenValue::_2))
                            )
                            .push(
                              Context(Link(&format!("https://www.youtube.com/watch?v={}", meta.id),
                              Text("Watch on YouTube").color(&Red::_400))
                            )
                            ).push(
                              Context(Margin(
                                Text(meta.description.trim_ascii()).sm().color(&Gray::_300).wrap(TextWrap::Pretty).whitespace(TextWhitespace::BreakSpaces)
                              ).y(ScreenValue::_2).top(ScreenValue::_6)
                              ))
                          }
                        )
                      )).size(Size::Large)
                    ).color(Stone::_900)
                  ).all(ScreenValue::_4)).top(ScreenValue::_8))
                )
              )
          ).push(
            rec
          )
        ).direction(Direction::Column).gap(ScreenValue::_6))
      ).x(ScreenValue::_10).top(ScreenValue::_6).render();

    render_page(
        &shell,
        ctx,
        content,
        &format!("{} - WatchDogs", video.title),
        user.into(),
    )
    .await
}

pub async fn build_rec(library: &Library, video: &Video) -> PreEscaped<String> {
    let videos = library.get_directory_videos(&video.directory).await;

    let video_elements = html! {
        @for video in videos {
          (video_element_wide(&video).await);
        };
    };

    Width(
        Fraction::_1on3,
        Div()
            .id("recommendations")
            .push(
                Margin(
                    Paragraph(Context(
                        SpaceBetween(
                            Flex(
                                Div()
                                    .vanish()
                                    .push(Span("In ")._4xl().extrabold())
                                    .push(Link(
                                        &format!("/d/{}", video.directory),
                                        Text(&video.directory)
                                            .color(&Blue::_500)
                                            ._4xl()
                                            .extrabold(),
                                    )),
                            )
                            .group()
                            .justify(Justify::Center),
                        )
                        .x(ScreenValue::_2),
                    ))
                    .align(TextAlignment::Center)
                    ._4xl()
                    .extrabold(),
                )
                .bottom(ScreenValue::_2),
            )
            .push(video_elements),
    )
    .render()
}