# typed: strict
module Domain::DomainsHelper
  extend T::Sig
  extend T::Helpers
  include HelpersInterface
  abstract!

  # If a URL is detected in plain text and is one of these domains,
  # it will be converted to an anchor tag.
  ALLOWED_PLAIN_TEXT_URL_DOMAINS = %w[
    e621.net
    furaffinity.net
    inkbunny.net
  ].freeze

  # If a link is detected in an anchor tag and is one of these domains,
  # it will be converted to a link.
  ALLOWED_EXTERNAL_LINK_DOMAINS =
    T.let(
      (
        %w[
          archiveofourown.org
          behance.net
          bigcartel.com
          boosty.to
          bsky.app
          carrd.co
          deviantart.com
          discord.gg
          dribbble.com
          e621.net
          facebook.com
          furaffinity.net
          gumroad.com
          hipolink.me
          inkbunny.net
          itch.io
          instagram.com
          ko-fi.com
          livejournal.com
          mstdn.social
          patreon.com
          pinterest.com
          pixiv.net
          redbubble.com
          spreadshirt.com
          spreadshirt.de
          t.me
          tumblr.com
          twitch.tv
          twitter.com
          vimeo.com
          weasyl.com
          x.com
          youtube.com
          sofurry.com
        ] + ALLOWED_PLAIN_TEXT_URL_DOMAINS
      ).freeze,
      T::Array[String],
    )

  DOMAIN_TO_ICON_PATH =
    T.let(
      {
        "bigcartel.com" => "bigcartel.png",
        "boosty.to" => "boosty.png",
        "bsky.app" => "bsky.png",
        "carrd.co" => "carrd.png",
        "deviantart.com" => "deviantart.png",
        "e621.net" => "e621.png",
        "furaffinity.net" => "fa.png",
        "ib.metapix.net" => "inkbunny.png",
        "inkbunny.net" => "inkbunny.png",
        "itaku.ee" => "itaku.png",
        "ko-fi.com" => "ko-fi.png",
        "newgrounds.com" => "newgrounds.png",
        "patreon.com" => "patreon.png",
        "pixiv.net" => "pixiv.png",
        "redbubble.com" => "redbubble.png",
        "spreadshirt.com" => "spreadshirt.png",
        "spreadshirt.de" => "spreadshirt.png",
        "subscribestar.com" => "subscribestar.png",
        "subscribestar.adult" => "subscribestar.png",
        "gumroad.com" => "gumroad.png",
        "itch.io" => "itch-io.png",
        "t.me" => "telegram.png",
        "tumblr.com" => "tumblr.png",
        "twitter.com" => "x-twitter.png",
        "weasyl.com" => "weasyl.png",
        "wixmp.com" => "deviantart.png",
        "x.com" => "x-twitter.png",
      }.freeze,
      T::Hash[String, String],
    )

  DOMAIN_TITLE_MAPPERS =
    T.let(
      [
        [%r{://t.me/([^/]+)}, ->(match) { match[1] }],
        [%r{://bsky.app/profile/([^/]+)}, ->(match) { match[1] }],
        [%r{://(.*\.)?x.com/([^/]+)}, ->(match) { match[2] }],
        [%r{://(.*\.)?twitter.com/([^/]+)}, ->(match) { match[2] }],
        [%r{://(.*\.)?patreon.com/([^/]+)}, ->(match) { match[2] }],
        [%r{://(.*\.)?furaffinity.net/user/([^/]+)}, ->(match) { match[2] }],
      ],
      T::Array[[Regexp, T.proc.params(match: MatchData).returns(String)]],
    )

  sig { params(domain: String, host: String).returns(T::Boolean) }
  def url_matches_domain?(domain, host)
    host == domain || host.end_with?(".#{domain}")
  end

  sig { params(domain: String).returns(T.nilable(String)) }
  def icon_path_for_domain(domain)
    for test_domain, icon in DOMAIN_TO_ICON_PATH
      if url_matches_domain?(test_domain, domain)
        return asset_path("domain-icons/#{icon}")
      end
    end
    nil
  end

  sig { params(url: String).returns(String) }
  def title_for_url(url)
    url = url.to_s
    for mapper in DOMAIN_TITLE_MAPPERS
      if (match = mapper[0].match(url)) && (group = mapper[1].call(match))
        return group
      end
    end
    url
  end
end
