# typed: strict
class Domain::User::SofurryUser < Domain::User
  include HasAttrJsonEnum

  validates :sofurry_id, uniqueness: true, allow_blank: true
  validates :username, uniqueness: true, allow_blank: true
  validates :useralias, uniqueness: true, allow_blank: true
  validate :username_and_useralias_match?

  has_created_posts! Domain::Post::SofurryPost
  has_many :folders,
           class_name: "::Domain::PostGroup::SofurryFolder",
           inverse_of: :owner,
           dependent: :destroy,
           autosave: true

  attr_json :last_scan_log_entry_id, :integer
  belongs_to :last_scan_log_entry, class_name: "::HttpLogEntry", optional: true

  attr_json :state, :string
  attr_json :sofurry_id, :integer
  attr_json :username, :string # contains spaces, upper case, etc
  attr_json :useralias, :string # only lowercase, spaces replaced with hyphens
  attr_json :registered_at, ActiveModelUtcTimeValue.new # or Jan 1, 1970 if "long long ago"
  attr_json :gallery_folder_ids, :integer, array: true

  attr_json :profile_description, :string
  # TODO - profiles with these fields:
  # - https://onyx-coldfire.sofurry.com/
  # - https://fawkesish.sofurry.com/
  attr_json :profile_species, :string
  # attr_json :profile_gender, :integer
  # attr_json :profile_orientation, :integer
  # attr_json :profile_mateship_status, :integer
  attr_json :profile_country, :string
  attr_json :profile_city, :string
  attr_json :profile_num_submissions, :integer
  attr_json :profile_num_submission_views, :integer
  attr_json :profile_num_comments_received, :integer
  attr_json :profile_num_comments_posted, :integer
  attr_json :profile_num_profile_views, :integer

  attr_json_enum(
    :profile_gender,
    :integer,
    { na: 0, male: 1, female: 2, herm: 3 },
    prefix: true,
  )

  attr_json_enum(
    :profile_orientation,
    :integer,
    { na: 0, straight: 1, gay: 2, bi: 3, pan: 4 },
    prefix: true,
  )

  attr_json_enum(
    :profile_mateship_status,
    :integer,
    {
      na: 0,
      single_uninterested: 1,
      single_casual: 2,
      single_permanent: 3,
      mated_open: 4,
      mated_closed: 5,
    },
    prefix: true,
  )

  enum :state, { pending: "pending", ok: "ok", error: "error" }, prefix: true

  attr_json_due_timestamp :scanned_page_at, 1.month
  attr_json_due_timestamp :scanned_gallery_at, 1.month

  after_initialize { self.state ||= "pending" }

  before_validation do
    if (username = self.username)
      self.useralias ||= username.downcase.gsub(" ", "-")
    end
  end

  sig { override.returns(String) }
  def account_status_for_view
    "TODO"
  end

  sig { override.returns(T.nilable(String)) }
  def external_url_for_view
    "https://#{username}.sofurry.com"
  end

  sig { override.returns(String) }
  def description_html_base_domain
    "sofurry.com"
  end

  sig { override.returns(String) }
  def site_name_for_view
    "SoFurry"
  end

  sig { override.returns(T.nilable(String)) }
  def description_html_for_view
    profile_description
  end

  sig { override.returns(T.nilable(String)) }
  def name_for_view
    username
  end

  sig { override.returns(T::Array[String]) }
  def names_for_search
    [username, useralias].compact.uniq
  end

  sig { override.returns(Domain::DomainType) }
  def self.domain_type
    Domain::DomainType::Sofurry
  end

  sig { override.returns([String, Symbol]) }
  def self.param_prefix_and_attribute
    ["sf", :username]
  end

  sig { override.returns(String) }
  def self.view_prefix
    "sf"
  end

  sig { void }
  def username_and_useralias_match?
    if (un = self.username) && un.downcase.gsub(" ", "-") != useralias
      errors.add(:useralias, "must match username")
      false
    else
      true
    end
  end
end
