# typed: strict
class Domain::Sofurry::GalleryPageParser
  extend T::Sig

  class Folder < T::Struct
    include T::Struct::ActsAsComparable
    const :name, String
    const :sofurry_id, Integer
  end

  class MediaType < T::Enum
    enums do
      Stories = new("stories")
      Art = new("art")
      Music = new("music")
      Journals = new("journals")
      Photos = new("photos")
    end
  end

  class ShortGalleryEntry < T::Struct
    include T::Struct::ActsAsComparable
    const :sofurry_id, Integer
    const :title, String
  end

  sig { params(page: String, user_id: Integer).void }
  def initialize(page, user_id:)
    @doc = T.let(Nokogiri.HTML(page), Nokogiri::HTML::Document)
    @page = T.let(page, String)
    @folders = T.let(nil, T.nilable(T::Array[String]))
    @user_id = T.let(user_id, Integer)
    @posts = T.let(nil, T.nilable(T::Array[ShortGalleryEntry]))
  end

  sig { returns(T::Array[Folder]) }
  def folders
    @folders ||=
      @doc
        .css(".sfBrowseListFolders .items .sfArtworkSmallWrapper strong a")
        .map do |elem|
          href = elem.attr("href")
          href_params = Addressable::URI.parse(href).query_values
          user_id = href_params["by"]
          if user_id&.to_i != @user_id
            raise "user_id mismatch: #{user_id} != #{@user_id}"
          end
          name = elem.text
          sofurry_id = href_params["folder"]&.to_i
          Folder.new(name:, sofurry_id:)
        end
  end

  sig { returns(T::Array[ShortGalleryEntry]) }
  def posts
    @posts ||=
      begin
        [
          @doc
            .css(".sf-browse-shortlist,.sf-browse-shortlist-zebra")
            .map do |elem|
              title_id = elem.css(".sf-browse-shortlist-title a").first || next
              sofurry_id = title_id&.attr("href").split("/")&.last&.to_i || next
              title = title_id&.text || next
              ShortGalleryEntry.new(sofurry_id:, title:)
            end
            .compact,
          @doc
            .css("a.sfArtworkSmallInner")
            .map do |elem|
              sofurry_id = elem.attr("href").split("/")&.last&.to_i || next
              img_elem = elem.css("img.sfArtworkItem").first || next
              title =
                img_elem.attr("alt")&.strip&.rpartition("|by")&.first || next
              ShortGalleryEntry.new(sofurry_id:, title:)
            end
            .compact,
        ].flatten
      end
  end

  sig { returns(T.nilable(String)) }
  def username
    @doc.css(".user-info .user-text").first&.text&.strip&.chomp
  end
end
