# frozen_string_literal: true

module DiscourseNarrativeBot
  module Actions
    TIMEOUT_DURATION = 900 # 15 mins

    def discobot_user
      @discobot ||= User.find(-2)
    end

    def discobot_username
      self.discobot_user.username_lower
    end

    private

    def reply_to(post, raw, opts = {}, post_alert_options = {})
      defaut_post_alert_opts = { skip_send_email: true }.merge(post_alert_options)

      if post
        default_opts = {
          raw: raw,
          topic_id: post.topic_id,
          reply_to_post_number: post.post_number,
          post_alert_options: defaut_post_alert_opts,
          skip_validations: true
        }

        new_post = PostCreator.create!(self.discobot_user, default_opts.merge(opts))
        reset_rate_limits(post) if new_post
        new_post
      else
        PostCreator.create!(self.discobot_user, {
          post_alert_options: defaut_post_alert_opts,
          raw: raw,
          skip_validations: true
        }.merge(opts))
      end
    end

    def reset_rate_limits(post)
      user = post.user

      duration =
        if user && user.new_user?
          SiteSetting.rate_limit_new_user_create_post
        else
          SiteSetting.rate_limit_create_post
        end

      return unless duration > 0

      data = DiscourseNarrativeBot::Store.get(user.id.to_s)
      return unless data

      key = "#{DiscourseNarrativeBot::PLUGIN_NAME}:reset-rate-limit:#{post.topic_id}:#{data['state']}"

      if !(count = Discourse.redis.get(key))
        count = 0
        Discourse.redis.setex(key, duration, count)
      end

      if count.to_i < 2
        post.default_rate_limiter.rollback!
        post.limit_posts_per_day&.rollback!
        Discourse.redis.incr(key)
      end
    end

    def fake_delay
      sleep(rand(1.0..2.0)) if Rails.env.production?
    end

    def bot_mentioned?(post)
      doc = Nokogiri::HTML5.fragment(post.cooked)

      valid = false

      doc.css(".mention").each do |mention|
        if User.normalize_username(mention.text) == "@#{self.discobot_username}"
          valid = true
          break
        end
      end

      valid
    end

    def reply_to_bot_post?(post)
      post&.reply_to_post && post.reply_to_post.user_id == -2
    end

    def pm_to_bot?(post)
      topic = post.topic
      return false if !topic

      topic.pm_with_non_human_user? &&
        topic.topic_allowed_users.where(user_id: -2).exists?
    end

    def cancel_timeout_job(user)
      Jobs.cancel_scheduled_job(:narrative_timeout, user_id: user.id, klass: self.class.to_s)
    end

    def enqueue_timeout_job(user)
      return if Rails.env.test?

      cancel_timeout_job(user)

      Jobs.enqueue_in(TIMEOUT_DURATION, :narrative_timeout,
        user_id: user.id,
        klass: self.class.to_s
      )
    end
  end
end