require_relative 'gen/stories_base'

module Asana
  module Resources
    # A _story_ represents an activity associated with an object in the Asana
    # system. Stories are generated by the system whenever users take actions such
    # as creating or assigning tasks, or moving tasks between projects. _Comments_
    # are also a form of user-generated story.
    class Story < StoriesBase


      attr_reader :gid

      attr_reader :resource_type

      attr_reader :resource_subtype

      attr_reader :created_at

      attr_reader :created_by

      attr_reader :liked
      alias_method :hearted, :liked

      attr_reader :likes
      alias_method :hearts, :likes

      attr_reader :num_likes

      attr_reader :text

      attr_reader :html_text

      attr_reader :target

      attr_reader :is_pinned

      attr_reader :is_edited

      attr_reader :source

      attr_reader :type

      class << self
        # Returns the plural name of the resource.
        def plural_name
          'stories'
        end

        # Returns the compact records for all stories on the task.
        #
        # task - [Gid] Globally unique identifier for the task.
        #
        # per_page - [Integer] the number of records to fetch per page.
        # options - [Hash] the request I/O options.
        def find_by_task(client, task: required("task"), per_page: 20, options: {})
          params = { limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
          Collection.new(parse(client.get("/tasks/#{task}/stories", params: params, options: options)), type: self, client: client)
        end

        # Returns the full record for a single story.
        #
        # id - [Gid] Globally unique identifier for the story.
        #
        # options - [Hash] the request I/O options.
        def find_by_id(client, id, options: {})

          self.new(parse(client.get("/stories/#{id}", options: options)).first, client: client)
        end

        # Adds a comment to a task. The comment will be authored by the
        # currently authenticated user, and timestamped when the server receives
        # the request.
        #
        # Returns the full record for the new story added to the task.
        #
        # task - [Id] Globally unique identifier for the task.
        #
        # text - [String] The plain text of the comment to add.
        # options - [Hash] the request I/O options.
        # data - [Hash] the attributes to post.
        def create_on_task(client, task: required("task"), text: required("text"), options: {}, **data)
          with_params = data.merge(text: text).reject { |_,v| v.nil? || Array(v).empty? }
          self.new(parse(client.post("/tasks/#{task}/stories", body: with_params, options: options)).first, client: client)
        end
      end

      # Updates the story and returns the full record for the updated story.
      # Only comment stories can have their text updated, and only comment stories and
      # attachment stories can be pinned. Only one of `text` and `html_text` can be specified.
      #
      # text - [String] The plain text with which to update the comment.
      #
      # html_text - [String] The rich text with which to update the comment.
      # is_pinned - [Boolean] Whether the story should be pinned on the resource.
      # options - [Hash] the request I/O options.
      # data - [Hash] the attributes to post.
      def update(text: nil, html_text: nil, is_pinned: nil, options: {}, **data)
        with_params = data.merge(text: text, html_text: html_text, is_pinned: is_pinned).reject { |_,v| v.nil? || Array(v).empty? }
        refresh_with(parse(client.put("/stories/#{gid}", body: with_params, options: options)).first)
      end

      # Deletes a story. A user can only delete stories they have created. Returns an empty data record.
      def delete()

        client.delete("/stories/#{gid}") && true
      end

    end
  end
end
