# 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 if 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