#pragma once

#include <string>
#include <string_view>
#include <utility>   // std::move
#include <gtkmm.h>
#include <glib.h>

// Forward declarations so we don't pull in heavy GTK headers here.
//namespace Gdk { class Texture; }
//namespace Glib { template <class T> class RefPtr; }

/**
 * @brief Represents a single book in the Bibliotheca library.
 *
 * A Book is uniquely identified by its SHA-256 digest of the underlying file.
 * It stores lightweight metadata (title, author, file/cover paths) and may
 * optionally hold a Gdk::Texture cover image for fast rendering in the UI.
 */
class Book {
public:
  // -----------------------------------------------------------------------
  // Constructors & Rule-of-Five
  // -----------------------------------------------------------------------

  Book(std::string_view idSha256,
       std::string_view title,
       std::string_view author,
       std::string_view filePath,
       std::string_view coverPath = {});

  Book();
  Book(const Book&);
  Book(Book&&) noexcept;
  Book& operator=(const Book&);
  Book& operator=(Book&&) noexcept;
  ~Book();

  // -----------------------------------------------------------------------
  // Accessors
  // -----------------------------------------------------------------------

  const std::string& id()        const noexcept { return m_id; }
  const std::string& title()     const noexcept { return m_title; }
  const std::string& author()    const noexcept { return m_author; }
  const std::string& filePath()  const noexcept { return m_filePath; }
  const std::string& coverPath() const noexcept { return m_coverPath; }
  const std::vector<std::string>& tags() const noexcept { return m_tags; }

  void set_tags(const std::vector<std::string>& tags) { m_tags = tags; }
  // -----------------------------------------------------------------------
  // Cover management
  // -----------------------------------------------------------------------

  const Glib::RefPtr<Gdk::Texture>& cover() const noexcept;
  void set_cover(const Glib::RefPtr<Gdk::Texture>& tex);
  void set_cover(Glib::RefPtr<Gdk::Texture>&& tex);
	
  void load_cover_from_disk();
	

  // -----------------------------------------------------------------------
  // Comparison operators
  // -----------------------------------------------------------------------

  // Equality by unique hash ID
  bool operator==(const Book& other) const noexcept { return m_id == other.m_id; }

  // Ordering by title, then author, then ID
  bool operator<(const Book& other) const noexcept;

private:
  // -----------------------------------------------------------------------
  // Data members
  // -----------------------------------------------------------------------

  std::string m_id;        ///< Hex SHA-256 of the file contents
  std::string m_title;     ///< Book title
  std::string m_author;    ///< Author name
  std::string m_filePath;  ///< Absolute path to the file on disk
  std::string m_coverPath; ///< Path to the cover image (optional)
  std::vector<std::string> m_tags; ///< Tags associated with the book

  Glib::RefPtr<Gdk::Texture> m_cover; ///< Cached cover image for UI rendering
};
