module BeefCake
  class Membership < BeefCake::Base
    attributes :id, :uid, :role_id, :role_name, :expires_at

    validates :uid, presence: true
    validates :role_id, presence: true

    def self.composite_key(role_id:, uid:)
      "#{role_id}:#{uid}"
    end

    def self.parse_composite_key(key)
      key.split(':', 2)
    end

    def self.find(id, _options = {})
      role_id, uid = parse_composite_key(id)

      twirp_data(client.get_role(Twitch::Fulton::Beefcake::GetRoleRequest.new(
                                   id: role_id
      )))
        .user_memberships
        .select { |u| u.user_id == uid }
        .map do |u|
          from_attributes(
            id: composite_key(role_id: role_id, uid: uid),
            uid: uid,
            role_id: role_id,
            expires_at: u.expiration.nil? ? nil : Time.at(u.expiration.seconds).to_date
          )
        end
        .first
    end

    def save
      return false unless valid?

      req = Twitch::Fulton::Beefcake::AddUserToRoleRequest.new(
        role_id: role_id,
        user_id: uid
      )

      if expires_at.present?
        req.membership_expiration = Google::Protobuf::Timestamp.new(
          seconds: expires_at.to_time.to_i
        )
      end

      handle_error(client.add_user_to_role(req))
      self.id = self.class.composite_key(role_id: role_id, uid: uid)

      true
    end

    def destroy
      handle_error(client.remove_user_from_role(
                     Twitch::Fulton::Beefcake::RemoveUserFromRoleRequest.new(
                       role_id: role_id,
                       user_id: uid
                     )
      ))
      true
    end

    def realm_user
      @realm_user ||= RealmUser.from_uri(uid)
    end
  end
end


