/*
    This file is part of jellything (https://codeberg.org/metamuffin/jellything)
    which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
    Copyright (C) 2026 metamuffin <metamuffin.org>
*/

use crate::{RenderInfo, components::props::Props};
use jellycommon::{
    jellyobject::{Object, Tag, TypedTag},
    routes::{u_image, u_node_slug_player},
    *,
};
use jellyui_locale::tr;
use std::marker::PhantomData;

markup::define! {
    NodePage<'a>(ri: &'a RenderInfo<'a>, nku: Object<'a>) {
        @let node = nku.get(NKU_NODE).unwrap_or_default();
        @let slug = node.get(NO_SLUG).unwrap_or_default();
        @let pics = node.get(NO_PICTURES).unwrap_or_default();
        @if let Some(path) = pics.get(PICT_BACKDROP) {
            img.backdrop[src=u_image(path, 2048)];
        }
        @if let Some(path) = pics.get(PICT_COVER) {
            @let cls = format!("bigposter {} {}", aspect_class(node), if pics.has(PICT_BACKDROP.0) { "has_backdrop" } else { "" });
            div[class=cls] { img[src=u_image(path, 2048), loading="lazy"]; }
        }
        .title {
            h1 { @node.get(NO_TITLE).unwrap_or_default() }
            // ul.parents { @for (node, _) in *parents { li {
            //     a.component[href=u_node_slug(&node.slug)] { @node.title }
            // }}}
            @if node.has(NO_TRACK.0) {
                a.play[href=u_node_slug_player(slug)] { @tr(ri.lang, "node.player_link") }
                // @if matches!(udata.watched, WatchedState::None | WatchedState::Pending | WatchedState::Progress(_)) {
                //     form.mark_watched[method="POST", action=u_node_slug_watched(&node.slug, ApiWatchedState::Watched)] {
                //         input[type="submit", value=trs(lang, "node.watched.set")];
                //     }
                // }
                // @if matches!(udata.watched, WatchedState::Watched) {
                //     form.mark_unwatched[method="POST", action=u_node_slug_watched(&node.slug, ApiWatchedState::None)] {
                //         input[type="submit", value=trs(lang, "node.watched.unset")];
                //     }
                // }
                // @if matches!(udata.watched, WatchedState::None) {
                //     form.mark_unwatched[method="POST", action=u_node_slug_watched(&node.slug, ApiWatchedState::Pending)] {
                //         input[type="submit", value=trs(lang, "node.watchlist.set")];
                //     }
                // }
                // @if matches!(udata.watched, WatchedState::Pending) {
                //     form.mark_unwatched[method="POST", action=u_node_slug_watched(&node.slug, ApiWatchedState::None)] {
                //         input[type="submit", value=trs(lang, "node.watchlist.unset")];
                //     }
                // }
                // form.rating[method="POST", action=u_node_slug_update_rating(&node.slug)] {
                //     input[type="range", name="rating", min=-10, max=10, step=1, value=udata.rating];
                //     input[type="submit", value=trs(lang, "node.update_rating")];
                // }
            }
        }
        .details {
            @Props { ri, nku: *nku, full: true }
            h3 { @node.get(NO_TAGLINE).unwrap_or_default() }
            @if let Some(description) = &node.get(NO_DESCRIPTION) {
                p { @for line in description.lines() { @line br; } }
            }
            // @if !media.chapters.is_empty() {
            //     h2 { @trs(lang, "node.chapters") }
            //     ul.children.hlist { @for chap in &media.chapters {
            //         @let (inl, sub) = format_chapter(chap);
            //         li { .card."aspect-thumb" {
            //             .poster {
            //                 a[href=u_node_slug_player_time(&node.slug, chap.time_start.unwrap_or(0.))] {
            //                     img[src=u_node_slug_thumbnail(&node.slug, chapter_key_time(chap, media.duration), 1024), loading="lazy"];
            //                 }
            //                 .cardhover { .props { p { @inl } } }
            //             }
            //             .title { span { @sub } }
            //         }}
            //     }}
            // }
            @if node.has(NO_TRACK.0) {
                details {
                    summary { @tr(ri.lang, "media.tracks") }
                    ol { @for track in node.iter(NO_TRACK) {
                        li { "track" @track.get(TR_NAME) }
                    }}
                }
            }
            @if let Some(idents) = node.get(NO_IDENTIFIERS) {
                details {
                    summary { @tr(ri.lang, "node.external_ids") }
                    table {
                        @for (key, value) in idents.entries::<&str>() { tr {
                            td { @tr(ri.lang, &format!("tag.iden.{key}")) }
                            @if let Some(url) = external_id_url(key, value) {
                                td { a[href=url] { pre { @value } } }
                            } else {
                                td { pre { @value } }
                            }
                        }}
                    }
                }
            }
            @if node.has(NO_TAG.0) {
                details {
                    summary { @tr(ri.lang, "node.tags") }
                    ol { @for tag in node.iter(NO_TAG) {
                        li { @tag }
                    }}
                }
            }
            @if node.has(NO_METASOURCE.0) {
                details {
                    summary { @tr(ri.lang, "tag.msrc") }
                    table {
                        tr { th {"Attribute"} th {"Source"} }
                        @for (key, source) in node.get(NO_METASOURCE).unwrap_or_default().entries::<Tag>() { tr {
                            td { @tr(ri.lang, &format!("tag.{key}")) }
                            td { @tr(ri.lang, &format!("tag.msrc.{source}")) }
                        }}
                        @for nkey in [NO_PICTURES, NO_IDENTIFIERS, NO_RATINGS] {
                            @let nob = node.get(nkey).unwrap_or_default();
                            @for (key, source) in nob.get(NO_METASOURCE).unwrap_or_default().entries::<Tag>() { tr {
                                td { @tr(ri.lang, &format!("tag.{nkey}")) ": " @tr(ri.lang, &format!("tag.{nkey}.{key}")) }
                                td { @tr(ri.lang, &format!("tag.msrc.{source}")) }
                            }}
                        }
                    }
                }
            }
        }
        //     @if matches!(node.kind, NodeKind::Collection | NodeKind::Channel) {
        //         @NodeFilterSortForm { f: filter, lang }
        //     }
        //     @if !similar.is_empty() {
        //         h2 { @trs(lang, "node.similar") }
        //         ul.children.hlist {@for (node, udata) in similar.iter() {
        //             li { @NodeCard { node, udata, lang } }
        //         }}
        //     }
    }

    Player<'a>(ri: &'a RenderInfo<'a>, nku: Object<'a>) {
        @let _ = ri;
        @let node = nku.get(NKU_NODE).unwrap_or_default();
        @let pics = node.get(NO_PICTURES).unwrap_or_default();
        video[id="player", poster=pics.get(PICT_COVER).map(|p| u_image(p, 2048))] {}
    }

}

// fn chapter_key_time(c: Object, dur: f64) -> f64 {
//     let start = c.get(CH_START).unwrap_or(0.);
//     let end = c.get(CH_END).unwrap_or(dur);
//     start * 0.8 + end * 0.2
// }

pub fn aspect_class(node: Object<'_>) -> &'static str {
    let kind = node.get(NO_KIND).unwrap_or(KIND_COLLECTION);
    match kind {
        KIND_VIDEO | KIND_EPISODE => "aspect-thumb",
        KIND_COLLECTION => "aspect-land",
        KIND_SEASON | KIND_SHOW | KIND_PERSON | KIND_SERIES | KIND_MOVIE | KIND_SHORTFORMVIDEO => {
            "aspect-port"
        }
        KIND_CHANNEL | KIND_MUSIC | _ => "aspect-square",
    }
}

fn external_id_url(key: Tag, value: &str) -> Option<String> {
    Some(match TypedTag(key, PhantomData) {
        IDENT_YOUTUBE_VIDEO => format!("https://youtube.com/watch?v={value}"),
        IDENT_YOUTUBE_CHANNEL => format!("https://youtube.com/channel/{value}"),
        IDENT_YOUTUBE_CHANNEL_HANDLE => format!("https://youtube.com/channel/@{value}"),
        IDENT_MUSICBRAINZ_RELEASE => format!("https://musicbrainz.org/release/{value}"),
        IDENT_MUSICBRAINZ_ARTIST => format!("https://musicbrainz.org/artist/{value}"),
        IDENT_MUSICBRAINZ_RELEASE_GROUP => {
            format!("https://musicbrainz.org/release-group/{value}")
        }
        IDENT_MUSICBRAINZ_RECORDING => {
            format!("https://musicbrainz.org/recording/{value}")
        }
        _ => return None,
    })
}
