use egui::{Label, RichText, Sense};
use nostrdb::{Note, NoteReply, Transaction};

use super::NoteOptions;
use crate::{jobs::JobsCache, note::NoteView, Mention};
use notedeck::{NoteAction, NoteContext};

#[must_use = "Please handle the resulting note action"]
#[profiling::function]
pub fn reply_desc(
    ui: &mut egui::Ui,
    txn: &Transaction,
    note_reply: &NoteReply,
    note_context: &mut NoteContext,
    note_options: NoteOptions,
    jobs: &mut JobsCache,
) -> Option<NoteAction> {
    let mut note_action: Option<NoteAction> = None;
    let size = 10.0;
    let selectable = false;
    let visuals = ui.visuals();
    let color = visuals.noninteractive().fg_stroke.color;
    let link_color = visuals.hyperlink_color;

    // note link renderer helper
    let note_link = |ui: &mut egui::Ui,
                     note_context: &mut NoteContext,
                     text: &str,
                     note: &Note<'_>,
                     jobs: &mut JobsCache| {
        let r = ui.add(
            Label::new(RichText::new(text).size(size).color(link_color))
                .sense(Sense::click())
                .selectable(selectable),
        );

        if r.clicked() {
            // TODO: jump to note
        }

        if r.hovered() {
            r.on_hover_ui_at_pointer(|ui| {
                ui.set_max_width(400.0);
                NoteView::new(note_context, note, note_options, jobs)
                    .actionbar(false)
                    .wide(true)
                    .show(ui);
            });
        }
    };

    ui.add(Label::new(RichText::new("replying to").size(size).color(color)).selectable(selectable));

    let reply = note_reply.reply()?;

    let reply_note = if let Ok(reply_note) = note_context.ndb.get_note_by_id(txn, reply.id) {
        reply_note
    } else {
        ui.add(Label::new(RichText::new("a note").size(size).color(color)).selectable(selectable));
        return None;
    };

    if note_reply.is_reply_to_root() {
        // We're replying to the root, let's show this
        let action = Mention::new(
            note_context.ndb,
            note_context.img_cache,
            txn,
            reply_note.pubkey(),
        )
        .size(size)
        .selectable(selectable)
        .show(ui);

        if action.is_some() {
            note_action = action;
        }

        ui.add(Label::new(RichText::new("'s").size(size).color(color)).selectable(selectable));

        note_link(ui, note_context, "thread", &reply_note, jobs);
    } else if let Some(root) = note_reply.root() {
        // replying to another post in a thread, not the root

        if let Ok(root_note) = note_context.ndb.get_note_by_id(txn, root.id) {
            if root_note.pubkey() == reply_note.pubkey() {
                // simply "replying to bob's note" when replying to bob in his thread
                let action = Mention::new(
                    note_context.ndb,
                    note_context.img_cache,
                    txn,
                    reply_note.pubkey(),
                )
                .size(size)
                .selectable(selectable)
                .show(ui);

                if action.is_some() {
                    note_action = action;
                }

                ui.add(
                    Label::new(RichText::new("'s").size(size).color(color)).selectable(selectable),
                );

                note_link(ui, note_context, "note", &reply_note, jobs);
            } else {
                // replying to bob in alice's thread

                let action = Mention::new(
                    note_context.ndb,
                    note_context.img_cache,
                    txn,
                    reply_note.pubkey(),
                )
                .size(size)
                .selectable(selectable)
                .show(ui);

                if action.is_some() {
                    note_action = action;
                }

                ui.add(
                    Label::new(RichText::new("'s").size(size).color(color)).selectable(selectable),
                );

                note_link(ui, note_context, "note", &reply_note, jobs);

                ui.add(
                    Label::new(RichText::new("in").size(size).color(color)).selectable(selectable),
                );

                let action = Mention::new(
                    note_context.ndb,
                    note_context.img_cache,
                    txn,
                    root_note.pubkey(),
                )
                .size(size)
                .selectable(selectable)
                .show(ui);

                if action.is_some() {
                    note_action = action;
                }

                ui.add(
                    Label::new(RichText::new("'s").size(size).color(color)).selectable(selectable),
                );

                note_link(ui, note_context, "thread", &root_note, jobs);
            }
        } else {
            let action = Mention::new(
                note_context.ndb,
                note_context.img_cache,
                txn,
                reply_note.pubkey(),
            )
            .size(size)
            .selectable(selectable)
            .show(ui);

            if action.is_some() {
                note_action = action;
            }

            ui.add(
                Label::new(RichText::new("in someone's thread").size(size).color(color))
                    .selectable(selectable),
            );
        }
    }

    note_action
}
