#include "TagManagerDialog.hpp"
#include <glibmm/markup.h>

TagManagerDialog::TagManagerDialog(Gtk::Window& parent, DatabaseManager& db)
  : Gtk::Dialog("Manage Tags", parent, true),
    m_db(db) {

  set_default_size(400, 450);
  set_modal(true);

  // Content area
  m_contentBox.set_spacing(8);
  m_contentBox.set_margin_top(12);
  m_contentBox.set_margin_bottom(12);
  m_contentBox.set_margin_start(12);
  m_contentBox.set_margin_end(12);

  // Empty state label
  m_emptyLabel.set_markup("<span size='large'>No tags</span>\n<small>Tags will appear here when you add them to books.</small>");
  m_emptyLabel.set_halign(Gtk::Align::CENTER);
  m_emptyLabel.set_valign(Gtk::Align::CENTER);
  m_emptyLabel.set_vexpand(true);

  // Scrolled list
  m_scrolled.set_policy(Gtk::PolicyType::NEVER, Gtk::PolicyType::AUTOMATIC);
  m_scrolled.set_vexpand(true);
  m_tagList.set_selection_mode(Gtk::SelectionMode::NONE);
  m_tagList.add_css_class("boxed-list");
  m_scrolled.set_child(m_tagList);

  // Cleanup button
  m_cleanupButton.set_label("Clean Up Unused");
  m_cleanupButton.set_tooltip_text("Remove tags that aren't assigned to any books");
  m_cleanupButton.signal_clicked().connect(sigc::mem_fun(*this, &TagManagerDialog::on_cleanup_clicked));
  m_buttonBox.set_halign(Gtk::Align::END);
  m_buttonBox.append(m_cleanupButton);

  m_contentBox.append(m_scrolled);
  m_contentBox.append(m_buttonBox);

  get_content_area()->append(m_contentBox);

  // Setup rename popover
  m_renameBox.set_spacing(6);
  m_renameBox.set_margin_top(6);
  m_renameBox.set_margin_bottom(6);
  m_renameBox.set_margin_start(6);
  m_renameBox.set_margin_end(6);

  m_renameEntry.set_placeholder_text("New tag name...");
  m_renameEntry.signal_activate().connect([this]() {
    m_renameApplyButton.activate();
  });

  m_renameApplyButton.set_label("Rename");
  m_renameApplyButton.add_css_class("suggested-action");
  m_renameApplyButton.signal_clicked().connect([this]() {
    const auto new_name = m_renameEntry.get_text();
    if (new_name.empty() || m_renameOldName.empty()) return;

    if (m_db.rename_tag(m_renameOldName, new_name.raw())) {
      m_renamePopover.popdown();
      refresh_tag_list();
      m_signalTagsModified.emit();
    }
  });

  m_renameBox.append(m_renameEntry);
  m_renameBox.append(m_renameApplyButton);
  m_renamePopover.set_child(m_renameBox);

  // Close button
  add_button("Close", Gtk::ResponseType::CLOSE);

  signal_response().connect([this](int) {
    hide();
  });

  refresh_tag_list();
}

void TagManagerDialog::refresh_tag_list() {
  // Remove all children
  while (auto* child = m_tagList.get_first_child()) {
    m_tagList.remove(*child);
  }

  auto tags = m_db.get_all_tags();

  if (tags.empty()) {
    m_scrolled.set_visible(false);
    m_buttonBox.set_visible(false);
    m_contentBox.append(m_emptyLabel);
    m_emptyLabel.set_visible(true);
  } else {
    m_emptyLabel.set_visible(false);
    if (m_emptyLabel.get_parent())
      m_contentBox.remove(m_emptyLabel);
    m_scrolled.set_visible(true);
    m_buttonBox.set_visible(true);

    for (const auto& tag : tags) {
      auto* row = create_tag_row(tag);
      m_tagList.append(*row);
    }
  }
}

Gtk::Widget* TagManagerDialog::create_tag_row(const DatabaseManager::TagInfo& tag) {
  auto* row = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 8);
  row->set_margin_top(8);
  row->set_margin_bottom(8);
  row->set_margin_start(12);
  row->set_margin_end(12);

  auto* name_label = Gtk::make_managed<Gtk::Label>(tag.name);
  name_label->set_hexpand(true);
  name_label->set_xalign(0);

  auto* count_label = Gtk::make_managed<Gtk::Label>(
    Glib::ustring::compose("%1 book%2", tag.usage_count, tag.usage_count == 1 ? "" : "s"));
  count_label->add_css_class("dim-label");

  auto* rename_btn = Gtk::make_managed<Gtk::Button>();
  rename_btn->set_icon_name("document-edit-symbolic");
  rename_btn->add_css_class("flat");
  rename_btn->set_tooltip_text("Rename tag");
  rename_btn->signal_clicked().connect([this, tag, rename_btn]() {
    on_rename_tag(tag.name);
    m_renamePopover.set_parent(*rename_btn);
    m_renamePopover.popup();
  });

  auto* delete_btn = Gtk::make_managed<Gtk::Button>();
  delete_btn->set_icon_name("user-trash-symbolic");
  delete_btn->add_css_class("flat");
  delete_btn->set_tooltip_text("Delete tag");
  delete_btn->signal_clicked().connect([this, tag]() {
    on_delete_tag(tag.name);
  });

  row->append(*name_label);
  row->append(*count_label);
  row->append(*rename_btn);
  row->append(*delete_btn);

  return row;
}

void TagManagerDialog::on_rename_tag(const std::string& old_name) {
  m_renameOldName = old_name;
  m_renameEntry.set_text(old_name);
  m_renameEntry.select_region(0, -1);
}

void TagManagerDialog::on_delete_tag(const std::string& tag_name) {
  if (m_db.delete_tag(tag_name)) {
    refresh_tag_list();
    m_signalTagsModified.emit();
  }
}

void TagManagerDialog::on_cleanup_clicked() {
  int removed = m_db.delete_unused_tags();
  if (removed > 0) {
    refresh_tag_list();
    m_signalTagsModified.emit();
  }
}
