//! Publication detail: right pane showing full reference fields.

use leptos::prelude::*;

use brittle_model::Reference;

/// Right pane: displays the fields of the currently selected reference.
///
/// When `reference` is `None`, a placeholder is shown.
#[component]
pub fn PubDetail(reference: RwSignal<Option<Reference>>) -> impl IntoView {
    use leptos::either::Either;

    view! {
        <div class="pub-detail-pane">
            {move || match reference.get() {
                None => Either::Left(view! {
                    <div class="empty-state">"Select a publication to see details"</div>
                }),
                Some(r) => Either::Right(view! {
                    <div class="detail-content">
                        <h2 class="detail-title">
                            {r.fields.get("title").cloned().unwrap_or_else(|| "[no title]".into())}
                        </h2>
                        <dl class="detail-fields">
                            // Entry type + cite key
                            <dt>"Type"</dt>
                            <dd>{r.entry_type.to_string()}</dd>

                            <dt>"Cite key"</dt>
                            <dd class="mono">{r.cite_key.clone()}</dd>

                            // Authors
                            {if r.authors.is_empty() {
                                None
                            } else {
                                let names = r.authors.iter()
                                    .map(|p| p.display_name())
                                    .collect::<Vec<_>>()
                                    .join("; ");
                                Some(view! {
                                    <dt>"Authors"</dt>
                                    <dd>{names}</dd>
                                })
                            }}

                            // Editors
                            {if r.editors.is_empty() {
                                None
                            } else {
                                let names = r.editors.iter()
                                    .map(|p| p.display_name())
                                    .collect::<Vec<_>>()
                                    .join("; ");
                                Some(view! {
                                    <dt>"Editors"</dt>
                                    <dd>{names}</dd>
                                })
                            }}

                            // Prioritised well-known fields
                            {PRIORITY_FIELDS.iter().filter_map(|&key| {
                                r.fields.get(key).map(|val| view! {
                                    <dt>{field_label(key)}</dt>
                                    <dd>{val.clone()}</dd>
                                })
                            }).collect::<Vec<_>>()}

                            // Remaining fields in alphabetical order
                            {r.fields.iter()
                                .filter(|(k, _)| !PRIORITY_FIELDS.contains(&k.as_str())
                                                  && *k != "title")
                                .map(|(k, v)| view! {
                                    <dt>{field_label(k)}</dt>
                                    <dd>{v.clone()}</dd>
                                })
                                .collect::<Vec<_>>()
                            }
                        </dl>
                        <p class="detail-timestamps">
                            "Modified: "{r.modified_at.format("%Y-%m-%d %H:%M UTC").to_string()}
                        </p>
                    </div>
                }),
            }}
        </div>
    }
}

/// Fields shown before the alphabetical remainder (excluding "title").
const PRIORITY_FIELDS: &[&str] = &["year", "journal", "booktitle", "volume", "doi", "abstract"];

/// Pretty-print a BibTeX field key.
fn field_label(key: &str) -> String {
    match key {
        "doi" => "DOI".into(),
        "isbn" => "ISBN".into(),
        "issn" => "ISSN".into(),
        "url" => "URL".into(),
        _ => {
            let mut s = key.replace('_', " ");
            if let Some(c) = s.get_mut(0..1) {
                c.make_ascii_uppercase();
            }
            s
        }
    }
}
