class LinkTag < LiquidTagBase
  include ActionView::Helpers
  PARTIAL = "articles/liquid".freeze

  def initialize(_tag_name, slug_or_path_or_url, _parse_context)
    super
    @article = get_article(slug_or_path_or_url)
    @title = @article.title if @article
  end

  def render(_context)
    ApplicationController.render(
      partial: PARTIAL,
      locals: { article: @article, title: @title },
    )
  end

  def get_article(slug)
    slug = strip_tags(slug.strip)
    find_article_by_user(article_hash(slug)) || find_article_by_org(article_hash(slug))
  end

  def article_hash(slug)
    url = Addressable::URI.parse(slug)
    domain = url.port ? "#{url.host}:#{url.port}" : url.host
    path = url.path

    # If domain is present in url check if it belongs to the app
    possible_domains = Subforem.cached_domains + [Settings::General.app_domain]
    unless domain.blank? || possible_domains.include?(domain.downcase)
      raise StandardError, I18n.t("liquid_tags.link_tag.not_exist_link", slug: slug)
    end

    path.slice!(0) if path.starts_with?("/") # remove leading slash if present
    path.slice!(-1) if path.ends_with?("/") # remove trailing slash if present
    extracted_hash = Addressable::Template.new("{username}/{slug}").extract(path)&.symbolize_keys
    raise StandardError, I18n.t("liquid_tags.link_tag.not_exist", slug: slug) unless extracted_hash

    extracted_hash
  end

  def find_article_by_user(hash)
    user = User.find_by(username: hash[:username])
    return unless user

    user.articles.where(slug: hash[:slug])&.first
  end

  def find_article_by_org(hash)
    org = Organization.find_by(slug: hash[:username])
    return unless org

    org.articles.where(slug: hash[:slug])&.first
  end
end

Liquid::Template.register_tag("link", LinkTag)
Liquid::Template.register_tag("post", LinkTag)
